From fca99d6126c31fbb18ed9f1034cee6f940b040e8 Mon Sep 17 00:00:00 2001 From: Maze Winther Date: Tue, 10 Feb 2026 16:28:21 +0100 Subject: refactor --- .../editor/panels/timeline/timeline-playhead.tsx | 92 ++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 apps/web/src/components/editor/panels/timeline/timeline-playhead.tsx (limited to 'apps/web/src/components/editor/panels/timeline/timeline-playhead.tsx') diff --git a/apps/web/src/components/editor/panels/timeline/timeline-playhead.tsx b/apps/web/src/components/editor/panels/timeline/timeline-playhead.tsx new file mode 100644 index 00000000..8af35dc9 --- /dev/null +++ b/apps/web/src/components/editor/panels/timeline/timeline-playhead.tsx @@ -0,0 +1,92 @@ +"use client"; + +import { useRef } from "react"; +import { TIMELINE_CONSTANTS } from "@/constants/timeline-constants"; +import { useTimelinePlayhead } from "@/hooks/timeline/use-timeline-playhead"; +import { useEditor } from "@/hooks/use-editor"; + +interface TimelinePlayheadProps { + zoomLevel: number; + rulerRef: React.RefObject; + rulerScrollRef: React.RefObject; + tracksScrollRef: React.RefObject; + timelineRef: React.RefObject; + playheadRef?: React.RefObject; + isSnappingToPlayhead?: boolean; +} + +export function TimelinePlayhead({ + zoomLevel, + rulerRef, + rulerScrollRef, + tracksScrollRef, + timelineRef, + playheadRef: externalPlayheadRef, + isSnappingToPlayhead = false, +}: TimelinePlayheadProps) { + const editor = useEditor(); + const duration = editor.timeline.getTotalDuration(); + const internalPlayheadRef = useRef(null); + const playheadRef = externalPlayheadRef || internalPlayheadRef; + + const { playheadPosition, handlePlayheadMouseDown } = useTimelinePlayhead({ + zoomLevel, + rulerRef, + rulerScrollRef, + tracksScrollRef, + playheadRef, + }); + + const timelineContainerHeight = + tracksScrollRef.current?.clientHeight ?? + timelineRef.current?.clientHeight ?? + 400; + const totalHeight = Math.max(0, timelineContainerHeight - 4); + + const timelinePosition = + playheadPosition * TIMELINE_CONSTANTS.PIXELS_PER_SECOND * zoomLevel; + const leftPosition = timelinePosition; + + const handlePlayheadKeyDown = ( + event: React.KeyboardEvent, + ) => { + if (event.key !== "ArrowLeft" && event.key !== "ArrowRight") return; + + event.preventDefault(); + const step = 1 / Math.max(1, editor.project.getActive().settings.fps); + const direction = event.key === "ArrowRight" ? 1 : -1; + const nextTime = Math.max( + 0, + Math.min(duration, playheadPosition + direction * step), + ); + + editor.playback.seek({ time: nextTime }); + }; + + return ( +
+
+ +
+
+ ); +} -- cgit v1.3.1