mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-03 04:38:33 +00:00
fix(studio): add preview zoom controls (#761)
* fix(studio): add smooth preview zoom with pinch/Ctrl+scroll - Scale iframe content from inside (contentDocument.documentElement) instead of scaling the parent div, avoiding compositor re-rasterization on every zoom frame — critical for smooth zoom on high-refresh displays (240Hz) - Document-level capture-phase wheel handler bypasses the DomEditOverlay - Center-based zoom (no pan drift from pointer-anchored formulas) - Transient HUD shows zoom % briefly, no persistent UI controls - Double-click preview area to reset zoom to fit - Drag-to-pan when zoomed past 100% - Momentum scroll suppression after pinch gesture (400ms cooldown) - Delta clamping (MAX_DELTA=10) prevents overshooting on fast gestures - toDomPrecision rounds transform values to 4 decimals (matches tldraw) - Zoom state persisted to localStorage with 200ms debounce - Exposes --preview-zoom CSS custom property for overlay coordinate mapping - Fix infinite render loop in NLELayout (onIframeRef → refreshPreviewDocumentVersion) * fix(studio): use CSS zoom instead of transform scale for preview zoom CSS transform: scale() on a div containing an iframe causes compositor cross-layer sync issues that produce visible frame tearing on high-refresh displays (240Hz ProMotion). CSS zoom property changes the actual rendered size without compositor layer synchronization, eliminating the jumping. - Replace transform: scale(Z) with zoom: Z on the stage div - Keep transform: translate() for panning (compositor-friendly, no iframe) - Overlays work correctly since getBoundingClientRect() includes zoom - Remove will-change, transition hacks, pointer-events toggles * fix(ci): use apt-get for ffmpeg in preview-regression workflow The FedericoCarboni/setup-ffmpeg action downloads from an external URL that has been persistently unreachable, causing CI failures. Switch to apt-get install which uses Ubuntu's package repos (same as ci.yml and player-perf.yml). * fix(studio): clear zoom timers on NLEPreview unmount settleTimerRef, hudTimerRef, and retiringTimerRef could fire after component unmount. Add cleanup effect to prevent stale callbacks. * feat(studio): persist sidebar, timeline, and playback speed across reloads Wire up studioUiPreferences for the three remaining UI states requested in #752: left sidebar collapsed, timeline visibility, and playback rate. All three now survive page reloads using the same localStorage key as preview zoom.
This commit is contained in:
@@ -13,6 +13,7 @@ import { useManifestPersistence } from "./hooks/useManifestPersistence";
|
||||
import { useTimelineEditing } from "./hooks/useTimelineEditing";
|
||||
import { useDomEditSession } from "./hooks/useDomEditSession";
|
||||
import { useAppHotkeys } from "./hooks/useAppHotkeys";
|
||||
import { readStudioUiPreferences, writeStudioUiPreferences } from "./utils/studioUiPreferences";
|
||||
import { useCaptionDetection } from "./hooks/useCaptionDetection";
|
||||
import { useRenderClipContent } from "./hooks/useRenderClipContent";
|
||||
import { useConsoleErrorCapture } from "./hooks/useConsoleErrorCapture";
|
||||
@@ -98,8 +99,15 @@ export function StudioApp() {
|
||||
window.setTimeout(() => setPreviewDocumentVersion((v) => v + 1), 300);
|
||||
}, []);
|
||||
|
||||
const [timelineVisible, setTimelineVisible] = useState(true);
|
||||
const toggleTimelineVisibility = useCallback(() => setTimelineVisible((v) => !v), []);
|
||||
const [timelineVisible, setTimelineVisible] = useState(
|
||||
() => readStudioUiPreferences().timelineVisible ?? true,
|
||||
);
|
||||
const toggleTimelineVisibility = useCallback(() => {
|
||||
setTimelineVisible((v) => {
|
||||
writeStudioUiPreferences({ timelineVisible: !v });
|
||||
return !v;
|
||||
});
|
||||
}, []);
|
||||
const { appToast, showToast } = useToast();
|
||||
const panelLayout = usePanelLayout();
|
||||
const editHistory = usePersistentEditHistory({ projectId });
|
||||
|
||||
Reference in New Issue
Block a user