diff --git a/src/components/video-editor/AnnotationOverlay.tsx b/src/components/video-editor/AnnotationOverlay.tsx index abbdf43f..4bdd44ec 100644 --- a/src/components/video-editor/AnnotationOverlay.tsx +++ b/src/components/video-editor/AnnotationOverlay.tsx @@ -40,6 +40,7 @@ function clampPercent(value: number) { return Math.min(100, Math.max(0, value)); } +/** Render an annotation in preview space with editor drag and resize controls. */ export function AnnotationOverlay({ annotation, isSelected, diff --git a/src/components/video-editor/VideoPlayback.tsx b/src/components/video-editor/VideoPlayback.tsx index 07727ec8..af8b49db 100644 --- a/src/components/video-editor/VideoPlayback.tsx +++ b/src/components/video-editor/VideoPlayback.tsx @@ -1252,6 +1252,9 @@ const VideoPlayback = forwardRef( useEffect(() => { zoomRegionsRef.current = zoomRegions; + if (!isPlayingRef.current) { + shouldSnapPausedFrameRef.current = true; + } }, [zoomRegions]); useEffect(() => { diff --git a/src/components/video-editor/videoPlayback/videoEventHandlers.ts b/src/components/video-editor/videoPlayback/videoEventHandlers.ts index c0c98000..4b6be5d2 100644 --- a/src/components/video-editor/videoPlayback/videoEventHandlers.ts +++ b/src/components/video-editor/videoPlayback/videoEventHandlers.ts @@ -27,6 +27,10 @@ interface VideoEventHandlersParams { speedRegionsRef: React.MutableRefObject; } +/** + * Bind media events to the preview's presented-frame clock while honoring trim + * and speed regions. + */ export function createVideoEventHandlers(params: VideoEventHandlersParams) { const { video, diff --git a/src/lib/exporter/captionRenderer.ts b/src/lib/exporter/captionRenderer.ts index 25846c30..03794acd 100644 --- a/src/lib/exporter/captionRenderer.ts +++ b/src/lib/exporter/captionRenderer.ts @@ -15,6 +15,7 @@ import { } from "@/components/video-editor/types"; import { drawSquircleOnCanvas } from "@/lib/geometry/squircle"; +/** Draw the active caption using the same typography and timing as preview. */ export function renderCaptions( ctx: CanvasRenderingContext2D, cues: CaptionCue[], diff --git a/src/lib/exporter/frameRenderer.ts b/src/lib/exporter/frameRenderer.ts index 7217c20a..473071d0 100644 --- a/src/lib/exporter/frameRenderer.ts +++ b/src/lib/exporter/frameRenderer.ts @@ -1661,6 +1661,7 @@ export class FrameRenderer { }; } + /** Advance the export camera from the shared scene target at this media time. */ private updateAnimationState(timeMs: number): number { if (!this.cameraContainer || !this.layoutCache) return 0; diff --git a/src/lib/exporter/modernFrameRenderer.ts b/src/lib/exporter/modernFrameRenderer.ts index 53f37b4e..25dc33c3 100644 --- a/src/lib/exporter/modernFrameRenderer.ts +++ b/src/lib/exporter/modernFrameRenderer.ts @@ -3343,6 +3343,7 @@ export class FrameRenderer { } } + /** Advance the export camera from the shared scene target at this media time. */ private updateAnimationState(timeMs: number): number { if (!this.cameraContainer || !this.layoutCache) { return 0; diff --git a/src/lib/exporter/modernVideoExporter.ts b/src/lib/exporter/modernVideoExporter.ts index be3889d8..b14c11a5 100644 --- a/src/lib/exporter/modernVideoExporter.ts +++ b/src/lib/exporter/modernVideoExporter.ts @@ -2096,6 +2096,7 @@ export class ModernVideoExporter { ); } + /** Build deterministic per-frame camera transforms for native compositors. */ private getNativeStaticLayoutZoomTelemetry( layout: ReturnType, totalFrames: number,