summaryrefslogtreecommitdiff
path: root/apps/web/src/components
diff options
context:
space:
mode:
authorAnwarul Islam <anwaarulislaam@gmail.com>2025-07-15 04:23:45 +0600
committerAnwarul Islam <anwaarulislaam@gmail.com>2025-07-15 04:23:45 +0600
commit4de81796a34f43d40e188f11f298943bb0654972 (patch)
tree84882c3a0a049949f09cc4a18dd6b9755282f2b6 /apps/web/src/components
parent55978c30fa8629840995922e76a98ad4b2045b80 (diff)
downloadopencut-4de81796a34f43d40e188f11f298943bb0654972.tar.gz
feat: add SnapIndicator component for timeline snapping visualization
Diffstat (limited to 'apps/web/src/components')
-rw-r--r--apps/web/src/components/editor/snap-indicator.tsx75
1 files changed, 75 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..398e06c6
--- /dev/null
+++ b/apps/web/src/components/editor/snap-indicator.tsx
@@ -0,0 +1,75 @@
+"use client";
+
+import { SnapPoint } from "@/hooks/use-timeline-snapping";
+import { TIMELINE_CONSTANTS } from "@/constants/timeline-constants";
+
+interface SnapIndicatorProps {
+ snapPoint: SnapPoint | null;
+ zoomLevel: number;
+ timelineHeight: number;
+ isVisible: boolean;
+}
+
+export function SnapIndicator({
+ snapPoint,
+ zoomLevel,
+ timelineHeight,
+ isVisible,
+}: SnapIndicatorProps) {
+ if (!isVisible || !snapPoint) {
+ return null;
+ }
+
+ const leftPosition =
+ snapPoint.time * TIMELINE_CONSTANTS.PIXELS_PER_SECOND * zoomLevel;
+
+ const getIndicatorColor = () => {
+ switch (snapPoint.type) {
+ case "grid":
+ return "bg-blue-400";
+ case "element-start":
+ case "element-end":
+ return "bg-green-400";
+ case "playhead":
+ return "bg-red-400";
+ default:
+ return "bg-gray-400";
+ }
+ };
+
+ const getIndicatorLabel = () => {
+ switch (snapPoint.type) {
+ case "grid":
+ return "Grid";
+ case "element-start":
+ return "Start";
+ case "element-end":
+ return "End";
+ case "playhead":
+ return "Playhead";
+ default:
+ return "";
+ }
+ };
+
+ return (
+ <div
+ className="absolute top-0 pointer-events-none z-50"
+ style={{
+ left: `${leftPosition}px`,
+ height: `${timelineHeight}px`,
+ }}
+ >
+ {/* Snap line */}
+ <div className={`w-0.5 h-full ${getIndicatorColor()} opacity-80`} />
+
+ {/* Snap label */}
+ <div
+ className={`absolute top-0 left-1 px-1 py-0.5 text-xs text-white rounded ${getIndicatorColor()} opacity-90 whitespace-nowrap`}
+ style={{ transform: "translateY(-100%)" }}
+ >
+ {getIndicatorLabel()} ({snapPoint.time.toFixed(1)}s)
+ </div>
+ </div>
+ );
+}