summaryrefslogtreecommitdiff
path: root/apps/web/src/hooks/use-timeline-element-resize.ts
diff options
context:
space:
mode:
authorMaze Winther <mazewinther@gmail.com>2025-07-07 19:13:20 +0200
committerMaze Winther <mazewinther@gmail.com>2025-07-07 19:13:20 +0200
commitf3763b846543debeb3ebfdbbbee16f614931cb06 (patch)
treeec25797276ef9be77ebe1e442cd95cbc771eb9aa /apps/web/src/hooks/use-timeline-element-resize.ts
parentbd0c7f22069d1a2e4b2a2d962becaf6b9e942414 (diff)
downloadopencut-f3763b846543debeb3ebfdbbbee16f614931cb06.tar.gz
refactor: move element resize logic to react hook
Diffstat (limited to 'apps/web/src/hooks/use-timeline-element-resize.ts')
-rw-r--r--apps/web/src/hooks/use-timeline-element-resize.ts83
1 files changed, 83 insertions, 0 deletions
diff --git a/apps/web/src/hooks/use-timeline-element-resize.ts b/apps/web/src/hooks/use-timeline-element-resize.ts
new file mode 100644
index 00000000..b12087ea
--- /dev/null
+++ b/apps/web/src/hooks/use-timeline-element-resize.ts
@@ -0,0 +1,83 @@
+import { useState } from "react";
+import { ResizeState, TimelineElement, TimelineTrack } from "@/types/timeline";
+
+interface UseTimelineElementResizeProps {
+ element: TimelineElement;
+ track: TimelineTrack;
+ zoomLevel: number;
+ onUpdateTrim: (
+ trackId: string,
+ elementId: string,
+ trimStart: number,
+ trimEnd: number
+ ) => void;
+}
+
+export function useTimelineElementResize({
+ element,
+ track,
+ zoomLevel,
+ onUpdateTrim,
+}: UseTimelineElementResizeProps) {
+ const [resizing, setResizing] = useState<ResizeState | null>(null);
+
+ const handleResizeStart = (
+ e: React.MouseEvent,
+ elementId: string,
+ side: "left" | "right"
+ ) => {
+ e.stopPropagation();
+ e.preventDefault();
+
+ setResizing({
+ elementId,
+ side,
+ startX: e.clientX,
+ initialTrimStart: element.trimStart,
+ initialTrimEnd: element.trimEnd,
+ });
+ };
+
+ const updateTrimFromMouseMove = (e: { clientX: number }) => {
+ if (!resizing) return;
+
+ const deltaX = e.clientX - resizing.startX;
+ const deltaTime = deltaX / (50 * zoomLevel);
+
+ if (resizing.side === "left") {
+ const newTrimStart = Math.max(
+ 0,
+ Math.min(
+ element.duration - element.trimEnd - 0.1,
+ resizing.initialTrimStart + deltaTime
+ )
+ );
+ onUpdateTrim(track.id, element.id, newTrimStart, element.trimEnd);
+ } else {
+ const newTrimEnd = Math.max(
+ 0,
+ Math.min(
+ element.duration - element.trimStart - 0.1,
+ resizing.initialTrimEnd - deltaTime
+ )
+ );
+ onUpdateTrim(track.id, element.id, element.trimStart, newTrimEnd);
+ }
+ };
+
+ const handleResizeMove = (e: React.MouseEvent) => {
+ updateTrimFromMouseMove(e);
+ };
+
+ const handleResizeEnd = () => {
+ setResizing(null);
+ };
+
+ return {
+ resizing,
+ isResizing: resizing !== null,
+ handleResizeStart,
+ handleResizeMove,
+ handleResizeEnd,
+ };
+}