diff --git a/packages/studio/src/components/editor/domEditOverlayGeometry.ts b/packages/studio/src/components/editor/domEditOverlayGeometry.ts index 647c92174..56620788d 100644 --- a/packages/studio/src/components/editor/domEditOverlayGeometry.ts +++ b/packages/studio/src/components/editor/domEditOverlayGeometry.ts @@ -92,9 +92,16 @@ export function toOverlayRect( const root = doc?.querySelector("[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;