From c56d6f8188cc1c0e72d75611269a8bda7b79e727 Mon Sep 17 00:00:00 2001 From: Maze Winther Date: Mon, 6 Apr 2026 00:57:54 +0200 Subject: [PATCH] fix: preserve negative start times during timeline drag --- .../element/use-element-interaction.ts | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/apps/web/src/hooks/timeline/element/use-element-interaction.ts b/apps/web/src/hooks/timeline/element/use-element-interaction.ts index fcc821fe..71ae4704 100644 --- a/apps/web/src/hooks/timeline/element/use-element-interaction.ts +++ b/apps/web/src/hooks/timeline/element/use-element-interaction.ts @@ -297,11 +297,12 @@ export function useElementInteraction({ zoomLevel, scrollLeft, }); - const adjustedTime = Math.max( - 0, - mouseTime - pendingDragRef.current.clickOffsetTime, - ); - const snappedTime = snapTimeToFrame({ time: adjustedTime, fps: activeProject.settings.fps }); + const adjustedTime = + mouseTime - pendingDragRef.current.clickOffsetTime; + const snappedTime = snapTimeToFrame({ + time: adjustedTime, + fps: activeProject.settings.fps, + }); startDrag({ ...pendingDragRef.current, initialCurrentTime: snappedTime, @@ -342,7 +343,7 @@ export function useElementInteraction({ zoomLevel, scrollLeft, }); - const adjustedTime = Math.max(0, mouseTime - dragState.clickOffsetTime); + const adjustedTime = mouseTime - dragState.clickOffsetTime; const fps = activeProject.settings.fps; const frameSnappedTime = snapTimeToFrame({ time: adjustedTime, fps }); @@ -455,6 +456,18 @@ export function useElementInteraction({ onSnapPointChange?.(null); return; } + const movingElement = + sourceTrack.elements.find(({ id }) => id === dragState.elementId) ?? null; + if ( + movingElement && + !dropTarget.isNewTrack && + tracks[dropTarget.trackIndex]?.id === dragState.trackId && + snappedTime === movingElement.startTime + ) { + endDrag(); + onSnapPointChange?.(null); + return; + } if (dropTarget.isNewTrack) { const newTrackId = generateUUID();