summaryrefslogtreecommitdiff
path: root/apps/web/src/timeline/controllers/keyframe-drag-controller.ts
diff options
context:
space:
mode:
Diffstat (limited to 'apps/web/src/timeline/controllers/keyframe-drag-controller.ts')
-rw-r--r--apps/web/src/timeline/controllers/keyframe-drag-controller.ts69
1 files changed, 42 insertions, 27 deletions
diff --git a/apps/web/src/timeline/controllers/keyframe-drag-controller.ts b/apps/web/src/timeline/controllers/keyframe-drag-controller.ts
index 51c60dee..e3a9cd96 100644
--- a/apps/web/src/timeline/controllers/keyframe-drag-controller.ts
+++ b/apps/web/src/timeline/controllers/keyframe-drag-controller.ts
@@ -1,7 +1,16 @@
import type { MouseEvent as ReactMouseEvent } from "react";
-import { roundToFrame, snappedSeekTime, type FrameRate } from "opencut-wasm";
+import type { FrameRate } from "opencut-wasm";
import { BASE_TIMELINE_PIXELS_PER_SECOND } from "@/timeline/scale";
-import { TICKS_PER_SECOND } from "@/wasm";
+import {
+ addMediaTime,
+ clampMediaTime,
+ type MediaTime,
+ mediaTime,
+ roundFrameTicks,
+ snapSeekMediaTime,
+ TICKS_PER_SECOND,
+ ZERO_MEDIA_TIME,
+} from "@/wasm";
import { TIMELINE_DRAG_THRESHOLD_PX } from "@/timeline/components/interaction";
import { timelineTimeToSnappedPixels } from "@/timeline";
import { getKeyframeById } from "@/animation";
@@ -48,7 +57,7 @@ export interface KeyframeDragConfig {
zoomLevel: number;
getFps: () => FrameRate | null;
element: TimelineElement;
- displayedStartTime: number;
+ displayedStartTime: MediaTime;
selectedKeyframes: SelectedKeyframeRef[];
isKeyframeSelected: (args: { keyframe: SelectedKeyframeRef }) => boolean;
setKeyframeSelection: (args: { keyframes: SelectedKeyframeRef[] }) => void;
@@ -62,8 +71,8 @@ export interface KeyframeDragConfig {
isAdditive: boolean;
}) => void;
executeCommand: (command: Command) => void;
- seek: (args: { time: number }) => void;
- getTotalDuration: () => number;
+ seek: (args: { time: MediaTime }) => void;
+ getTotalDuration: () => MediaTime;
}
export interface KeyframeDragConfigRef {
@@ -161,7 +170,7 @@ export class KeyframeDragController {
event: ReactMouseEvent;
keyframes: SelectedKeyframeRef[];
orderedKeyframes: SelectedKeyframeRef[];
- indicatorTime: number;
+ indicatorTime: MediaTime;
}): void {
event.stopPropagation();
@@ -174,14 +183,18 @@ export class KeyframeDragController {
const { displayedStartTime, getFps, getTotalDuration, seek } = this.config;
const fps = getFps();
+ const absoluteIndicatorTime = addMediaTime({
+ a: displayedStartTime,
+ b: indicatorTime,
+ });
const seekTime =
fps != null
- ? (snappedSeekTime({
- time: displayedStartTime + indicatorTime,
+ ? snapSeekMediaTime({
+ time: absoluteIndicatorTime,
duration: getTotalDuration(),
- rate: fps,
- }) ?? displayedStartTime + indicatorTime)
- : displayedStartTime + indicatorTime;
+ fps,
+ })
+ : absoluteIndicatorTime;
seek({ time: seekTime });
if (event.shiftKey) {
@@ -206,24 +219,23 @@ export class KeyframeDragController {
displayedStartTime,
elementLeft,
}: {
- indicatorTime: number;
+ indicatorTime: MediaTime;
indicatorOffsetPx: number;
isBeingDragged: boolean;
- displayedStartTime: number;
+ displayedStartTime: MediaTime;
elementLeft: number;
}): number {
if (!isBeingDragged || this.session.kind !== "active")
return indicatorOffsetPx;
- const clampedTime = Math.max(
- 0,
- Math.min(
- this.config.element.duration,
- indicatorTime + this.session.deltaTicks,
- ),
- );
+ const deltaTime = mediaTime({ ticks: this.session.deltaTicks });
+ const clampedTime = clampMediaTime({
+ time: addMediaTime({ a: indicatorTime, b: deltaTime }),
+ min: ZERO_MEDIA_TIME,
+ max: this.config.element.duration,
+ });
return (
timelineTimeToSnappedPixels({
- time: displayedStartTime + clampedTime,
+ time: addMediaTime({ a: displayedStartTime, b: clampedTime }),
zoomLevel: this.config.zoomLevel,
}) - elementLeft
);
@@ -270,10 +282,14 @@ export class KeyframeDragController {
elementId: ref.elementId,
propertyPath: ref.propertyPath,
keyframeId: ref.keyframeId,
- nextTime: Math.max(
- 0,
- Math.min(element.duration, keyframe.time + deltaTicks),
- ),
+ nextTime: clampMediaTime({
+ time: addMediaTime({
+ a: keyframe.time,
+ b: mediaTime({ ticks: deltaTicks }),
+ }),
+ min: ZERO_MEDIA_TIME,
+ max: element.duration,
+ }),
}),
];
});
@@ -313,8 +329,7 @@ export class KeyframeDragController {
((clientX - this.session.startMouseX) / pixelsPerSecond) *
TICKS_PER_SECOND,
);
- this.session.deltaTicks =
- roundToFrame({ time: rawDeltaTicks, rate: fps }) ?? rawDeltaTicks;
+ this.session.deltaTicks = roundFrameTicks({ ticks: rawDeltaTicks, fps });
this.notify();
}