fix: keyframe drag bug

This commit is contained in:
Maze Winther
2026-03-02 15:06:31 +01:00
parent 9261589ff3
commit 887d1795dd
@@ -9,7 +9,10 @@ import { useEditor } from "@/hooks/use-editor";
import { useKeyframeSelection } from "./use-keyframe-selection"; import { useKeyframeSelection } from "./use-keyframe-selection";
import { snapTimeToFrame } from "@/lib/time"; import { snapTimeToFrame } from "@/lib/time";
import { timelineTimeToSnappedPixels } from "@/lib/timeline"; import { timelineTimeToSnappedPixels } from "@/lib/timeline";
import { DRAG_THRESHOLD_PX, TIMELINE_CONSTANTS } from "@/constants/timeline-constants"; import {
DRAG_THRESHOLD_PX,
TIMELINE_CONSTANTS,
} from "@/constants/timeline-constants";
import { RetimeKeyframeCommand } from "@/lib/commands/timeline/element/keyframes/retime-keyframe"; import { RetimeKeyframeCommand } from "@/lib/commands/timeline/element/keyframes/retime-keyframe";
import { BatchCommand } from "@/lib/commands"; import { BatchCommand } from "@/lib/commands";
import type { SelectedKeyframeRef } from "@/types/animation"; import type { SelectedKeyframeRef } from "@/types/animation";
@@ -44,6 +47,7 @@ export function useKeyframeDrag({
const { const {
selectedKeyframes, selectedKeyframes,
isKeyframeSelected, isKeyframeSelected,
setKeyframeSelection,
toggleKeyframeSelection, toggleKeyframeSelection,
selectKeyframeRange, selectKeyframeRange,
} = useKeyframeSelection(); } = useKeyframeSelection();
@@ -74,9 +78,9 @@ export function useKeyframeDrag({
}) => { }) => {
const commands: Command[] = keyframeRefs.flatMap((keyframeRef) => { const commands: Command[] = keyframeRefs.flatMap((keyframeRef) => {
const channel = element.animations?.channels[keyframeRef.propertyPath]; const channel = element.animations?.channels[keyframeRef.propertyPath];
const keyframe = channel?.keyframes.find( const keyframe = channel?.keyframes.find(
(keyframe) => keyframe.id === keyframeRef.keyframeId, (keyframe) => keyframe.id === keyframeRef.keyframeId,
); );
if (!keyframe) return []; if (!keyframe) return [];
const nextTime = Math.max( const nextTime = Math.max(
0, 0,
@@ -115,9 +119,9 @@ export function useKeyframeDrag({
setIsPendingDrag(false); setIsPendingDrag(false);
setDragState({ setDragState({
isDragging: true, isDragging: true,
draggingKeyframeIds: new Set( draggingKeyframeIds: new Set(
pending.keyframeRefs.map((keyframe) => keyframe.keyframeId), pending.keyframeRefs.map((keyframe) => keyframe.keyframeId),
), ),
deltaTime: 0, deltaTime: 0,
}); });
return; return;
@@ -140,11 +144,11 @@ export function useKeyframeDrag({
if (!dragState.isDragging) return; if (!dragState.isDragging) return;
const handleMouseUp = () => { const handleMouseUp = () => {
const draggingRefs = selectedKeyframes.filter( const draggingRefs = selectedKeyframes.filter(
(keyframe) => (keyframe) =>
keyframe.elementId === element.id && keyframe.elementId === element.id &&
dragState.draggingKeyframeIds.has(keyframe.keyframeId), dragState.draggingKeyframeIds.has(keyframe.keyframeId),
); );
if (draggingRefs.length > 0 && dragState.deltaTime !== 0) { if (draggingRefs.length > 0 && dragState.deltaTime !== 0) {
commitDrag({ commitDrag({
@@ -191,21 +195,26 @@ export function useKeyframeDrag({
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
mouseDownXRef.current = event.clientX; mouseDownXRef.current = event.clientX;
const anySelected = keyframes.some((keyframe) => const anySelected = keyframes.some((keyframe) =>
isKeyframeSelected({ keyframe }), isKeyframeSelected({ keyframe }),
); );
const keyframeRefsToTrack = anySelected ? selectedKeyframes : keyframes;
pendingDragRef.current = { if (!anySelected) {
keyframeRefs: keyframeRefsToTrack, setKeyframeSelection({ keyframes });
startMouseX: event.clientX, }
};
setIsPendingDrag(true); const keyframeRefsToTrack = anySelected ? selectedKeyframes : keyframes;
},
[isKeyframeSelected, selectedKeyframes], pendingDragRef.current = {
); keyframeRefs: keyframeRefsToTrack,
startMouseX: event.clientX,
};
setIsPendingDrag(true);
},
[isKeyframeSelected, selectedKeyframes, setKeyframeSelection],
);
const handleKeyframeClick = useCallback( const handleKeyframeClick = useCallback(
({ ({