diff options
| author | Maze <167211895+mazeincoding@users.noreply.github.com> | 2026-01-31 00:20:04 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-01-31 00:20:04 +0100 |
| commit | 7bf0984698e43b9aa2dd879f65951318ed410390 (patch) | |
| tree | ccf2cd590a47d550152afc07129cb55c71a9ec35 /apps/web/src/hooks/timeline/use-snap-indicator-position.ts | |
| parent | 0173db99448d1c4c6415dcf15272e17551b48b04 (diff) | |
| download | opencut-7bf0984698e43b9aa2dd879f65951318ed410390.tar.gz | |
codebase overhaul (#697)
Diffstat (limited to 'apps/web/src/hooks/timeline/use-snap-indicator-position.ts')
| -rw-r--r-- | apps/web/src/hooks/timeline/use-snap-indicator-position.ts | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/apps/web/src/hooks/timeline/use-snap-indicator-position.ts b/apps/web/src/hooks/timeline/use-snap-indicator-position.ts new file mode 100644 index 00000000..c6ecbf7c --- /dev/null +++ b/apps/web/src/hooks/timeline/use-snap-indicator-position.ts @@ -0,0 +1,62 @@ +import { useEffect, useState } from "react"; +import { TIMELINE_CONSTANTS } from "@/constants/timeline-constants"; +import type { TimelineTrack } from "@/types/timeline"; + +interface UseSnapIndicatorPositionParams { + snapPoint: { time: number } | null; + zoomLevel: number; + tracks: TimelineTrack[]; + timelineRef: React.RefObject<HTMLDivElement>; + trackLabelsRef?: React.RefObject<HTMLDivElement>; + tracksScrollRef: React.RefObject<HTMLDivElement>; +} + +interface SnapIndicatorPosition { + leftPosition: number; + topPosition: number; + height: number; +} + +export function useSnapIndicatorPosition({ + snapPoint, + zoomLevel, + tracks, + timelineRef, + trackLabelsRef, + tracksScrollRef, +}: UseSnapIndicatorPositionParams): SnapIndicatorPosition { + const [scrollLeft, setScrollLeft] = useState(0); + + useEffect(() => { + const tracksViewport = tracksScrollRef.current; + + if (!tracksViewport) return; + + const handleScroll = () => { + setScrollLeft(tracksViewport.scrollLeft); + }; + + setScrollLeft(tracksViewport.scrollLeft); + + tracksViewport.addEventListener("scroll", handleScroll); + return () => tracksViewport.removeEventListener("scroll", handleScroll); + }, [tracksScrollRef]); + + const timelineContainerHeight = timelineRef.current?.offsetHeight || 400; + const totalHeight = timelineContainerHeight - 8; // 8px padding from edges + + const trackLabelsWidth = + tracks.length > 0 && trackLabelsRef?.current + ? trackLabelsRef.current.offsetWidth + : 0; + + const timelinePosition = + (snapPoint?.time || 0) * TIMELINE_CONSTANTS.PIXELS_PER_SECOND * zoomLevel; + const leftPosition = trackLabelsWidth + timelinePosition - scrollLeft; + + return { + leftPosition, + topPosition: 0, + height: totalHeight, + }; +} |
