@aura3d/editor-runtime 1.0.6 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/dist/AnimationSceneEditor.d.ts +111 -0
  2. package/dist/AnimationSceneEditor.d.ts.map +1 -0
  3. package/dist/AnimationSceneEditor.js +285 -0
  4. package/dist/AnimationSceneEditor.js.map +1 -0
  5. package/dist/AssetDropZone.d.ts +52 -0
  6. package/dist/AssetDropZone.d.ts.map +1 -0
  7. package/dist/AssetDropZone.js +115 -0
  8. package/dist/AssetDropZone.js.map +1 -0
  9. package/dist/CameraPathEditor.d.ts +48 -0
  10. package/dist/CameraPathEditor.d.ts.map +1 -0
  11. package/dist/CameraPathEditor.js +181 -0
  12. package/dist/CameraPathEditor.js.map +1 -0
  13. package/dist/CartoonSceneEditor.d.ts +111 -0
  14. package/dist/CartoonSceneEditor.d.ts.map +1 -0
  15. package/dist/CartoonSceneEditor.js +285 -0
  16. package/dist/CartoonSceneEditor.js.map +1 -0
  17. package/dist/CurveEditor.d.ts +38 -0
  18. package/dist/CurveEditor.d.ts.map +1 -0
  19. package/dist/CurveEditor.js +112 -0
  20. package/dist/CurveEditor.js.map +1 -0
  21. package/dist/EpisodeReviewPanel.d.ts +67 -0
  22. package/dist/EpisodeReviewPanel.d.ts.map +1 -0
  23. package/dist/EpisodeReviewPanel.js +162 -0
  24. package/dist/EpisodeReviewPanel.js.map +1 -0
  25. package/dist/EventTrackEditor.d.ts +54 -0
  26. package/dist/EventTrackEditor.d.ts.map +1 -0
  27. package/dist/EventTrackEditor.js +124 -0
  28. package/dist/EventTrackEditor.js.map +1 -0
  29. package/dist/KeyframeEditor.d.ts +49 -0
  30. package/dist/KeyframeEditor.d.ts.map +1 -0
  31. package/dist/KeyframeEditor.js +161 -0
  32. package/dist/KeyframeEditor.js.map +1 -0
  33. package/dist/MultiUserReviewWorkflow.d.ts +77 -0
  34. package/dist/MultiUserReviewWorkflow.d.ts.map +1 -0
  35. package/dist/MultiUserReviewWorkflow.js +162 -0
  36. package/dist/MultiUserReviewWorkflow.js.map +1 -0
  37. package/dist/NonlinearAnimationEditor.d.ts +81 -0
  38. package/dist/NonlinearAnimationEditor.d.ts.map +1 -0
  39. package/dist/NonlinearAnimationEditor.js +180 -0
  40. package/dist/NonlinearAnimationEditor.js.map +1 -0
  41. package/dist/PropertyPanel.d.ts +21 -0
  42. package/dist/PropertyPanel.d.ts.map +1 -0
  43. package/dist/PropertyPanel.js +72 -0
  44. package/dist/PropertyPanel.js.map +1 -0
  45. package/dist/RenderQueuePanel.d.ts +38 -0
  46. package/dist/RenderQueuePanel.d.ts.map +1 -0
  47. package/dist/RenderQueuePanel.js +72 -0
  48. package/dist/RenderQueuePanel.js.map +1 -0
  49. package/dist/SceneOutliner.d.ts +19 -0
  50. package/dist/SceneOutliner.d.ts.map +1 -0
  51. package/dist/SceneOutliner.js +64 -0
  52. package/dist/SceneOutliner.js.map +1 -0
  53. package/dist/TimelineEditorController.d.ts +102 -0
  54. package/dist/TimelineEditorController.d.ts.map +1 -0
  55. package/dist/TimelineEditorController.js +449 -0
  56. package/dist/TimelineEditorController.js.map +1 -0
  57. package/dist/TimelineTrackTypes.d.ts +25 -0
  58. package/dist/TimelineTrackTypes.d.ts.map +1 -0
  59. package/dist/TimelineTrackTypes.js +48 -0
  60. package/dist/TimelineTrackTypes.js.map +1 -0
  61. package/dist/TimelineUI.d.ts +27 -0
  62. package/dist/TimelineUI.d.ts.map +1 -0
  63. package/dist/TimelineUI.js +123 -0
  64. package/dist/TimelineUI.js.map +1 -0
  65. package/dist/VisualReviewDashboard.d.ts +43 -0
  66. package/dist/VisualReviewDashboard.d.ts.map +1 -0
  67. package/dist/VisualReviewDashboard.js +47 -0
  68. package/dist/VisualReviewDashboard.js.map +1 -0
  69. package/dist/index.d.ts +32 -0
  70. package/dist/index.d.ts.map +1 -1
  71. package/dist/index.js +16 -0
  72. package/dist/index.js.map +1 -1
  73. package/package.json +5 -4
  74. package/src/AnimationSceneEditor.ts +368 -0
  75. package/src/AssetDropZone.ts +144 -0
  76. package/src/CameraPathEditor.ts +223 -0
  77. package/src/CurveEditor.ts +152 -0
  78. package/src/EpisodeReviewPanel.ts +236 -0
  79. package/src/EventTrackEditor.ts +169 -0
  80. package/src/KeyframeEditor.ts +214 -0
  81. package/src/MultiUserReviewWorkflow.ts +229 -0
  82. package/src/NonlinearAnimationEditor.ts +262 -0
  83. package/src/PropertyPanel.ts +82 -0
  84. package/src/RenderQueuePanel.ts +106 -0
  85. package/src/SceneOutliner.ts +78 -0
  86. package/src/TimelineEditorController.ts +525 -0
  87. package/src/TimelineTrackTypes.ts +89 -0
  88. package/src/TimelineUI.ts +153 -0
  89. package/src/VisualReviewDashboard.ts +87 -0
  90. package/src/index.ts +55 -0
  91. package/tests/editor-runtime.test.ts +490 -0
