Skip to content

fix(studio): canvas border expands when zooming — switch from CSS zoom to transform scale#810

Closed
miguel-heygen wants to merge 5 commits into
mainfrom
fix/preview-zoom-padding
Closed

fix(studio): canvas border expands when zooming — switch from CSS zoom to transform scale#810
miguel-heygen wants to merge 5 commits into
mainfrom
fix/preview-zoom-padding

Conversation

@miguel-heygen
Copy link
Copy Markdown
Collaborator

Summary

  • Replaces stage.style.zoom with CSS transform: scale() on the preview stage element
  • Changes transformOrigin from "0 0" (top-left) to "50% 50%" (centre) to match the existing pan-clamping formula

Root cause

CSS zoom is a layout property. Changing it at runtime triggers ResizeObserver on descendant elements, which causes scaleIframeToFit to re-run with getBoundingClientRect() values that are already inflated by the zoom factor. The iframe ends up scaled too small relative to the player's visual bounds, and the visible letterbox grows as zoom increases — the "canvas border expands inward" symptom reported in #752.

CSS transform: scale() is visual-only. ResizeObserver never fires on scale changes, so scaleIframeToFit keeps the scale it computed on initial mount (based on layout dimensions). The parent transform then magnifies the player and composition uniformly, so the composition always fills the player's visual bounds at any zoom level.

Test plan

  • Open Studio preview, zoom in and out with Ctrl+scroll or the zoom buttons — no visible letterbox should appear at any zoom level
  • Reload the page with a non-default stored zoom — composition should fill correctly on mount
  • Pan while zoomed in — pan clamping should feel symmetrical (previously it was asymmetric because origin was top-left)

Closes #752

@miguel-heygen miguel-heygen force-pushed the fix/preview-zoom-padding branch from 09333bd to 35f64ed Compare May 13, 2026 23:16
Adds a subtle outline and drop shadow to the composition stage so it
reads as a distinct canvas against the neutral-900 workspace background.
@miguel-heygen miguel-heygen force-pushed the fix/preview-zoom-padding branch from 35f64ed to cda6d21 Compare May 13, 2026 23:25
…view

The viewport's focus:ring was appearing as a teal border when zooming
via Ctrl+wheel. Switch to focus-visible: so the ring only shows on
keyboard navigation, not on pointer/scroll focus.
CSS zoom on absolute inset-2 affects layout metrics, causing the canvas
to shift/shrink incorrectly at non-100% zoom levels. transform scale is
visual-only (no layout side effects) and aligns with the center-origin
pan clamping math in clampPreviewPan.
Remove redundant zoom clear on every frame and add will-change: transform
so the outline and box-shadow are pre-composited on their own GPU layer
instead of repainting on each zoom step.
…d CSS zoom double-scaling

getBoundingClientRect() returns visual dimensions inflated by ancestor CSS zoom.
When the preview stage has zoom: 2, the player's rect was 2x its layout size,
so scaleIframeToFit computed a 2x scale — then CSS zoom doubled it again.
offsetWidth/offsetHeight return layout dimensions regardless of ancestor zoom,
giving the correct scale at every zoom level.

Reverts the NLEPreview writeTransform back to CSS zoom (smooth, native) now
that the root cause in scaleIframeToFit is fixed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

(studio) Add Zoom/Scaling controls for Video Preview

1 participant