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/use-timeline-snapping.ts | |
| parent | 0173db99448d1c4c6415dcf15272e17551b48b04 (diff) | |
| download | opencut-7bf0984698e43b9aa2dd879f65951318ed410390.tar.gz | |
codebase overhaul (#697)
Diffstat (limited to 'apps/web/src/hooks/use-timeline-snapping.ts')
| -rw-r--r-- | apps/web/src/hooks/use-timeline-snapping.ts | 178 |
1 files changed, 0 insertions, 178 deletions
diff --git a/apps/web/src/hooks/use-timeline-snapping.ts b/apps/web/src/hooks/use-timeline-snapping.ts deleted file mode 100644 index f7f96392..00000000 --- a/apps/web/src/hooks/use-timeline-snapping.ts +++ /dev/null @@ -1,178 +0,0 @@ -import { useCallback } from "react"; -import { TimelineTrack } from "@/types/timeline"; -import { TIMELINE_CONSTANTS } from "@/constants/timeline-constants"; - -export interface SnapPoint { - time: number; - type: "element-start" | "element-end" | "playhead"; - elementId?: string; - trackId?: string; -} - -export interface SnapResult { - snappedTime: number; - snapPoint: SnapPoint | null; - snapDistance: number; -} - -export interface UseTimelineSnappingOptions { - snapThreshold?: number; // Distance in pixels to trigger snapping - enableElementSnapping?: boolean; - enablePlayheadSnapping?: boolean; -} - -export function useTimelineSnapping({ - snapThreshold = 10, - enableElementSnapping = true, - enablePlayheadSnapping = true, -}: UseTimelineSnappingOptions = {}) { - const findSnapPoints = useCallback( - ( - tracks: TimelineTrack[], - currentTime: number, - playheadTime: number, - zoomLevel: number, - excludeElementId?: string - ): SnapPoint[] => { - const snapPoints: SnapPoint[] = []; - - // Add element snap points - if (enableElementSnapping) { - tracks.forEach((track) => { - track.elements.forEach((element) => { - // Skip the element being dragged - if (element.id === excludeElementId) return; - - const elementStart = element.startTime; - const elementEnd = - element.startTime + - (element.duration - element.trimStart - element.trimEnd); - - snapPoints.push( - { - time: elementStart, - type: "element-start", - elementId: element.id, - trackId: track.id, - }, - { - time: elementEnd, - type: "element-end", - elementId: element.id, - trackId: track.id, - } - ); - }); - }); - } - - // Add playhead snap point - if (enablePlayheadSnapping) { - snapPoints.push({ - time: playheadTime, - type: "playhead", - }); - } - - return snapPoints; - }, - [enableElementSnapping, enablePlayheadSnapping] - ); - - const snapToNearestPoint = useCallback( - ( - targetTime: number, - snapPoints: SnapPoint[], - zoomLevel: number - ): SnapResult => { - const pixelsPerSecond = TIMELINE_CONSTANTS.PIXELS_PER_SECOND * zoomLevel; - const thresholdInSeconds = snapThreshold / pixelsPerSecond; - - let closestSnapPoint: SnapPoint | null = null; - let closestDistance = Infinity; - - snapPoints.forEach((snapPoint) => { - const distance = Math.abs(targetTime - snapPoint.time); - if (distance < thresholdInSeconds && distance < closestDistance) { - closestDistance = distance; - closestSnapPoint = snapPoint; - } - }); - - return { - snappedTime: closestSnapPoint - ? (closestSnapPoint as SnapPoint).time - : targetTime, - snapPoint: closestSnapPoint, - snapDistance: closestDistance, - }; - }, - [snapThreshold] - ); - - const snapElementPosition = useCallback( - ( - targetTime: number, - tracks: TimelineTrack[], - playheadTime: number, - zoomLevel: number, - excludeElementId?: string - ): SnapResult => { - const snapPoints = findSnapPoints( - tracks, - targetTime, - playheadTime, - zoomLevel, - excludeElementId - ); - - return snapToNearestPoint(targetTime, snapPoints, zoomLevel); - }, - [findSnapPoints, snapToNearestPoint] - ); - - const snapElementEdge = useCallback( - ( - targetTime: number, - elementDuration: number, - tracks: TimelineTrack[], - playheadTime: number, - zoomLevel: number, - excludeElementId?: string, - snapToStart = true // true for start edge, false for end edge - ): SnapResult => { - const snapPoints = findSnapPoints( - tracks, - targetTime, - playheadTime, - zoomLevel, - excludeElementId - ); - - // For end edge snapping, we need to account for element duration - const effectiveTargetTime = snapToStart - ? targetTime - : targetTime + elementDuration; - const snapResult = snapToNearestPoint( - effectiveTargetTime, - snapPoints, - zoomLevel - ); - - // Adjust the snapped time back for end edge - if (!snapToStart && snapResult.snapPoint) { - snapResult.snappedTime = snapResult.snappedTime - elementDuration; - } - - return snapResult; - }, - [findSnapPoints, snapToNearestPoint] - ); - - return { - snapElementPosition, - snapElementEdge, - findSnapPoints, - snapToNearestPoint, - }; -} |
