diff options
Diffstat (limited to 'apps/web/src/hooks/use-timeline-element-resize.ts')
| -rw-r--r-- | apps/web/src/hooks/use-timeline-element-resize.ts | 50 |
1 files changed, 43 insertions, 7 deletions
diff --git a/apps/web/src/hooks/use-timeline-element-resize.ts b/apps/web/src/hooks/use-timeline-element-resize.ts index 0e409977..f16ca8e2 100644 --- a/apps/web/src/hooks/use-timeline-element-resize.ts +++ b/apps/web/src/hooks/use-timeline-element-resize.ts @@ -1,6 +1,7 @@ import { useState, useEffect } from "react"; import { ResizeState, TimelineElement, TimelineTrack } from "@/types/timeline"; import { useMediaStore } from "@/stores/media-store"; +import { useTimelineStore } from "@/stores/timeline-store"; interface UseTimelineElementResizeProps { element: TimelineElement; @@ -28,6 +29,7 @@ export function useTimelineElementResize({ }: UseTimelineElementResizeProps) { const [resizing, setResizing] = useState<ResizeState | null>(null); const { mediaItems } = useMediaStore(); + const { updateElementStartTime } = useTimelineStore(); // Set up document-level mouse listeners during resize (like proper drag behavior) useEffect(() => { @@ -100,12 +102,50 @@ export function useTimelineElementResize({ const deltaTime = deltaX / (50 * zoomLevel); if (resizing.side === "left") { - // Left resize - only trim within original duration + // Left resize - different behavior for media vs text/image elements const maxAllowed = element.duration - resizing.initialTrimEnd - 0.1; const calculated = resizing.initialTrimStart + deltaTime; - const newTrimStart = Math.max(0, Math.min(maxAllowed, calculated)); - onUpdateTrim(track.id, element.id, newTrimStart, resizing.initialTrimEnd); + if (calculated >= 0) { + // Normal trimming within available content + const newTrimStart = Math.min(maxAllowed, calculated); + const trimDelta = newTrimStart - resizing.initialTrimStart; + const newStartTime = element.startTime + trimDelta; + + onUpdateTrim( + track.id, + element.id, + newTrimStart, + resizing.initialTrimEnd + ); + updateElementStartTime(track.id, element.id, newStartTime); + } else { + // Trying to extend beyond trimStart = 0 + if (canExtendElementDuration()) { + // Text/Image: extend element to the left by moving startTime and increasing duration + const extensionAmount = Math.abs(calculated); + const newStartTime = element.startTime - extensionAmount; + const newDuration = element.duration + extensionAmount; + + // Keep trimStart at 0 and extend the element + onUpdateTrim(track.id, element.id, 0, resizing.initialTrimEnd); + onUpdateDuration(track.id, element.id, newDuration); + updateElementStartTime(track.id, element.id, newStartTime); + } else { + // Video/Audio: can't extend beyond original content - limit to trimStart = 0 + const newTrimStart = 0; + const trimDelta = newTrimStart - resizing.initialTrimStart; + const newStartTime = element.startTime + trimDelta; + + onUpdateTrim( + track.id, + element.id, + newTrimStart, + resizing.initialTrimEnd + ); + updateElementStartTime(track.id, element.id, newStartTime); + } + } } else { // Right resize - can extend duration for supported element types const calculated = resizing.initialTrimEnd - deltaTime; @@ -145,10 +185,6 @@ export function useTimelineElementResize({ } }; - const handleResizeMove = (e: React.MouseEvent) => { - updateTrimFromMouseMove(e); - }; - const handleResizeEnd = () => { setResizing(null); }; |
