summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorMaze Winther <mazewinther@gmail.com>2026-03-02 16:40:41 +0100
committerMaze Winther <mazewinther@gmail.com>2026-03-02 16:40:41 +0100
commit565d2595da3ab23c39b5cd5fdcacdf676ca0e572 (patch)
tree1bdef90e11a32d985c34ab4e781a7fdeb2b37d86 /apps
parenta526066b61f18b082adf6faeaf3e19f3d13cd77d (diff)
downloadopencut-565d2595da3ab23c39b5cd5fdcacdf676ca0e572.tar.gz
clcik to seek on keyframes
Diffstat (limited to 'apps')
-rw-r--r--apps/web/src/components/editor/panels/timeline/timeline-element.tsx16
-rw-r--r--apps/web/src/hooks/timeline/element/use-keyframe-drag.ts41
2 files changed, 35 insertions, 22 deletions
diff --git a/apps/web/src/components/editor/panels/timeline/timeline-element.tsx b/apps/web/src/components/editor/panels/timeline/timeline-element.tsx
index f4258aa0..3ce2cd14 100644
--- a/apps/web/src/components/editor/panels/timeline/timeline-element.tsx
+++ b/apps/web/src/components/editor/panels/timeline/timeline-element.tsx
@@ -259,7 +259,7 @@ export function TimelineElement({
handleKeyframeMouseDown,
handleKeyframeClick,
getVisualOffsetPx,
- } = useKeyframeDrag({ zoomLevel, element });
+ } = useKeyframeDrag({ zoomLevel, element, displayedStartTime });
const handleRevealInMedia = ({ event }: { event: React.MouseEvent }) => {
event.stopPropagation();
if (hasMediaId(element)) {
@@ -516,6 +516,7 @@ function KeyframeIndicators({
event: React.MouseEvent;
keyframes: SelectedKeyframeRef[];
orderedKeyframes: SelectedKeyframeRef[];
+ indicatorTime: number;
}) => void;
getVisualOffsetPx: (params: {
indicatorTime: number;
@@ -554,12 +555,13 @@ function KeyframeIndicators({
onMouseDown={(event) =>
onKeyframeMouseDown({ event, keyframes: indicator.keyframes })
}
- onClick={(event) =>
- onKeyframeClick({
- event,
- keyframes: indicator.keyframes,
- orderedKeyframes,
- })
+ onClick={(event) =>
+ onKeyframeClick({
+ event,
+ keyframes: indicator.keyframes,
+ orderedKeyframes,
+ indicatorTime: indicator.time,
+ })
}
aria-label="Select keyframe"
>
diff --git a/apps/web/src/hooks/timeline/element/use-keyframe-drag.ts b/apps/web/src/hooks/timeline/element/use-keyframe-drag.ts
index 2dd7cb3e..b18db6eb 100644
--- a/apps/web/src/hooks/timeline/element/use-keyframe-drag.ts
+++ b/apps/web/src/hooks/timeline/element/use-keyframe-drag.ts
@@ -7,7 +7,7 @@ import {
} from "react";
import { useEditor } from "@/hooks/use-editor";
import { useKeyframeSelection } from "./use-keyframe-selection";
-import { snapTimeToFrame } from "@/lib/time";
+import { snapTimeToFrame, getSnappedSeekTime } from "@/lib/time";
import { timelineTimeToSnappedPixels } from "@/lib/timeline";
import {
DRAG_THRESHOLD_PX,
@@ -18,7 +18,6 @@ import { BatchCommand } from "@/lib/commands";
import type { SelectedKeyframeRef } from "@/types/animation";
import type { TimelineElement } from "@/types/timeline";
import type { Command } from "@/lib/commands/base-command";
-
export interface KeyframeDragState {
isDragging: boolean;
draggingKeyframeIds: Set<string>;
@@ -39,9 +38,11 @@ interface PendingKeyframeDrag {
export function useKeyframeDrag({
zoomLevel,
element,
+ displayedStartTime,
}: {
zoomLevel: number;
element: TimelineElement;
+ displayedStartTime: number;
}) {
const editor = useEditor();
const {
@@ -222,10 +223,12 @@ export function useKeyframeDrag({
event,
keyframes,
orderedKeyframes,
+ indicatorTime,
}: {
event: ReactMouseEvent;
keyframes: SelectedKeyframeRef[];
orderedKeyframes: SelectedKeyframeRef[];
+ indicatorTime: number;
}) => {
event.stopPropagation();
@@ -234,23 +237,31 @@ export function useKeyframeDrag({
Math.abs(event.clientX - mouseDownXRef.current) > DRAG_THRESHOLD_PX;
mouseDownXRef.current = null;
- if (wasDrag) return;
+ if (wasDrag) return;
- if (event.shiftKey) {
- selectKeyframeRange({
- orderedKeyframes,
- targetKeyframes: keyframes,
- isAdditive: event.metaKey || event.ctrlKey,
+ const duration = editor.timeline.getTotalDuration();
+ const seekTime = getSnappedSeekTime({
+ rawTime: displayedStartTime + indicatorTime,
+ duration,
+ fps,
});
- return;
- }
+ editor.playback.seek({ time: seekTime });
- toggleKeyframeSelection({
- keyframes,
- isMultiKey: event.metaKey || event.ctrlKey,
- });
+ if (event.shiftKey) {
+ selectKeyframeRange({
+ 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(