@@ -0,0 +1,112 @@
1
+ import { CommandHistory } from "./CommandHistory.js";
2
+ import { KeyframeEditor, readTimelineKeyframes } from "./KeyframeEditor.js";
3
+ export class CurveEditor {
4
+ keyframes;
5
+ constructor(history = new CommandHistory()) {
6
+ this.keyframes = new KeyframeEditor(history);
7
+ }
8
+ get commandHistory() {
9
+ return this.keyframes.commandHistory;
10
+ }
11
+ sample(clip, propertyPath, time) {
12
+ assertFinite(time, "Curve sample time");
13
+ const keyframes = propertyKeyframes(clip, propertyPath);
14
+ if (keyframes.length === 0) {
15
+ return { propertyPath, time, value: undefined };
16
+ }
17
+ if (time <= keyframes[0].time) {
18
+ return { propertyPath, time, value: keyframes[0].value, segmentStartId: keyframes[0].id };
19
+ }
20
+ const last = keyframes[keyframes.length - 1];
21
+ if (time >= last.time) {
22
+ return { propertyPath, time, value: last.value, segmentStartId: last.id };
23
+ }
24
+ const endIndex = keyframes.findIndex((keyframe) => keyframe.time >= time);
25
+ const start = keyframes[endIndex - 1];
26
+ const end = keyframes[endIndex];
27
+ if (!start || !end) {
28
+ return { propertyPath, time, value: last.value, segmentStartId: last.id };
29
+ }
30
+ return {
31
+ propertyPath,
32
+ time,
33
+ value: sampleSegment(start, end, time),
34
+ segmentStartId: start.id,
35
+ segmentEndId: end.id
36
+ };
37
+ }
38
+ samplePoints(clip, propertyPath, startTime, endTime, steps) {
39
+ assertFinite(startTime, "Curve startTime");
40
+ assertFinite(endTime, "Curve endTime");
41
+ if (endTime < startTime)
42
+ throw new RangeError("Curve endTime must be greater than or equal to startTime.");
43
+ if (!Number.isInteger(steps) || steps < 1)
44
+ throw new RangeError("Curve sample steps must be a positive integer.");
45
+ const points = [];
46
+ for (let index = 0; index <= steps; index += 1) {
47
+ const time = startTime + (endTime - startTime) * (index / steps);
48
+ const value = this.sample(clip, propertyPath, time).value;
49
+ if (typeof value === "number") {
50
+ points.push({ time: Number(time.toFixed(4)), value: Number(value.toFixed(4)) });
51
+ }
52
+ }
53
+ return points;
54
+ }
55
+ async setBezierHandles(clip, keyframeId, handles) {
56
+ const keyframes = readTimelineKeyframes(clip);
57
+ const target = keyframes.find((keyframe) => keyframe.id === keyframeId);
58
+ if (!target)
59
+ throw new Error(`Timeline keyframe does not exist: ${keyframeId}`);
60
+ const updated = {
61
+ ...target,
62
+ interpolation: "bezier",
63
+ inHandle: handles.inHandle,
64
+ outHandle: handles.outHandle
65
+ };
66
+ await this.keyframes.replaceKeyframes(clip, keyframes.map((keyframe) => keyframe.id === keyframeId ? updated : keyframe), `Set bezier handles ${keyframeId}`);
67
+ return updated;
68
+ }
69
+ evidence(clip, propertyPath, sampleCount = 8) {
70
+ const keyframes = propertyKeyframes(clip, propertyPath);
71
+ const startTime = keyframes[0]?.time ?? 0;
72
+ const endTime = keyframes[keyframes.length - 1]?.time ?? startTime;
73
+ return {
74
+ propertyPath,
75
+ keyframeCount: keyframes.length,
76
+ bezierSegmentCount: keyframes.filter((keyframe) => keyframe.interpolation === "bezier").length,
77
+ sampledPointCount: this.samplePoints(clip, propertyPath, startTime, endTime, Math.max(1, sampleCount)).length,
78
+ evidence: {
79
+ deterministicSampling: true,
80
+ bezierHandles: keyframes.some((keyframe) => keyframe.inHandle || keyframe.outHandle),
81
+ holdInterpolation: keyframes.some((keyframe) => keyframe.interpolation === "hold")
82
+ }
83
+ };
84
+ }
85
+ }
86
+ function propertyKeyframes(clip, propertyPath) {
87
+ return readTimelineKeyframes(clip).filter((keyframe) => keyframe.propertyPath === propertyPath);
88
+ }
89
+ function sampleSegment(start, end, time) {
90
+ if (start.interpolation === "hold" || typeof start.value !== "number" || typeof end.value !== "number") {
91
+ return start.value;
92
+ }
93
+ const duration = end.time - start.time;
94
+ const t = duration <= 0 ? 1 : clamp((time - start.time) / duration, 0, 1);
95
+ if (start.interpolation !== "bezier") {
96
+ return Number((start.value + (end.value - start.value) * t).toFixed(4));
97
+ }
98
+ const p0 = start.value;
99
+ const p1 = start.value + (start.outHandle?.value ?? 0);
100
+ const p2 = end.value + (end.inHandle?.value ?? 0);
101
+ const p3 = end.value;
102
+ const inv = 1 - t;
103
+ return Number((inv * inv * inv * p0 + 3 * inv * inv * t * p1 + 3 * inv * t * t * p2 + t * t * t * p3).toFixed(4));
104
+ }
105
+ function assertFinite(value, label) {
106
+ if (!Number.isFinite(value))
107
+ throw new RangeError(`${label} must be finite.`);
108
+ }
109
+ function clamp(value, min, max) {
110
+ return Math.max(min, Math.min(max, value));
111
+ }
112
+ //# sourceMappingURL=CurveEditor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CurveEditor.js","sourceRoot":"","sources":["../../../../packages/editor-runtime/src/CurveEditor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ export type EpisodeReviewStatus = "draft" | "needs-review" | "approved" | "rejected";
2
+ export interface EpisodeReviewRejectedFrame {
3
+ readonly id: string;
4
+ readonly time: number;
5
+ readonly reason: string;
6
+ }
7
+ export interface EpisodeReviewNote {
8
+ readonly id: string;
9
+ readonly author: string;
10
+ readonly text: string;
11
+ readonly time?: number;
12
+ }
13
+ export interface EpisodeReviewWaveformLane {
14
+ readonly id: string;
15
+ readonly label: string;
16
+ readonly startTime: number;
17
+ readonly duration: number;
18
+ readonly peakCount: number;
19
+ readonly pathPointCount: number;
20
+ }
21
+ export interface EpisodeReviewManualVisemeEdit {
22
+ readonly id: string;
23
+ readonly characterId: string;
24
+ readonly visemeId: string;
25
+ readonly startTime: number;
26
+ readonly endTime: number;
27
+ readonly reason?: string;
28
+ }
29
+ export interface EpisodeReviewPanelState {
30
+ readonly packageId: string;
31
+ readonly packageHash?: string;
32
+ readonly status: EpisodeReviewStatus;
33
+ readonly reviewer?: string;
34
+ readonly approvedAt?: string;
35
+ readonly notes: readonly EpisodeReviewNote[];
36
+ readonly rejectedFrames: readonly EpisodeReviewRejectedFrame[];
37
+ readonly waveformLanes?: readonly EpisodeReviewWaveformLane[];
38
+ readonly manualVisemeEdits?: readonly EpisodeReviewManualVisemeEdit[];
39
+ }
40
+ export interface EpisodeReviewPanelSnapshot extends EpisodeReviewPanelState {
41
+ readonly kind: "episode-review-panel";
42
+ readonly approvalRecorded: boolean;
43
+ readonly rejectedFrameCount: number;
44
+ readonly noteCount: number;
45
+ readonly waveformLaneCount: number;
46
+ readonly manualVisemeEditCount: number;
47
+ readonly reviewUiEvidence: {
48
+ readonly waveformReview: boolean;
49
+ readonly manualVisemeEdits: boolean;
50
+ readonly visualFrameReview: boolean;
51
+ readonly reviewerNotes: boolean;
52
+ };
53
+ }
54
+ export declare class EpisodeReviewPanel {
55
+ private state;
56
+ constructor(state: EpisodeReviewPanelState);
57
+ addNote(note: EpisodeReviewNote): EpisodeReviewPanelSnapshot;
58
+ rejectFrame(frame: EpisodeReviewRejectedFrame): EpisodeReviewPanelSnapshot;
59
+ setWaveformLanes(waveformLanes: readonly EpisodeReviewWaveformLane[]): EpisodeReviewPanelSnapshot;
60
+ applyManualVisemeEdit(edit: EpisodeReviewManualVisemeEdit): EpisodeReviewPanelSnapshot;
61
+ approve(reviewer: string, approvedAt?: string): EpisodeReviewPanelSnapshot;
62
+ markNeedsReview(): EpisodeReviewPanelSnapshot;
63
+ serialize(): EpisodeReviewPanelState;
64
+ snapshot(): EpisodeReviewPanelSnapshot;
65
+ }
66
+ export declare function createEpisodeReviewPanel(state: EpisodeReviewPanelState): EpisodeReviewPanel;
67
+ //# sourceMappingURL=EpisodeReviewPanel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EpisodeReviewPanel.d.ts","sourceRoot":"","sources":["../../../../packages/editor-runtime/src/EpisodeReviewPanel.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,162 @@
1
+ export class EpisodeReviewPanel {
2
+ state;
3
+ constructor(state) {
4
+ this.state = sanitizeReviewState(state);
5
+ }
6
+ addNote(note) {
7
+ this.state = sanitizeReviewState({
8
+ ...this.state,
9
+ notes: [...this.state.notes, sanitizeReviewNote(note)]
10
+ });
11
+ return this.snapshot();
12
+ }
13
+ rejectFrame(frame) {
14
+ this.state = sanitizeReviewState({
15
+ ...this.state,
16
+ status: "rejected",
17
+ rejectedFrames: [...this.state.rejectedFrames, sanitizeRejectedFrame(frame)]
18
+ });
19
+ return this.snapshot();
20
+ }
21
+ setWaveformLanes(waveformLanes) {
22
+ this.state = sanitizeReviewState({
23
+ ...this.state,
24
+ waveformLanes: waveformLanes.map(sanitizeWaveformLane)
25
+ });
26
+ return this.snapshot();
27
+ }
28
+ applyManualVisemeEdit(edit) {
29
+ const sanitized = sanitizeManualVisemeEdit(edit);
30
+ this.state = sanitizeReviewState({
31
+ ...this.state,
32
+ manualVisemeEdits: [
33
+ ...((this.state.manualVisemeEdits ?? []).filter((candidate) => candidate.id !== sanitized.id)),
34
+ sanitized
35
+ ]
36
+ });
37
+ return this.snapshot();
38
+ }
39
+ approve(reviewer, approvedAt = new Date(0).toISOString()) {
40
+ const name = nonEmpty(reviewer, "Episode review reviewer");
41
+ if (this.state.rejectedFrames.length > 0) {
42
+ throw new Error("Episode review cannot be approved while rejected frames are present.");
43
+ }
44
+ this.state = sanitizeReviewState({
45
+ ...this.state,
46
+ status: "approved",
47
+ reviewer: name,
48
+ approvedAt
49
+ });
50
+ return this.snapshot();
51
+ }
52
+ markNeedsReview() {
53
+ this.state = sanitizeReviewState({
54
+ ...this.state,
55
+ status: "needs-review",
56
+ reviewer: undefined,
57
+ approvedAt: undefined
58
+ });
59
+ return this.snapshot();
60
+ }
61
+ serialize() {
62
+ return sanitizeReviewState(this.state);
63
+ }
64
+ snapshot() {
65
+ const waveformLanes = this.state.waveformLanes ?? [];
66
+ const manualVisemeEdits = this.state.manualVisemeEdits ?? [];
67
+ return {
68
+ kind: "episode-review-panel",
69
+ ...this.serialize(),
70
+ approvalRecorded: this.state.status === "approved" && Boolean(this.state.reviewer),
71
+ rejectedFrameCount: this.state.rejectedFrames.length,
72
+ noteCount: this.state.notes.length,
73
+ waveformLaneCount: waveformLanes.length,
74
+ manualVisemeEditCount: manualVisemeEdits.length,
75
+ reviewUiEvidence: {
76
+ waveformReview: waveformLanes.length > 0,
77
+ manualVisemeEdits: manualVisemeEdits.length > 0,
78
+ visualFrameReview: this.state.rejectedFrames.length > 0,
79
+ reviewerNotes: this.state.notes.length > 0
80
+ }
81
+ };
82
+ }
83
+ }
84
+ export function createEpisodeReviewPanel(state) {
85
+ return new EpisodeReviewPanel(state);
86
+ }
87
+ function sanitizeReviewState(state) {
88
+ return {
89
+ packageId: nonEmpty(state.packageId, "Episode review packageId"),
90
+ packageHash: state.packageHash,
91
+ status: state.status,
92
+ reviewer: state.reviewer,
93
+ approvedAt: state.approvedAt,
94
+ notes: state.notes.map(sanitizeReviewNote),
95
+ rejectedFrames: state.rejectedFrames.map(sanitizeRejectedFrame),
96
+ waveformLanes: (state.waveformLanes ?? []).map(sanitizeWaveformLane),
97
+ manualVisemeEdits: (state.manualVisemeEdits ?? []).map(sanitizeManualVisemeEdit)
98
+ };
99
+ }
100
+ function sanitizeReviewNote(note) {
101
+ return {
102
+ id: nonEmpty(note.id, "Episode review note id"),
103
+ author: nonEmpty(note.author, "Episode review note author"),
104
+ text: nonEmpty(note.text, "Episode review note text"),
105
+ time: note.time
106
+ };
107
+ }
108
+ function sanitizeRejectedFrame(frame) {
109
+ if (!Number.isFinite(frame.time) || frame.time < 0) {
110
+ throw new Error("Episode review rejected frame time must be a non-negative finite number.");
111
+ }
112
+ return {
113
+ id: nonEmpty(frame.id, "Episode review rejected frame id"),
114
+ time: frame.time,
115
+ reason: nonEmpty(frame.reason, "Episode review rejected frame reason")
116
+ };
117
+ }
118
+ function sanitizeWaveformLane(lane) {
119
+ if (!Number.isFinite(lane.startTime) || lane.startTime < 0) {
120
+ throw new Error("Episode review waveform lane startTime must be a non-negative finite number.");
121
+ }
122
+ if (!Number.isFinite(lane.duration) || lane.duration < 0) {
123
+ throw new Error("Episode review waveform lane duration must be a non-negative finite number.");
124
+ }
125
+ if (!Number.isInteger(lane.peakCount) || lane.peakCount < 0) {
126
+ throw new Error("Episode review waveform lane peakCount must be a non-negative integer.");
127
+ }
128
+ if (!Number.isInteger(lane.pathPointCount) || lane.pathPointCount < 0) {
129
+ throw new Error("Episode review waveform lane pathPointCount must be a non-negative integer.");
130
+ }
131
+ return {
132
+ id: nonEmpty(lane.id, "Episode review waveform lane id"),
133
+ label: nonEmpty(lane.label, "Episode review waveform lane label"),
134
+ startTime: lane.startTime,
135
+ duration: lane.duration,
136
+ peakCount: lane.peakCount,
137
+ pathPointCount: lane.pathPointCount
138
+ };
139
+ }
140
+ function sanitizeManualVisemeEdit(edit) {
141
+ if (!Number.isFinite(edit.startTime) || edit.startTime < 0) {
142
+ throw new Error("Episode review manual viseme startTime must be a non-negative finite number.");
143
+ }
144
+ if (!Number.isFinite(edit.endTime) || edit.endTime <= edit.startTime) {
145
+ throw new Error("Episode review manual viseme endTime must be greater than startTime.");
146
+ }
147
+ return {
148
+ id: nonEmpty(edit.id, "Episode review manual viseme id"),
149
+ characterId: nonEmpty(edit.characterId, "Episode review manual viseme characterId"),
150
+ visemeId: nonEmpty(edit.visemeId, "Episode review manual viseme visemeId"),
151
+ startTime: edit.startTime,
152
+ endTime: edit.endTime,
153
+ reason: edit.reason
154
+ };
155
+ }
156
+ function nonEmpty(value, label) {
157
+ const trimmed = value.trim();
158
+ if (!trimmed)
159
+ throw new Error(`${label} must be a non-empty string.`);
160
+ return trimmed;
161
+ }
162
+ //# sourceMappingURL=EpisodeReviewPanel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EpisodeReviewPanel.js","sourceRoot":"","sources":["../../../../packages/editor-runtime/src/EpisodeReviewPanel.ts"],"names":[],"mappings":"AA4DA,MAAM,OAAO,kBAAkB;IACrB,KAAK,CAA0B;IAEvC,YAAY,KAA8B;QACxC,IAAI,CAAC,KAAK,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;IAC1C,CAAC;IAED,OAAO,CAAC,IAAuB;QAC7B,IAAI,CAAC,KAAK,GAAG,mBAAmB,CAAC;YAC/B,GAAG,IAAI,CAAC,KAAK;YACb,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,kBAAkB,CAAC,IAAI,CAAC,CAAC;SACvD,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;IACzB,CAAC;IAED,WAAW,CAAC,KAAiC;QAC3C,IAAI,CAAC,KAAK,GAAG,mBAAmB,CAAC;YAC/B,GAAG,IAAI,CAAC,KAAK;YACb,MAAM,EAAE,UAAU;YAClB,cAAc,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE,qBAAqB,CAAC,KAAK,CAAC,CAAC;SAC7E,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;IACzB,CAAC;IAED,gBAAgB,CAAC,aAAmD;QAClE,IAAI,CAAC,KAAK,GAAG,mBAAmB,CAAC;YAC/B,GAAG,IAAI,CAAC,KAAK;YACb,aAAa,EAAE,aAAa,CAAC,GAAG,CAAC,oBAAoB,CAAC;SACvD,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;IACzB,CAAC;IAED,qBAAqB,CAAC,IAAmC;QACvD,MAAM,SAAS,GAAG,wBAAwB,CAAC,IAAI,CAAC,CAAC;QACjD,IAAI,CAAC,KAAK,GAAG,mBAAmB,CAAC;YAC/B,GAAG,IAAI,CAAC,KAAK;YACb,iBAAiB,EAAE;gBACjB,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,KAAK,SAAS,CAAC,EAAE,CAAC,CAAC;gBAC9F,SAAS;aACV;SACF,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;IACzB,CAAC;IAED,OAAO,CAAC,QAAgB,EAAE,UAAU,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE;QAC9D,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,EAAE,yBAAyB,CAAC,CAAC;QAC3D,IAAI,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzC,MAAM,IAAI,KAAK,CAAC,sEAAsE,CAAC,CAAC;QAC1F,CAAC;QACD,IAAI,CAAC,KAAK,GAAG,mBAAmB,CAAC;YAC/B,GAAG,IAAI,CAAC,KAAK;YACb,MAAM,EAAE,UAAU;YAClB,QAAQ,EAAE,IAAI;YACd,UAAU;SACX,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;IACzB,CAAC;IAED,eAAe;QACb,IAAI,CAAC,KAAK,GAAG,mBAAmB,CAAC;YAC/B,GAAG,IAAI,CAAC,KAAK;YACb,MAAM,EAAE,cAAc;YACtB,QAAQ,EAAE,SAAS;YACnB,UAAU,EAAE,SAAS;SACtB,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;IACzB,CAAC;IAED,SAAS;QACP,OAAO,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACzC,CAAC;IAED,QAAQ;QACN,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,IAAI,EAAE,CAAC;QACrD,MAAM,iBAAiB,GAAG,IAAI,CAAC,KAAK,CAAC,iBAAiB,IAAI,EAAE,CAAC;QAC7D,OAAO;YACL,IAAI,EAAE,sBAAsB;YAC5B,GAAG,IAAI,CAAC,SAAS,EAAE;YACnB,gBAAgB,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;YAClF,kBAAkB,EAAE,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM;YACpD,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM;YAClC,iBAAiB,EAAE,aAAa,CAAC,MAAM;YACvC,qBAAqB,EAAE,iBAAiB,CAAC,MAAM;YAC/C,gBAAgB,EAAE;gBAChB,cAAc,EAAE,aAAa,CAAC,MAAM,GAAG,CAAC;gBACxC,iBAAiB,EAAE,iBAAiB,CAAC,MAAM,GAAG,CAAC;gBAC/C,iBAAiB,EAAE,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC;gBACvD,aAAa,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC;aAC3C;SACF,CAAC;IACJ,CAAC;CACF;AAED,MAAM,UAAU,wBAAwB,CAAC,KAA8B;IACrE,OAAO,IAAI,kBAAkB,CAAC,KAAK,CAAC,CAAC;AACvC,CAAC;AAED,SAAS,mBAAmB,CAAC,KAA8B;IACzD,OAAO;QACL,SAAS,EAAE,QAAQ,CAAC,KAAK,CAAC,SAAS,EAAE,0BAA0B,CAAC;QAChE,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,kBAAkB,CAAC;QAC1C,cAAc,EAAE,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,qBAAqB,CAAC;QAC/D,aAAa,EAAE,CAAC,KAAK,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,oBAAoB,CAAC;QACpE,iBAAiB,EAAE,CAAC,KAAK,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,wBAAwB,CAAC;KACjF,CAAC;AACJ,CAAC;AAED,SAAS,kBAAkB,CAAC,IAAuB;IACjD,OAAO;QACL,EAAE,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,wBAAwB,CAAC;QAC/C,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,4BAA4B,CAAC;QAC3D,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,0BAA0B,CAAC;QACrD,IAAI,EAAE,IAAI,CAAC,IAAI;KAChB,CAAC;AACJ,CAAC;AAED,SAAS,qBAAqB,CAAC,KAAiC;IAC9D,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;QACnD,MAAM,IAAI,KAAK,CAAC,0EAA0E,CAAC,CAAC;IAC9F,CAAC;IACD,OAAO;QACL,EAAE,EAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,EAAE,kCAAkC,CAAC;QAC1D,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC,MAAM,EAAE,sCAAsC,CAAC;KACvE,CAAC;AACJ,CAAC;AAED,SAAS,oBAAoB,CAAC,IAA+B;IAC3D,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC;QAC3D,MAAM,IAAI,KAAK,CAAC,8EAA8E,CAAC,CAAC;IAClG,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,GAAG,CAAC,EAAE,CAAC;QACzD,MAAM,IAAI,KAAK,CAAC,6EAA6E,CAAC,CAAC;IACjG,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC;QAC5D,MAAM,IAAI,KAAK,CAAC,wEAAwE,CAAC,CAAC;IAC5F,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,IAAI,CAAC,cAAc,GAAG,CAAC,EAAE,CAAC;QACtE,MAAM,IAAI,KAAK,CAAC,6EAA6E,CAAC,CAAC;IACjG,CAAC;IACD,OAAO;QACL,EAAE,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,iCAAiC,CAAC;QACxD,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,oCAAoC,CAAC;QACjE,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,cAAc,EAAE,IAAI,CAAC,cAAc;KACpC,CAAC;AACJ,CAAC;AAED,SAAS,wBAAwB,CAAC,IAAmC;IACnE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC;QAC3D,MAAM,IAAI,KAAK,CAAC,8EAA8E,CAAC,CAAC;IAClG,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;QACrE,MAAM,IAAI,KAAK,CAAC,sEAAsE,CAAC,CAAC;IAC1F,CAAC;IACD,OAAO;QACL,EAAE,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,iCAAiC,CAAC;QACxD,WAAW,EAAE,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,0CAA0C,CAAC;QACnF,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,uCAAuC,CAAC;QAC1E,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,MAAM,EAAE,IAAI,CAAC,MAAM;KACpB,CAAC;AACJ,CAAC;AAED,SAAS,QAAQ,CAAC,KAAa,EAAE,KAAa;IAC5C,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,8BAA8B,CAAC,CAAC;IACtE,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,54 @@
1
+ import type { AnimationClipEventType, SerializedAnimationEventTracks } from "@aura3d/animation";
2
+ export interface EventMarkerView {
3
+ readonly id: string;
4
+ readonly time: number;
5
+ readonly duration?: number;
6
+ readonly type: AnimationClipEventType;
7
+ readonly selected: boolean;
8
+ }
9
+ export interface EventTrackLane {
10
+ readonly name: string;
11
+ readonly type: AnimationClipEventType;
12
+ readonly markers: readonly EventMarkerView[];
13
+ }
14
+ export interface EventTrackEditorOptions {
15
+ readonly clipId: string;
16
+ readonly duration: number;
17
+ }
18
+ export interface AddEventMarkerOptions {
19
+ readonly id?: string;
20
+ readonly type?: AnimationClipEventType;
21
+ /** Window length (seconds). >0 makes the marker an active-frame window (e.g. hitbox on/off). */
22
+ readonly duration?: number;
23
+ readonly payload?: unknown;
24
+ readonly tags?: readonly string[];
25
+ }
26
+ /**
27
+ * Timeline event-track authoring controller. Deterministic: marker ids come from a monotonic
28
+ * counter (no `Date.now`/`Math.random`), so undo/redo and serialization are reproducible.
29
+ */
30
+ export declare class EventTrackEditor {
31
+ readonly clipId: string;
32
+ duration: number;
33
+ private readonly order;
34
+ private readonly lanesMap;
35
+ private selectedId;
36
+ private idCounter;
37
+ constructor(options: EventTrackEditorOptions);
38
+ addTrack(name: string, type?: AnimationClipEventType): this;
39
+ removeTrack(name: string): this;
40
+ /** Add a marker to a lane (auto-creates the lane). Returns the new marker id. */
41
+ addMarker(trackName: string, time: number, options?: AddEventMarkerOptions): string;
42
+ /** Move an existing marker to a new time. */
43
+ moveMarker(trackName: string, markerId: string, time: number): this;
44
+ /** Delete a marker. */
45
+ removeMarker(trackName: string, markerId: string): this;
46
+ select(markerId: string | undefined): this;
47
+ markerCount(): number;
48
+ /** View-model for the timeline UI: lanes with marker positions + selection state. */
49
+ lanes(): readonly EventTrackLane[];
50
+ /** Serialize to the canonical `animation-event-tracks/v1` shape. */
51
+ serialize(): SerializedAnimationEventTracks;
52
+ }
53
+ export declare function createEventTrackEditor(options: EventTrackEditorOptions): EventTrackEditor;
54
+ //# sourceMappingURL=EventTrackEditor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EventTrackEditor.d.ts","sourceRoot":"","sources":["../../../../packages/editor-runtime/src/EventTrackEditor.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAEV,sBAAsB,EAEtB,8BAA8B,EAC/B,MAAM,mBAAmB,CAAC;AAE3B,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,sBAAsB,CAAC;IACtC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,sBAAsB,CAAC;IACtC,QAAQ,CAAC,OAAO,EAAE,SAAS,eAAe,EAAE,CAAC;CAC9C;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,CAAC,EAAE,sBAAsB,CAAC;IACvC,gGAAgG;IAChG,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC;AAOD;;;GAGG;AACH,qBAAa,gBAAgB;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgB;IACtC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAgC;IACzD,OAAO,CAAC,UAAU,CAAqB;IACvC,OAAO,CAAC,SAAS,CAAK;gBAEV,OAAO,EAAE,uBAAuB;IAQ5C,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,sBAAiC,GAAG,IAAI;IAQrE,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAK/B,iFAAiF;IACjF,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,qBAA0B,GAAG,MAAM;IAoBvF,6CAA6C;IAC7C,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAYnE,uBAAuB;IACvB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IASvD,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAK1C,WAAW,IAAI,MAAM;IAMrB,qFAAqF;IACrF,KAAK,IAAI,SAAS,cAAc,EAAE;IAiBlC,oEAAoE;IACpE,SAAS,IAAI,8BAA8B;CAO5C;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,uBAAuB,GAAG,gBAAgB,CAEzF"}
@@ -0,0 +1,124 @@
1
+ // Editor authoring controller for animation event tracks (T2.2). Lets a timeline UI add / move /
2
+ // delete typed markers on named lanes (hitbox active-frames, footsteps, VFX, generic markers) and
3
+ // serialize to the canonical `animation-event-tracks/v1` shape that `@aura3d/animation`'s
4
+ // `deserializeAnimationEventTracks` / `sampleClipEvents` consume — so authored tracks drive gameplay
5
+ // (hitbox windows) and playback (footstep/VFX triggers) deterministically.
6
+ //
7
+ // Type-only imports from `@aura3d/animation` keep this controller free of any runtime coupling to
8
+ // that package (the types are erased at build time); the serialized output is verified to round-trip
9
+ // through the animation package's deserializer in tests.
10
+ /**
11
+ * Timeline event-track authoring controller. Deterministic: marker ids come from a monotonic
12
+ * counter (no `Date.now`/`Math.random`), so undo/redo and serialization are reproducible.
13
+ */
14
+ export class EventTrackEditor {
15
+ clipId;
16
+ duration;
17
+ order = [];
18
+ lanesMap = new Map();
19
+ selectedId;
20
+ idCounter = 0;
21
+ constructor(options) {
22
+ if (!Number.isFinite(options.duration) || options.duration < 0) {
23
+ throw new Error("EventTrackEditor duration must be a finite, non-negative number.");
24
+ }
25
+ this.clipId = options.clipId;
26
+ this.duration = options.duration;
27
+ }
28
+ addTrack(name, type = "marker") {
29
+ if (!this.lanesMap.has(name)) {
30
+ this.lanesMap.set(name, { type, markers: [] });
31
+ this.order.push(name);
32
+ }
33
+ return this;
34
+ }
35
+ removeTrack(name) {
36
+ if (this.lanesMap.delete(name))
37
+ this.order.splice(this.order.indexOf(name), 1);
38
+ return this;
39
+ }
40
+ /** Add a marker to a lane (auto-creates the lane). Returns the new marker id. */
41
+ addMarker(trackName, time, options = {}) {
42
+ if (!Number.isFinite(time) || time < 0) {
43
+ throw new Error("Event marker time must be a finite, non-negative number.");
44
+ }
45
+ this.addTrack(trackName, options.type);
46
+ const lane = this.lanesMap.get(trackName);
47
+ const id = options.id ?? `${trackName}#${this.idCounter++}`;
48
+ lane.markers.push({
49
+ id,
50
+ name: trackName,
51
+ type: options.type ?? lane.type,
52
+ time,
53
+ ...(options.duration !== undefined ? { duration: options.duration } : {}),
54
+ ...(options.payload !== undefined ? { payload: options.payload } : {}),
55
+ ...(options.tags !== undefined ? { tags: options.tags } : {})
56
+ });
57
+ lane.markers.sort((a, b) => a.time - b.time);
58
+ return id;
59
+ }
60
+ /** Move an existing marker to a new time. */
61
+ moveMarker(trackName, markerId, time) {
62
+ if (!Number.isFinite(time) || time < 0) {
63
+ throw new Error("Event marker time must be a finite, non-negative number.");
64
+ }
65
+ const lane = this.lanesMap.get(trackName);
66
+ const index = lane?.markers.findIndex((m) => m.id === markerId) ?? -1;
67
+ if (!lane || index < 0)
68
+ throw new Error(`Marker ${markerId} not found on track ${trackName}.`);
69
+ lane.markers[index] = { ...lane.markers[index], time };
70
+ lane.markers.sort((a, b) => a.time - b.time);
71
+ return this;
72
+ }
73
+ /** Delete a marker. */
74
+ removeMarker(trackName, markerId) {
75
+ const lane = this.lanesMap.get(trackName);
76
+ if (!lane)
77
+ return this;
78
+ const index = lane.markers.findIndex((m) => m.id === markerId);
79
+ if (index >= 0)
80
+ lane.markers.splice(index, 1);
81
+ if (this.selectedId === markerId)
82
+ this.selectedId = undefined;
83
+ return this;
84
+ }
85
+ select(markerId) {
86
+ this.selectedId = markerId;
87
+ return this;
88
+ }
89
+ markerCount() {
90
+ let count = 0;
91
+ for (const lane of this.lanesMap.values())
92
+ count += lane.markers.length;
93
+ return count;
94
+ }
95
+ /** View-model for the timeline UI: lanes with marker positions + selection state. */
96
+ lanes() {
97
+ return this.order.map((name) => {
98
+ const lane = this.lanesMap.get(name);
99
+ return {
100
+ name,
101
+ type: lane.type,
102
+ markers: lane.markers.map((m) => ({
103
+ id: m.id,
104
+ time: m.time,
105
+ ...(m.duration !== undefined ? { duration: m.duration } : {}),
106
+ type: m.type ?? lane.type,
107
+ selected: m.id === this.selectedId
108
+ }))
109
+ };
110
+ });
111
+ }
112
+ /** Serialize to the canonical `animation-event-tracks/v1` shape. */
113
+ serialize() {
114
+ const tracks = this.order.map((name) => {
115
+ const lane = this.lanesMap.get(name);
116
+ return { name, type: lane.type, markers: lane.markers.map((m) => ({ ...m })) };
117
+ });
118
+ return { schema: "animation-event-tracks/v1", clipId: this.clipId, duration: this.duration, tracks };
119
+ }
120
+ }
121
+ export function createEventTrackEditor(options) {
122
+ return new EventTrackEditor(options);
123
+ }
124
+ //# sourceMappingURL=EventTrackEditor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EventTrackEditor.js","sourceRoot":"","sources":["../../../../packages/editor-runtime/src/EventTrackEditor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ import { CommandHistory } from "./CommandHistory";
2
+ import type { TimelineClip } from "./TimelineModel";
3
+ export type TimelineKeyframeValue = number | string | boolean;
4
+ export type TimelineKeyframeInterpolation = "hold" | "linear" | "bezier";
5
+ export interface TimelineBezierHandle {
6
+ readonly time: number;
7
+ readonly value: number;
8
+ }
9
+ export interface TimelineKeyframe {
10
+ readonly id: string;
11
+ readonly propertyPath: string;
12
+ readonly time: number;
13
+ readonly value: TimelineKeyframeValue;
14
+ readonly interpolation: TimelineKeyframeInterpolation;
15
+ readonly inHandle?: TimelineBezierHandle;
16
+ readonly outHandle?: TimelineBezierHandle;
17
+ }
18
+ export interface CreateTimelineKeyframeOptions {
19
+ readonly id?: string;
20
+ readonly propertyPath: string;
21
+ readonly time: number;
22
+ readonly value: TimelineKeyframeValue;
23
+ readonly interpolation?: TimelineKeyframeInterpolation;
24
+ readonly inHandle?: TimelineBezierHandle;
25
+ readonly outHandle?: TimelineBezierHandle;
26
+ }
27
+ export interface PasteTimelineKeyframesOptions {
28
+ readonly timeOffset?: number;
29
+ readonly idPrefix?: string;
30
+ readonly propertyPath?: string;
31
+ }
32
+ export declare function readTimelineKeyframes(clip: TimelineClip): readonly TimelineKeyframe[];
33
+ export declare function encodeTimelineKeyframes(keyframes: readonly TimelineKeyframe[]): string;
34
+ export declare function timelineKeyframesByProperty(clip: TimelineClip, propertyPath: string): readonly TimelineKeyframe[];
35
+ export declare class KeyframeEditor {
36
+ private readonly history;
37
+ constructor(history?: CommandHistory);
38
+ get commandHistory(): CommandHistory;
39
+ keyframes(clip: TimelineClip, propertyPath?: string): readonly TimelineKeyframe[];
40
+ addKeyframe(clip: TimelineClip, options: CreateTimelineKeyframeOptions): Promise<TimelineKeyframe>;
41
+ deleteKeyframes(clip: TimelineClip, ids: readonly string[]): Promise<void>;
42
+ moveKeyframes(clip: TimelineClip, ids: readonly string[], deltaTime: number): Promise<readonly TimelineKeyframe[]>;
43
+ scaleKeyframes(clip: TimelineClip, ids: readonly string[], pivotTime: number, scale: number): Promise<readonly TimelineKeyframe[]>;
44
+ copyKeyframes(clip: TimelineClip, ids: readonly string[]): readonly TimelineKeyframe[];
45
+ pasteKeyframes(clip: TimelineClip, keyframes: readonly TimelineKeyframe[], options?: PasteTimelineKeyframesOptions): Promise<readonly TimelineKeyframe[]>;
46
+ replaceKeyframes(clip: TimelineClip, keyframes: readonly TimelineKeyframe[], label?: string): Promise<void>;
47
+ private applyKeyframes;
48
+ }
49
+ //# sourceMappingURL=KeyframeEditor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"KeyframeEditor.d.ts","sourceRoot":"","sources":["../../../../packages/editor-runtime/src/KeyframeEditor.ts"],"names":[],"mappings":"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"}