diff options
Diffstat (limited to 'apps/web/src/clipboard')
| -rw-r--r-- | apps/web/src/clipboard/handlers/elements.ts | 2 | ||||
| -rw-r--r-- | apps/web/src/clipboard/handlers/index.ts | 2 | ||||
| -rw-r--r-- | apps/web/src/clipboard/handlers/keyframes.ts | 24 | ||||
| -rw-r--r-- | apps/web/src/clipboard/types.ts | 17 |
4 files changed, 26 insertions, 19 deletions
diff --git a/apps/web/src/clipboard/handlers/elements.ts b/apps/web/src/clipboard/handlers/elements.ts index b2f5f2c3..2297b493 100644 --- a/apps/web/src/clipboard/handlers/elements.ts +++ b/apps/web/src/clipboard/handlers/elements.ts @@ -35,7 +35,7 @@ export const ElementsClipboardHandler = { }; }, - paste(entry, context) { + paste({ entry, context }) { if (entry.items.length === 0) { return null; } diff --git a/apps/web/src/clipboard/handlers/index.ts b/apps/web/src/clipboard/handlers/index.ts index 29d4d1d0..a042c3dd 100644 --- a/apps/web/src/clipboard/handlers/index.ts +++ b/apps/web/src/clipboard/handlers/index.ts @@ -45,5 +45,5 @@ export function buildPasteClipboardCommand({ const handler = clipboardHandlers[entry.type] as ClipboardHandler< typeof entry.type >; - return handler.paste(entry as never, context); + return handler.paste({ entry: entry as never, context }); } diff --git a/apps/web/src/clipboard/handlers/keyframes.ts b/apps/web/src/clipboard/handlers/keyframes.ts index ad156e12..dde8384f 100644 --- a/apps/web/src/clipboard/handlers/keyframes.ts +++ b/apps/web/src/clipboard/handlers/keyframes.ts @@ -1,4 +1,6 @@ import { getKeyframeById } from "@/animation"; +import { getChannelEntriesFromData } from "@/animation/channel-data"; +import { isScalarChannel } from "@/animation/interpolation"; import type { SelectedKeyframeRef } from "@/animation/types"; import type { TimelineElement } from "@/timeline"; import { PasteKeyframesCommand } from "@/commands/timeline"; @@ -7,6 +9,7 @@ import type { KeyframeClipboardCurvePatch, KeyframeClipboardItem, } from "../types"; +import { roundMediaTime, subMediaTime, type MediaTime } from "@/wasm"; function resolveSingleSourceElement({ selectedKeyframes, @@ -40,14 +43,13 @@ function getCurvePatches({ propertyPath: KeyframeClipboardItem["propertyPath"]; keyframeId: string; }): KeyframeClipboardCurvePatch[] { - const binding = element.animations?.bindings[propertyPath]; - if (!binding) { + const data = element.animations?.[propertyPath]; + if (!data) { return []; } - return binding.components.flatMap((component) => { - const channel = element.animations?.channels[component.channelId]; - if (channel?.kind !== "scalar") { + return getChannelEntriesFromData({ data }).flatMap(([componentKey, channel]) => { + if (!channel || !isScalarChannel(channel)) { return []; } @@ -60,7 +62,7 @@ function getCurvePatches({ return [ { - componentKey: component.key, + componentKey, patch: { leftHandle: keyframe.leftHandle ?? null, rightHandle: keyframe.rightHandle ?? null, @@ -80,7 +82,7 @@ function buildClipboardItem({ element: TimelineElement; propertyPath: KeyframeClipboardItem["propertyPath"]; keyframeId: string; -}): (Omit<KeyframeClipboardItem, "timeOffset"> & { time: number }) | null { +}): (Omit<KeyframeClipboardItem, "timeOffset"> & { time: MediaTime }) | null { const keyframe = getKeyframeById({ animations: element.animations, propertyPath, @@ -136,10 +138,11 @@ export const KeyframesClipboardHandler = { } const minTime = Math.min(...rawItems.map((item) => item.time)); + const minTimeMedia = roundMediaTime({ time: minTime }); const items = rawItems .map(({ time, ...item }) => ({ ...item, - timeOffset: time - minTime, + timeOffset: subMediaTime({ a: time, b: minTimeMedia }), })) .sort( (left, right) => @@ -154,7 +157,10 @@ export const KeyframesClipboardHandler = { }; }, - paste(entry, { selectedElements, time }) { + paste({ + entry, + context: { selectedElements, time }, + }) { const targetElement = selectedElements[0]; if (!targetElement || entry.items.length === 0) { return null; diff --git a/apps/web/src/clipboard/types.ts b/apps/web/src/clipboard/types.ts index 0d249c9d..24ca9105 100644 --- a/apps/web/src/clipboard/types.ts +++ b/apps/web/src/clipboard/types.ts @@ -2,16 +2,17 @@ import type { EditorCore } from "@/core"; import type { AnimationInterpolation, AnimationPath, - AnimationValue, ScalarCurveKeyframePatch, SelectedKeyframeRef, } from "@/animation/types"; +import type { ParamValue } from "@/params"; import type { Command } from "@/commands/base-command"; import type { CreateTimelineElement, ElementRef, TrackType, } from "@/timeline"; +import type { MediaTime } from "@/wasm"; export interface ElementClipboardItem { trackId: string; @@ -26,8 +27,8 @@ export interface KeyframeClipboardCurvePatch { export interface KeyframeClipboardItem { propertyPath: AnimationPath; - timeOffset: number; - value: AnimationValue; + timeOffset: MediaTime; + value: ParamValue; interpolation: AnimationInterpolation; curvePatches: KeyframeClipboardCurvePatch[]; } @@ -61,17 +62,17 @@ export interface PasteContext { editor: EditorCore; selectedElements: ElementRef[]; selectedKeyframes: SelectedKeyframeRef[]; - time: number; + time: MediaTime; } export interface ClipboardHandler<TType extends ClipboardEntryType> { type: TType; canCopy(context: CopyContext): boolean; copy(context: CopyContext): ClipboardEntryByType[TType] | null; - paste( - entry: ClipboardEntryByType[TType], - context: PasteContext, - ): Command | null; + paste(args: { + entry: ClipboardEntryByType[TType]; + context: PasteContext; + }): Command | null; } export type ClipboardHandlerMap = { |
