diff options
| author | Maze <167211895+mazeincoding@users.noreply.github.com> | 2025-07-15 14:17:50 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-07-15 14:17:50 +0200 |
| commit | f5ed3e196a8b9c48941646f5cd8fd7676816623a (patch) | |
| tree | 18bb88c1e850f8da0e66c0381220f8a04b8fefda /apps/web/src/components/editor/snap-indicator.tsx | |
| parent | cb877769fba83ddb7131e103581edb14f4cf2e92 (diff) | |
| parent | 1fdf2a051529e40cf7a0857d31a83057b878f08d (diff) | |
| download | opencut-f5ed3e196a8b9c48941646f5cd8fd7676816623a.tar.gz | |
Merge pull request #266 from anwarulislam/feat/snapping
feature: add timeline snapping functionality
Diffstat (limited to 'apps/web/src/components/editor/snap-indicator.tsx')
| -rw-r--r-- | apps/web/src/components/editor/snap-indicator.tsx | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/apps/web/src/components/editor/snap-indicator.tsx b/apps/web/src/components/editor/snap-indicator.tsx new file mode 100644 index 00000000..83a1f678 --- /dev/null +++ b/apps/web/src/components/editor/snap-indicator.tsx @@ -0,0 +1,54 @@ +"use client"; + +import { SnapPoint } from "@/hooks/use-timeline-snapping"; +import { TIMELINE_CONSTANTS } from "@/constants/timeline-constants"; +import type { TimelineTrack } from "@/types/timeline"; + +interface SnapIndicatorProps { + snapPoint: SnapPoint | null; + zoomLevel: number; + isVisible: boolean; + tracks: TimelineTrack[]; + timelineRef: React.RefObject<HTMLDivElement>; + trackLabelsRef?: React.RefObject<HTMLDivElement>; +} + +export function SnapIndicator({ + snapPoint, + zoomLevel, + isVisible, + tracks, + timelineRef, + trackLabelsRef, +}: SnapIndicatorProps) { + if (!isVisible || !snapPoint) { + return null; + } + + const timelineContainerHeight = timelineRef.current?.offsetHeight || 400; + const totalHeight = timelineContainerHeight - 8; // 8px padding from edges + + // Get dynamic track labels width, fallback to 0 if no tracks or no ref + const trackLabelsWidth = + tracks.length > 0 && trackLabelsRef?.current + ? trackLabelsRef.current.offsetWidth + : 0; + + const leftPosition = + trackLabelsWidth + + snapPoint.time * TIMELINE_CONSTANTS.PIXELS_PER_SECOND * zoomLevel; + + return ( + <div + className="absolute pointer-events-none z-[90]" + style={{ + left: `${leftPosition}px`, + top: 0, + height: `${totalHeight}px`, + width: "2px", + }} + > + <div className={`w-0.5 h-full bg-primary/40 opacity-80`} /> + </div> + ); +} |
