fix(studio): use declared dimensions for overlay scale during GSAP playback

When GSAP applies transforms (scale, translate) to the root composition
element during playback, rootRect.width/height from getBoundingClientRect()
changes to reflect the transformed size. The overlay scale calculation
(rootScaleX/Y = iframeRect / rootRect) then produces wrong values,
causing overlays to appear at incorrect positions during animated
playback — especially visible during scroll animations (y transform)
and entrance animations (scale transform).

Fix: use the composition's declared data-width/data-height attributes
for scale calculation. These are the canonical dimensions that don't
change with GSAP transforms. Falls back to rootRect dimensions when
the attributes aren't present (non-composition elements).
This commit is contained in:
Miguel Ángel
2026-05-25 19:47:53 -04:00
parent 07d14553c9
commit 825c0aa194
@@ -92,9 +92,16 @@ export function toOverlayRect(
const root =
doc?.querySelector<HTMLElement>("[data-composition-id]") ?? doc?.documentElement ?? null;
const rootRect = root?.getBoundingClientRect();
const rootWidth = rootRect?.width;
const rootHeight = rootRect?.height;
if (!rootWidth || !rootHeight) return null;
// Use the composition's declared dimensions (data-width/data-height) for scale
// calculation instead of rootRect.width/height. When GSAP applies transforms
// (scale, translate) to the root element, rootRect dimensions change but the
// composition's canonical size stays the same. Using rootRect causes overlay
// misalignment during animated playback.
const declaredWidth = readPositiveDimension(root?.getAttribute("data-width") ?? null);
const declaredHeight = readPositiveDimension(root?.getAttribute("data-height") ?? null);
const rootWidth = declaredWidth ?? rootRect?.width;
const rootHeight = declaredHeight ?? rootRect?.height;
if (!rootWidth || !rootHeight || !rootRect) return null;
const elementRect = element.getBoundingClientRect();
const rootScaleX = iframeRect.width / rootWidth;