diff options
Diffstat (limited to 'apps/web/src/timeline/controllers/keyframe-drag-controller.ts')
| -rw-r--r-- | apps/web/src/timeline/controllers/keyframe-drag-controller.ts | 69 |
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(); } |
