summaryrefslogtreecommitdiff
path: root/apps/web/src/hooks/timeline/use-timeline-playhead.ts
diff options
context:
space:
mode:
authorMaze Winther <mazewinther@gmail.com>2026-03-01 01:32:09 +0100
committerMaze Winther <mazewinther@gmail.com>2026-03-01 01:32:09 +0100
commit5e7c27f542e94ffee5d2106ce318b6f43cc7e738 (patch)
treeb33c3370c01b9b2ee685f1039543bc02f8764f7b /apps/web/src/hooks/timeline/use-timeline-playhead.ts
parent744419469da403be57d30b5b19f6b43246caa57d (diff)
parent354f4dec67ef7eb39d34fca941ca34025a68136b (diff)
downloadopencut-5e7c27f542e94ffee5d2106ce318b6f43cc7e738.tar.gz
Merge branch 'dev' into ripple-editing
Diffstat (limited to 'apps/web/src/hooks/timeline/use-timeline-playhead.ts')
-rw-r--r--apps/web/src/hooks/timeline/use-timeline-playhead.ts64
1 files changed, 35 insertions, 29 deletions
diff --git a/apps/web/src/hooks/timeline/use-timeline-playhead.ts b/apps/web/src/hooks/timeline/use-timeline-playhead.ts
index 44e12ab1..1426a003 100644
--- a/apps/web/src/hooks/timeline/use-timeline-playhead.ts
+++ b/apps/web/src/hooks/timeline/use-timeline-playhead.ts
@@ -4,9 +4,9 @@ import { useEdgeAutoScroll } from "@/hooks/timeline/use-edge-auto-scroll";
import { useEditor } from "../use-editor";
import { useShiftKey } from "@/hooks/use-shift-key";
import {
- useTimelineSnapping,
- type SnapPoint,
-} from "@/hooks/timeline/use-timeline-snapping";
+ findSnapPoints,
+ snapToNearestPoint,
+} from "@/lib/timeline/snap-utils";
import { TIMELINE_CONSTANTS } from "@/constants/timeline-constants";
interface UseTimelinePlayheadProps {
@@ -31,10 +31,6 @@ export function useTimelinePlayhead({
const isPlaying = editor.playback.getIsPlaying();
const isScrubbing = editor.playback.getIsScrubbing();
const isShiftHeldRef = useShiftKey();
- const { snapToNearestPoint } = useTimelineSnapping({
- enableElementSnapping: false,
- enablePlayheadSnapping: false,
- });
const seek = useCallback(
({ time }: { time: number }) => editor.playback.seek({ time }),
@@ -51,7 +47,13 @@ export function useTimelinePlayhead({
isScrubbing && scrubTime !== null ? scrubTime : currentTime;
const handleScrub = useCallback(
- ({ event }: { event: MouseEvent | React.MouseEvent }) => {
+ ({
+ event,
+ snappingEnabled = true,
+ }: {
+ event: MouseEvent | React.MouseEvent;
+ snappingEnabled?: boolean;
+ }) => {
const ruler = rulerRef.current;
if (!ruler) return;
const rulerRect = ruler.getBoundingClientRect();
@@ -80,21 +82,25 @@ export function useTimelinePlayhead({
fps: framesPerSecond,
});
- const bookmarks = editor.scenes.getActiveScene()?.bookmarks ?? [];
- const bookmarkSnapPoints: SnapPoint[] = bookmarks.map((bookmark) => ({
- time: bookmark.time,
- type: "bookmark",
- }));
- const shouldSnapToBookmark =
- !isShiftHeldRef.current && bookmarkSnapPoints.length > 0;
- const snapResult = shouldSnapToBookmark
- ? snapToNearestPoint({
- targetTime: frameTime,
- snapPoints: bookmarkSnapPoints,
- zoomLevel,
- })
- : null;
- const time = snapResult?.snapPoint ? snapResult.snappedTime : frameTime;
+ const shouldSnap = snappingEnabled && !isShiftHeldRef.current;
+ const time = (() => {
+ if (!shouldSnap) return frameTime;
+ const tracks = editor.timeline.getTracks();
+ const bookmarks =
+ editor.scenes.getActiveScene()?.bookmarks ?? [];
+ const snapPoints = findSnapPoints({
+ tracks,
+ playheadTime: frameTime,
+ bookmarks,
+ enablePlayheadSnapping: false,
+ });
+ const snapResult = snapToNearestPoint({
+ targetTime: frameTime,
+ snapPoints,
+ zoomLevel,
+ });
+ return snapResult.snapPoint ? snapResult.snappedTime : frameTime;
+ })();
setScrubTime(time);
seek({ time });
@@ -109,7 +115,7 @@ export function useTimelinePlayhead({
activeProject.settings.fps,
isShiftHeldRef,
editor.scenes,
- snapToNearestPoint,
+ editor.timeline,
],
);
@@ -133,10 +139,10 @@ export function useTimelinePlayhead({
setIsDraggingRuler(true);
setHasDraggedRuler(false);
- editor.playback.setScrubbing({ isScrubbing: true });
- handleScrub({ event });
- },
- [handleScrub, playheadRef, editor.playback],
+ editor.playback.setScrubbing({ isScrubbing: true });
+ handleScrub({ event, snappingEnabled: false });
+ },
+ [handleScrub, playheadRef, editor.playback],
);
const handlePlayheadMouseDownEvent = useCallback(
@@ -184,7 +190,7 @@ export function useTimelinePlayhead({
if (isDraggingRuler) {
setIsDraggingRuler(false);
if (!hasDraggedRuler) {
- handleScrub({ event });
+ handleScrub({ event, snappingEnabled: false });
}
setHasDraggedRuler(false);
}