mirror of
https://github.com/OpenCut-app/OpenCut.git
synced 2026-07-13 21:52:53 +02:00
clcik to seek on keyframes
This commit is contained in:
@@ -259,7 +259,7 @@ export function TimelineElement({
|
|||||||
handleKeyframeMouseDown,
|
handleKeyframeMouseDown,
|
||||||
handleKeyframeClick,
|
handleKeyframeClick,
|
||||||
getVisualOffsetPx,
|
getVisualOffsetPx,
|
||||||
} = useKeyframeDrag({ zoomLevel, element });
|
} = useKeyframeDrag({ zoomLevel, element, displayedStartTime });
|
||||||
const handleRevealInMedia = ({ event }: { event: React.MouseEvent }) => {
|
const handleRevealInMedia = ({ event }: { event: React.MouseEvent }) => {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
if (hasMediaId(element)) {
|
if (hasMediaId(element)) {
|
||||||
@@ -516,6 +516,7 @@ function KeyframeIndicators({
|
|||||||
event: React.MouseEvent;
|
event: React.MouseEvent;
|
||||||
keyframes: SelectedKeyframeRef[];
|
keyframes: SelectedKeyframeRef[];
|
||||||
orderedKeyframes: SelectedKeyframeRef[];
|
orderedKeyframes: SelectedKeyframeRef[];
|
||||||
|
indicatorTime: number;
|
||||||
}) => void;
|
}) => void;
|
||||||
getVisualOffsetPx: (params: {
|
getVisualOffsetPx: (params: {
|
||||||
indicatorTime: number;
|
indicatorTime: number;
|
||||||
@@ -554,12 +555,13 @@ function KeyframeIndicators({
|
|||||||
onMouseDown={(event) =>
|
onMouseDown={(event) =>
|
||||||
onKeyframeMouseDown({ event, keyframes: indicator.keyframes })
|
onKeyframeMouseDown({ event, keyframes: indicator.keyframes })
|
||||||
}
|
}
|
||||||
onClick={(event) =>
|
onClick={(event) =>
|
||||||
onKeyframeClick({
|
onKeyframeClick({
|
||||||
event,
|
event,
|
||||||
keyframes: indicator.keyframes,
|
keyframes: indicator.keyframes,
|
||||||
orderedKeyframes,
|
orderedKeyframes,
|
||||||
})
|
indicatorTime: indicator.time,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
aria-label="Select keyframe"
|
aria-label="Select keyframe"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import {
|
|||||||
} from "react";
|
} from "react";
|
||||||
import { useEditor } from "@/hooks/use-editor";
|
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, getSnappedSeekTime } from "@/lib/time";
|
||||||
import { timelineTimeToSnappedPixels } from "@/lib/timeline";
|
import { timelineTimeToSnappedPixels } from "@/lib/timeline";
|
||||||
import {
|
import {
|
||||||
DRAG_THRESHOLD_PX,
|
DRAG_THRESHOLD_PX,
|
||||||
@@ -18,7 +18,6 @@ import { BatchCommand } from "@/lib/commands";
|
|||||||
import type { SelectedKeyframeRef } from "@/types/animation";
|
import type { SelectedKeyframeRef } from "@/types/animation";
|
||||||
import type { TimelineElement } from "@/types/timeline";
|
import type { TimelineElement } from "@/types/timeline";
|
||||||
import type { Command } from "@/lib/commands/base-command";
|
import type { Command } from "@/lib/commands/base-command";
|
||||||
|
|
||||||
export interface KeyframeDragState {
|
export interface KeyframeDragState {
|
||||||
isDragging: boolean;
|
isDragging: boolean;
|
||||||
draggingKeyframeIds: Set<string>;
|
draggingKeyframeIds: Set<string>;
|
||||||
@@ -39,9 +38,11 @@ interface PendingKeyframeDrag {
|
|||||||
export function useKeyframeDrag({
|
export function useKeyframeDrag({
|
||||||
zoomLevel,
|
zoomLevel,
|
||||||
element,
|
element,
|
||||||
|
displayedStartTime,
|
||||||
}: {
|
}: {
|
||||||
zoomLevel: number;
|
zoomLevel: number;
|
||||||
element: TimelineElement;
|
element: TimelineElement;
|
||||||
|
displayedStartTime: number;
|
||||||
}) {
|
}) {
|
||||||
const editor = useEditor();
|
const editor = useEditor();
|
||||||
const {
|
const {
|
||||||
@@ -222,10 +223,12 @@ export function useKeyframeDrag({
|
|||||||
event,
|
event,
|
||||||
keyframes,
|
keyframes,
|
||||||
orderedKeyframes,
|
orderedKeyframes,
|
||||||
|
indicatorTime,
|
||||||
}: {
|
}: {
|
||||||
event: ReactMouseEvent;
|
event: ReactMouseEvent;
|
||||||
keyframes: SelectedKeyframeRef[];
|
keyframes: SelectedKeyframeRef[];
|
||||||
orderedKeyframes: SelectedKeyframeRef[];
|
orderedKeyframes: SelectedKeyframeRef[];
|
||||||
|
indicatorTime: number;
|
||||||
}) => {
|
}) => {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
||||||
@@ -234,23 +237,31 @@ export function useKeyframeDrag({
|
|||||||
Math.abs(event.clientX - mouseDownXRef.current) > DRAG_THRESHOLD_PX;
|
Math.abs(event.clientX - mouseDownXRef.current) > DRAG_THRESHOLD_PX;
|
||||||
mouseDownXRef.current = null;
|
mouseDownXRef.current = null;
|
||||||
|
|
||||||
if (wasDrag) return;
|
if (wasDrag) return;
|
||||||
|
|
||||||
if (event.shiftKey) {
|
const duration = editor.timeline.getTotalDuration();
|
||||||
selectKeyframeRange({
|
const seekTime = getSnappedSeekTime({
|
||||||
orderedKeyframes,
|
rawTime: displayedStartTime + indicatorTime,
|
||||||
targetKeyframes: keyframes,
|
duration,
|
||||||
isAdditive: event.metaKey || event.ctrlKey,
|
fps,
|
||||||
});
|
});
|
||||||
return;
|
editor.playback.seek({ time: seekTime });
|
||||||
}
|
|
||||||
|
|
||||||
toggleKeyframeSelection({
|
if (event.shiftKey) {
|
||||||
keyframes,
|
selectKeyframeRange({
|
||||||
isMultiKey: event.metaKey || event.ctrlKey,
|
orderedKeyframes,
|
||||||
});
|
targetKeyframes: keyframes,
|
||||||
|
isAdditive: event.metaKey || event.ctrlKey,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleKeyframeSelection({
|
||||||
|
keyframes,
|
||||||
|
isMultiKey: event.metaKey || event.ctrlKey,
|
||||||
|
});
|
||||||
},
|
},
|
||||||
[toggleKeyframeSelection, selectKeyframeRange],
|
[toggleKeyframeSelection, selectKeyframeRange, editor, displayedStartTime, fps],
|
||||||
);
|
);
|
||||||
|
|
||||||
const getVisualOffsetPx = useCallback(
|
const getVisualOffsetPx = useCallback(
|
||||||
|
|||||||
Reference in New Issue
Block a user