summaryrefslogtreecommitdiff
path: root/apps/web/src/lib/commands/timeline/element/update-element-duration.ts
diff options
context:
space:
mode:
authorMaze Winther <mazewinther@gmail.com>2026-02-27 16:33:57 +0100
committerMaze Winther <mazewinther@gmail.com>2026-02-27 16:33:57 +0100
commit49426f19cd8eaed7cf6c47999b66fee7ee637a56 (patch)
tree1b37451529cfcb36e6cae79494c61b9c616077df /apps/web/src/lib/commands/timeline/element/update-element-duration.ts
parent9b94f89def4f96836c4f42a23a73e97fe647a43c (diff)
downloadopencut-49426f19cd8eaed7cf6c47999b66fee7ee637a56.tar.gz
feat: implement keyframe animation system
Add keyframe support for transform, opacity, and volume properties. Includes animation engine (interpolation, mutations, resolvers), timeline markers with selection/snapping, properties panel toggles, keyframe-aware renderer, and full undo/redo command support. Also refactor element command constructors to object params, extract timeline pixel math to pixel-utils.ts, and update cursor rules.
Diffstat (limited to 'apps/web/src/lib/commands/timeline/element/update-element-duration.ts')
-rw-r--r--apps/web/src/lib/commands/timeline/element/update-element-duration.ts40
1 files changed, 30 insertions, 10 deletions
diff --git a/apps/web/src/lib/commands/timeline/element/update-element-duration.ts b/apps/web/src/lib/commands/timeline/element/update-element-duration.ts
index 6b3a860b..3366548d 100644
--- a/apps/web/src/lib/commands/timeline/element/update-element-duration.ts
+++ b/apps/web/src/lib/commands/timeline/element/update-element-duration.ts
@@ -1,28 +1,48 @@
import { Command } from "@/lib/commands/base-command";
import type { TimelineTrack } from "@/types/timeline";
import { EditorCore } from "@/core";
+import { clampAnimationsToDuration } from "@/lib/animation";
export class UpdateElementDurationCommand extends Command {
private savedState: TimelineTrack[] | null = null;
+ private readonly trackId: string;
+ private readonly elementId: string;
+ private readonly duration: number;
- constructor(
- private trackId: string,
- private elementId: string,
- private duration: number,
- ) {
+ constructor({
+ trackId,
+ elementId,
+ duration,
+ }: {
+ trackId: string;
+ elementId: string;
+ duration: number;
+ }) {
super();
+ this.trackId = trackId;
+ this.elementId = elementId;
+ this.duration = duration;
}
execute(): void {
const editor = EditorCore.getInstance();
this.savedState = editor.timeline.getTracks();
- const updatedTracks = this.savedState.map((t) => {
- if (t.id !== this.trackId) return t;
- const newElements = t.elements.map((el) =>
- el.id === this.elementId ? { ...el, duration: this.duration } : el,
+ const updatedTracks = this.savedState.map((track) => {
+ if (track.id !== this.trackId) return track;
+ const newElements = track.elements.map((element) =>
+ element.id === this.elementId
+ ? {
+ ...element,
+ duration: this.duration,
+ animations: clampAnimationsToDuration({
+ animations: element.animations,
+ duration: this.duration,
+ }),
+ }
+ : element,
);
- return { ...t, elements: newElements } as typeof t;
+ return { ...track, elements: newElements } as typeof track;
});
editor.timeline.updateTracks(updatedTracks);