mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-09 03:16:38 +00:00
fix(studio): resize from the element's real box, not a 200px guess
Resizing an element whose size is driven by a scale animation committed a scale computed against a hardcoded 200px fallback, because the only original size the draft recorded was the element's INLINE width, and a composition sizes its elements from the stylesheet. A 630px chip dropped at 1260px wide committed a scale of 6.3 instead of 2, so it landed at over three times the size it was dropped at. The next drag compounded it, because that wrong scale then counted as the element's live one. The draft now records the box it measured, once, before it writes a width of its own, and the intercept reads that. The inline attributes keep their own job of restoring an inline style, which is why they cannot answer this question.
This commit is contained in:
@@ -12,6 +12,8 @@ import {
|
||||
STUDIO_ORIGINAL_INLINE_TRANSLATE_ATTR,
|
||||
STUDIO_ORIGINAL_WIDTH_ATTR,
|
||||
STUDIO_ORIGINAL_HEIGHT_ATTR,
|
||||
STUDIO_ORIGINAL_BOX_WIDTH_ATTR,
|
||||
STUDIO_ORIGINAL_BOX_HEIGHT_ATTR,
|
||||
STUDIO_ORIGINAL_MIN_WIDTH_ATTR,
|
||||
STUDIO_ORIGINAL_MIN_HEIGHT_ATTR,
|
||||
STUDIO_ORIGINAL_MAX_WIDTH_ATTR,
|
||||
@@ -361,6 +363,12 @@ function writeStudioBoxSizeVars(
|
||||
if (!element.hasAttribute(STUDIO_BOX_SIZE_ATTR)) {
|
||||
element.setAttribute(STUDIO_ORIGINAL_WIDTH_ATTR, element.style.getPropertyValue("width"));
|
||||
element.setAttribute(STUDIO_ORIGINAL_HEIGHT_ATTR, element.style.getPropertyValue("height"));
|
||||
// Measured here and only here: this branch runs once, before the draft
|
||||
// writes a width, so it is the last moment the element still has the box
|
||||
// the user started with. Offset sizes are layout, so a scale animation
|
||||
// running on the element does not distort them.
|
||||
element.setAttribute(STUDIO_ORIGINAL_BOX_WIDTH_ATTR, String(element.offsetWidth));
|
||||
element.setAttribute(STUDIO_ORIGINAL_BOX_HEIGHT_ATTR, String(element.offsetHeight));
|
||||
element.setAttribute(
|
||||
STUDIO_ORIGINAL_MIN_WIDTH_ATTR,
|
||||
element.style.getPropertyValue("min-width"),
|
||||
|
||||
@@ -17,6 +17,8 @@ import {
|
||||
STUDIO_ORIGINAL_INLINE_TRANSLATE_ATTR,
|
||||
STUDIO_ORIGINAL_WIDTH_ATTR,
|
||||
STUDIO_ORIGINAL_HEIGHT_ATTR,
|
||||
STUDIO_ORIGINAL_BOX_WIDTH_ATTR,
|
||||
STUDIO_ORIGINAL_BOX_HEIGHT_ATTR,
|
||||
STUDIO_ORIGINAL_MIN_WIDTH_ATTR,
|
||||
STUDIO_ORIGINAL_MIN_HEIGHT_ATTR,
|
||||
STUDIO_ORIGINAL_MAX_WIDTH_ATTR,
|
||||
@@ -222,6 +224,9 @@ describe("buildBoxSizePatches / buildClearBoxSizePatches", () => {
|
||||
{ type: "attribute", property: STUDIO_ORIGINAL_WIDTH_ATTR, value: null },
|
||||
{ type: "inline-style", property: "height", value: "150px" },
|
||||
{ type: "attribute", property: STUDIO_ORIGINAL_HEIGHT_ATTR, value: null },
|
||||
// Measurements, so they are cleared without restoring a style.
|
||||
{ type: "attribute", property: STUDIO_ORIGINAL_BOX_WIDTH_ATTR, value: null },
|
||||
{ type: "attribute", property: STUDIO_ORIGINAL_BOX_HEIGHT_ATTR, value: null },
|
||||
{ type: "inline-style", property: "min-width", value: "0px" },
|
||||
{ type: "attribute", property: STUDIO_ORIGINAL_MIN_WIDTH_ATTR, value: null },
|
||||
{ type: "inline-style", property: "min-height", value: "0px" },
|
||||
@@ -257,8 +262,8 @@ describe("buildBoxSizePatches / buildClearBoxSizePatches", () => {
|
||||
|
||||
it("clear: bare element emits only null ops — no style restores fire when orig attrs are absent", () => {
|
||||
const ops = buildClearBoxSizePatches(div());
|
||||
// 3 fixed (studio-width, studio-height, box-size marker) + 14 attr-null pushes (one per BOX_SIZE_ORIG_ATTR)
|
||||
expect(ops).toHaveLength(17);
|
||||
// 3 fixed (studio-width, studio-height, box-size marker) + 16 attr-null pushes (one per BOX_SIZE_ORIG_ATTR)
|
||||
expect(ops).toHaveLength(19);
|
||||
expect(ops.every((op) => op.value === null)).toBe(true);
|
||||
});
|
||||
|
||||
|
||||
@@ -13,6 +13,8 @@ import {
|
||||
STUDIO_ORIGINAL_INLINE_TRANSLATE_ATTR,
|
||||
STUDIO_ORIGINAL_WIDTH_ATTR,
|
||||
STUDIO_ORIGINAL_HEIGHT_ATTR,
|
||||
STUDIO_ORIGINAL_BOX_WIDTH_ATTR,
|
||||
STUDIO_ORIGINAL_BOX_HEIGHT_ATTR,
|
||||
STUDIO_ORIGINAL_MIN_WIDTH_ATTR,
|
||||
STUDIO_ORIGINAL_MIN_HEIGHT_ATTR,
|
||||
STUDIO_ORIGINAL_MAX_WIDTH_ATTR,
|
||||
@@ -135,6 +137,9 @@ const BOX_SIZE_STYLE_PROPS = [
|
||||
const BOX_SIZE_ORIG_ATTRS: ReadonlyArray<[string, string]> = [
|
||||
[STUDIO_ORIGINAL_WIDTH_ATTR, "width"],
|
||||
[STUDIO_ORIGINAL_HEIGHT_ATTR, "height"],
|
||||
// Records a measurement rather than a style, so it restores nothing.
|
||||
[STUDIO_ORIGINAL_BOX_WIDTH_ATTR, ""],
|
||||
[STUDIO_ORIGINAL_BOX_HEIGHT_ATTR, ""],
|
||||
[STUDIO_ORIGINAL_MIN_WIDTH_ATTR, "min-width"],
|
||||
[STUDIO_ORIGINAL_MIN_HEIGHT_ATTR, "min-height"],
|
||||
[STUDIO_ORIGINAL_MAX_WIDTH_ATTR, "max-width"],
|
||||
|
||||
@@ -17,6 +17,8 @@ import {
|
||||
STUDIO_ORIGINAL_INLINE_TRANSLATE_ATTR,
|
||||
STUDIO_ORIGINAL_WIDTH_ATTR,
|
||||
STUDIO_ORIGINAL_HEIGHT_ATTR,
|
||||
STUDIO_ORIGINAL_BOX_WIDTH_ATTR,
|
||||
STUDIO_ORIGINAL_BOX_HEIGHT_ATTR,
|
||||
STUDIO_ORIGINAL_MIN_WIDTH_ATTR,
|
||||
STUDIO_ORIGINAL_MIN_HEIGHT_ATTR,
|
||||
STUDIO_ORIGINAL_MAX_WIDTH_ATTR,
|
||||
@@ -60,6 +62,8 @@ export function captureStudioBoxSize(element: HTMLElement): StudioBoxSizeSnapsho
|
||||
marker: element.getAttribute(STUDIO_BOX_SIZE_ATTR),
|
||||
originalWidth: element.getAttribute(STUDIO_ORIGINAL_WIDTH_ATTR),
|
||||
originalHeight: element.getAttribute(STUDIO_ORIGINAL_HEIGHT_ATTR),
|
||||
originalBoxWidth: element.getAttribute(STUDIO_ORIGINAL_BOX_WIDTH_ATTR),
|
||||
originalBoxHeight: element.getAttribute(STUDIO_ORIGINAL_BOX_HEIGHT_ATTR),
|
||||
originalMinWidth: element.getAttribute(STUDIO_ORIGINAL_MIN_WIDTH_ATTR),
|
||||
originalMinHeight: element.getAttribute(STUDIO_ORIGINAL_MIN_HEIGHT_ATTR),
|
||||
originalMaxWidth: element.getAttribute(STUDIO_ORIGINAL_MAX_WIDTH_ATTR),
|
||||
@@ -128,6 +132,8 @@ export function restoreStudioBoxSize(element: HTMLElement, previous: StudioBoxSi
|
||||
restoreAttribute(element, STUDIO_BOX_SIZE_ATTR, previous.marker);
|
||||
restoreAttribute(element, STUDIO_ORIGINAL_WIDTH_ATTR, previous.originalWidth);
|
||||
restoreAttribute(element, STUDIO_ORIGINAL_HEIGHT_ATTR, previous.originalHeight);
|
||||
restoreAttribute(element, STUDIO_ORIGINAL_BOX_WIDTH_ATTR, previous.originalBoxWidth);
|
||||
restoreAttribute(element, STUDIO_ORIGINAL_BOX_HEIGHT_ATTR, previous.originalBoxHeight);
|
||||
restoreAttribute(element, STUDIO_ORIGINAL_MIN_WIDTH_ATTR, previous.originalMinWidth);
|
||||
restoreAttribute(element, STUDIO_ORIGINAL_MIN_HEIGHT_ATTR, previous.originalMinHeight);
|
||||
restoreAttribute(element, STUDIO_ORIGINAL_MAX_WIDTH_ATTR, previous.originalMaxWidth);
|
||||
|
||||
@@ -16,6 +16,18 @@ export const STUDIO_ORIGINAL_TRANSLATE_ATTR = "data-hf-studio-original-translate
|
||||
export const STUDIO_ORIGINAL_INLINE_TRANSLATE_ATTR = "data-hf-studio-original-inline-translate";
|
||||
export const STUDIO_ORIGINAL_WIDTH_ATTR = "data-hf-studio-original-width";
|
||||
export const STUDIO_ORIGINAL_HEIGHT_ATTR = "data-hf-studio-original-height";
|
||||
/**
|
||||
* The element's laid-out box before a resize draft touched it, in CSS pixels.
|
||||
*
|
||||
* The two attributes above record the element's INLINE width and height so a
|
||||
* reset can put them back, and are empty for the usual case of an element sized
|
||||
* by the stylesheet. That made them useless as a measurement, and the resize
|
||||
* intercept, which needs the original box to work out a scale, fell back to a
|
||||
* hardcoded guess and produced a wildly wrong one. These record the measurement
|
||||
* instead, and restore nothing.
|
||||
*/
|
||||
export const STUDIO_ORIGINAL_BOX_WIDTH_ATTR = "data-hf-studio-original-box-width";
|
||||
export const STUDIO_ORIGINAL_BOX_HEIGHT_ATTR = "data-hf-studio-original-box-height";
|
||||
export const STUDIO_ORIGINAL_MIN_WIDTH_ATTR = "data-hf-studio-original-min-width";
|
||||
export const STUDIO_ORIGINAL_MIN_HEIGHT_ATTR = "data-hf-studio-original-min-height";
|
||||
export const STUDIO_ORIGINAL_MAX_WIDTH_ATTR = "data-hf-studio-original-max-width";
|
||||
@@ -70,6 +82,8 @@ export interface StudioBoxSizeSnapshot {
|
||||
marker: string | null;
|
||||
originalWidth: string | null;
|
||||
originalHeight: string | null;
|
||||
originalBoxWidth: string | null;
|
||||
originalBoxHeight: string | null;
|
||||
originalMinWidth: string | null;
|
||||
originalMinHeight: string | null;
|
||||
originalMaxWidth: string | null;
|
||||
|
||||
Reference in New Issue
Block a user