diff options
| author | Maze Winther <mazewinther@gmail.com> | 2026-03-25 16:47:22 +0100 |
|---|---|---|
| committer | Maze Winther <mazewinther@gmail.com> | 2026-03-29 15:48:22 +0200 |
| commit | 8db3bead13441a5882d8689dfc6a9f09c82375d9 (patch) | |
| tree | e9d0cafa93904ffcbec3188c37961bcc16c6422d /apps/web/src/components/editor/panels/timeline/timeline-playhead.tsx | |
| parent | 39ea298a9ccba3104c549c0ca079c231981811f5 (diff) | |
| download | opencut-8db3bead13441a5882d8689dfc6a9f09c82375d9.tar.gz | |
feat: masks, properties refactor, shaders, storage migrations, and more
Diffstat (limited to 'apps/web/src/components/editor/panels/timeline/timeline-playhead.tsx')
| -rw-r--r-- | apps/web/src/components/editor/panels/timeline/timeline-playhead.tsx | 38 |
1 files changed, 25 insertions, 13 deletions
diff --git a/apps/web/src/components/editor/panels/timeline/timeline-playhead.tsx b/apps/web/src/components/editor/panels/timeline/timeline-playhead.tsx index e290259e..1abe65bd 100644 --- a/apps/web/src/components/editor/panels/timeline/timeline-playhead.tsx +++ b/apps/web/src/components/editor/panels/timeline/timeline-playhead.tsx @@ -8,9 +8,14 @@ import { } from "@/lib/timeline"; import { useTimelinePlayhead } from "@/hooks/timeline/use-timeline-playhead"; import { useEditor } from "@/hooks/use-editor"; +import { + TIMELINE_LAYERS, + TIMELINE_SCROLLBAR_SIZE_PX, +} from "@/constants/timeline-constants"; interface TimelinePlayheadProps { zoomLevel: number; + hasHorizontalScrollbar: boolean; rulerRef: React.RefObject<HTMLDivElement | null>; rulerScrollRef: React.RefObject<HTMLDivElement | null>; tracksScrollRef: React.RefObject<HTMLDivElement | null>; @@ -21,6 +26,7 @@ interface TimelinePlayheadProps { export function TimelinePlayhead({ zoomLevel, + hasHorizontalScrollbar, rulerRef, rulerScrollRef, tracksScrollRef, @@ -33,7 +39,7 @@ export function TimelinePlayhead({ const internalPlayheadRef = useRef<HTMLDivElement>(null); const playheadRef = externalPlayheadRef || internalPlayheadRef; - const { playheadPosition, handlePlayheadMouseDown } = useTimelinePlayhead({ + const { handlePlayheadMouseDown } = useTimelinePlayhead({ zoomLevel, rulerRef, rulerScrollRef, @@ -42,16 +48,23 @@ export function TimelinePlayhead({ }); const timelineContainerHeight = - tracksScrollRef.current?.clientHeight ?? timelineRef.current?.clientHeight ?? + tracksScrollRef.current?.clientHeight ?? 400; - const totalHeight = Math.max(0, timelineContainerHeight - 4); + const totalHeight = Math.max( + 0, + timelineContainerHeight - + (hasHorizontalScrollbar ? TIMELINE_SCROLLBAR_SIZE_PX - 5 : 0), + ); + const currentTime = editor.playback.getCurrentTime(); const centerPosition = timelineTimeToSnappedPixels({ - time: playheadPosition, + time: currentTime, zoomLevel, }); - const leftPosition = getCenteredLineLeft({ centerPixel: centerPosition }); + const scrollLeft = tracksScrollRef.current?.scrollLeft ?? 0; + const leftPosition = + getCenteredLineLeft({ centerPixel: centerPosition }) - scrollLeft; const handlePlayheadKeyDown = ( event: React.KeyboardEvent<HTMLDivElement>, @@ -61,10 +74,8 @@ export function TimelinePlayhead({ 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), - ); + const now = editor.playback.getCurrentTime(); + const nextTime = Math.max(0, Math.min(duration, now + direction * step)); editor.playback.seek({ time: nextTime }); }; @@ -76,23 +87,24 @@ export function TimelinePlayhead({ aria-label="Timeline playhead" aria-valuemin={0} aria-valuemax={duration} - aria-valuenow={playheadPosition} + aria-valuenow={currentTime} tabIndex={0} - className="pointer-events-none absolute z-5" + className="pointer-events-none absolute" style={{ left: `${leftPosition}px`, top: 0, height: `${totalHeight}px`, width: `${TIMELINE_INDICATOR_LINE_WIDTH_PX}px`, + zIndex: TIMELINE_LAYERS.playhead, }} onKeyDown={handlePlayheadKeyDown} > - <div className="bg-foreground pointer-events-none absolute left-0 h-full w-0.5" /> + <div className="bg-primary pointer-events-none absolute left-0 h-full w-0.5" /> <button type="button" aria-label="Drag playhead" - className={`pointer-events-auto absolute top-1 left-1/2 size-3 -translate-x-1/2 transform cursor-col-resize rounded-full border-2 shadow-xs ${isSnappingToPlayhead ? "bg-foreground border-foreground" : "bg-foreground border-foreground/50"}`} + className={`pointer-events-auto absolute top-1 left-1/2 size-3 -translate-x-1/2 transform cursor-col-resize rounded-full border-2 shadow-xs ${isSnappingToPlayhead ? "bg-primary border-primary" : "bg-primary border-primary/50"}`} onMouseDown={handlePlayheadMouseDown} /> </div> |
