summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorAnwarul Islam <anwaarulislaam@gmail.com>2025-07-15 04:27:19 +0600
committerAnwarul Islam <anwaarulislaam@gmail.com>2025-07-15 04:27:19 +0600
commit1106aeeb60b493f85bd70685f066362aa43fcd6e (patch)
treeee156295bdcf15b0e7df47b002a9c313337efc82 /apps
parentaf632d8cc5100124ebd12ba0173d01ba651cccd8 (diff)
downloadopencut-1106aeeb60b493f85bd70685f066362aa43fcd6e.tar.gz
feat: integrate snapping functionality into timeline track component
Diffstat (limited to 'apps')
-rw-r--r--apps/web/src/components/editor/timeline-track.tsx42
1 files changed, 37 insertions, 5 deletions
diff --git a/apps/web/src/components/editor/timeline-track.tsx b/apps/web/src/components/editor/timeline-track.tsx
index 033b79a6..0b29c778 100644
--- a/apps/web/src/components/editor/timeline-track.tsx
+++ b/apps/web/src/components/editor/timeline-track.tsx
@@ -22,6 +22,7 @@ import {
TIMELINE_CONSTANTS,
} from "@/constants/timeline-constants";
import { useProjectStore } from "@/stores/project-store";
+import { useTimelineSnapping } from "@/hooks/use-timeline-snapping";
export function TimelineTrackContent({
track,
@@ -45,8 +46,25 @@ export function TimelineTrackContent({
endDrag: endDragAction,
clearSelectedElements,
insertTrackAt,
+ snappingEnabled,
+ gridSnappingEnabled,
+ elementSnappingEnabled,
+ playheadSnappingEnabled,
+ snapThreshold,
+ gridInterval,
} = useTimelineStore();
+ const { currentTime } = usePlaybackStore();
+
+ // Initialize snapping hook
+ const { snapElementPosition } = useTimelineSnapping({
+ snapThreshold,
+ gridInterval,
+ enableGridSnapping: snappingEnabled && gridSnappingEnabled,
+ enableElementSnapping: snappingEnabled && elementSnappingEnabled,
+ enablePlayheadSnapping: snappingEnabled && playheadSnappingEnabled,
+ });
+
const timelineRef = useRef<HTMLDivElement>(null);
const [isDropping, setIsDropping] = useState(false);
const [dropPosition, setDropPosition] = useState<number | null>(null);
@@ -85,12 +103,26 @@ export function TimelineTrackContent({
mouseX / (TIMELINE_CONSTANTS.PIXELS_PER_SECOND * zoomLevel)
);
const adjustedTime = Math.max(0, mouseTime - dragState.clickOffsetTime);
- // Use frame snapping if project has FPS, otherwise use decimal snapping
- const projectStore = useProjectStore.getState();
- const projectFps = projectStore.activeProject?.fps || 30;
- const snappedTime = snapTimeToFrame(adjustedTime, projectFps);
- updateDragTime(snappedTime);
+ // Apply snapping if enabled
+ let finalTime = adjustedTime;
+ if (snappingEnabled) {
+ const snapResult = snapElementPosition(
+ adjustedTime,
+ tracks,
+ currentTime,
+ zoomLevel,
+ dragState.elementId || undefined
+ );
+ finalTime = snapResult.snappedTime;
+ } else {
+ // Use frame snapping if project has FPS, otherwise use decimal snapping
+ const projectStore = useProjectStore.getState();
+ const projectFps = projectStore.activeProject?.fps || 30;
+ finalTime = snapTimeToFrame(adjustedTime, projectFps);
+ }
+
+ updateDragTime(finalTime);
};
const handleMouseUp = (e: MouseEvent) => {