diff options
| author | Maze Winther <mazewinther@gmail.com> | 2026-04-26 02:50:04 +0200 |
|---|---|---|
| committer | Maze Winther <mazewinther@gmail.com> | 2026-04-26 02:50:04 +0200 |
| commit | eea6d43c82e1fd09d94d73001090dad205b1f1d2 (patch) | |
| tree | 384c92e467effb708bcc96e25117c064b18464b8 /apps/web/src/timeline/hooks/use-timeline-playhead.ts | |
| parent | f1b45b4328cff6a016720ce7b38b87ac2992dc2d (diff) | |
| download | opencut-eea6d43c82e1fd09d94d73001090dad205b1f1d2.tar.gz | |
fix: model editor time as wasm MediaTime ticks end-to-end
Diffstat (limited to 'apps/web/src/timeline/hooks/use-timeline-playhead.ts')
| -rw-r--r-- | apps/web/src/timeline/hooks/use-timeline-playhead.ts | 27 |
1 files changed, 15 insertions, 12 deletions
diff --git a/apps/web/src/timeline/hooks/use-timeline-playhead.ts b/apps/web/src/timeline/hooks/use-timeline-playhead.ts index 7d9cf447..6fbf2147 100644 --- a/apps/web/src/timeline/hooks/use-timeline-playhead.ts +++ b/apps/web/src/timeline/hooks/use-timeline-playhead.ts @@ -1,5 +1,5 @@ import { snappedSeekTime } from "opencut-wasm"; -import { TICKS_PER_SECOND } from "@/wasm"; +import { mediaTime, type MediaTime, TICKS_PER_SECOND } from "@/wasm"; import { useEffect, useCallback, useRef } from "react"; import { useEdgeAutoScroll } from "@/timeline/hooks/use-edge-auto-scroll"; import { useEditor } from "@/editor/use-editor"; @@ -53,11 +53,11 @@ export function useTimelinePlayhead({ }, [zoomLevel, duration, isScrubbing, editor.playback]); const seek = useCallback( - ({ time }: { time: number }) => editor.playback.seek({ time }), + ({ time }: { time: MediaTime }) => editor.playback.seek({ time }), [editor.playback], ); - const scrubTimeRef = useRef<number | null>(null); + const scrubTimeRef = useRef<MediaTime | null>(null); const isDraggingRulerRef = useRef(false); const hasDraggedRulerRef = useRef(false); const lastMouseXRef = useRef<number>(0); @@ -92,11 +92,14 @@ export function useTimelinePlayhead({ clampedMouseX / (BASE_TIMELINE_PIXELS_PER_SECOND * zoomLevel), ), ); - const rawTime = Math.round(rawTimeSeconds * TICKS_PER_SECOND); + const rawTime = mediaTime({ + ticks: Math.round(rawTimeSeconds * TICKS_PER_SECOND), + }); const rate = activeProject.settings.fps; - const frameTime = - snappedSeekTime({ time: rawTime, duration, rate }) ?? rawTime; + const frameTime = ( + snappedSeekTime({ time: rawTime, duration, rate }) ?? rawTime + ) as MediaTime; const shouldSnap = snappingEnabled && !isShiftHeldRef.current; const time = (() => { @@ -224,7 +227,7 @@ export function useTimelinePlayhead({ }, [isScrubbing, seek, handleScrub, editor, tracksScrollRef, zoomLevel]); const updatePlayheadLeft = useCallback( - (time: number) => { + (time: MediaTime) => { const playheadEl = playheadRef?.current; if (!playheadEl) return; const centerPosition = timelineTimeToSnappedPixels({ @@ -251,8 +254,7 @@ export function useTimelinePlayhead({ }, [editor.playback, rulerScrollRef, updatePlayheadLeft]); useEffect(() => { - const handlePlaybackUpdate = (e: Event) => { - const time = (e as CustomEvent<{ time: number }>).detail.time; + const handlePlaybackTime = (time: MediaTime) => { updatePlayheadLeft(time); if (!isPlayingRef.current || isScrubbingRef.current) return; @@ -280,11 +282,12 @@ export function useTimelinePlayhead({ rulerViewport.scrollLeft = tracksViewport.scrollLeft = desiredScroll; } }; + const handlePlaybackUpdate = (e: Event) => { + handlePlaybackTime((e as CustomEvent<{ time: MediaTime }>).detail.time); + }; const initialTime = editor.playback.getCurrentTime(); - handlePlaybackUpdate({ - detail: { time: initialTime }, - } as CustomEvent<{ time: number }>); + handlePlaybackTime(initialTime); window.addEventListener("playback-update", handlePlaybackUpdate); window.addEventListener("playback-seek", handlePlaybackUpdate); |
