@pixerate/editor 0.144.0 → 0.145.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.
@@ -26,7 +26,7 @@ var _chunk7B5GTJXBcjs = require('../chunk-7B5GTJXB.cjs');
26
26
 
27
27
 
28
28
 
29
- var _chunkSVR5FR7Bcjs = require('../chunk-SVR5FR7B.cjs');
29
+ var _chunkUUTTJK77cjs = require('../chunk-UUTTJK77.cjs');
30
30
 
31
31
 
32
32
 
@@ -98,4 +98,4 @@ require('../chunk-A6QWKBJP.cjs');
98
98
 
99
99
 
100
100
 
101
- exports.ANIMATION_EASING_LABELS = _chunkDWJJI6RTcjs.ANIMATION_EASING_LABELS; exports.ANIMATION_EASING_PRESETS = _chunkDWJJI6RTcjs.ANIMATION_EASING_PRESETS; exports.ANIMATION_TIME_EPSILON = _chunkSVR5FR7Bcjs.ANIMATION_TIME_EPSILON; exports.AnimationPlayer = _chunkSVR5FR7Bcjs.AnimationPlayer; exports.CUBIC_BEZIER_PRESETS = _chunkDWJJI6RTcjs.CUBIC_BEZIER_PRESETS; exports.MOTION_BEHAVIORS = _chunk7B5GTJXBcjs.MOTION_BEHAVIORS; exports.ManualClock = _chunkSVR5FR7Bcjs.ManualClock; exports.PRESENCE_COLORS = _chunkUJGAA6AKcjs.PRESENCE_COLORS; exports.PerformanceQueue = _chunkUJGAA6AKcjs.PerformanceQueue; exports.PresenceStore = _chunkUJGAA6AKcjs.PresenceStore; exports.SPRING_PRESETS = _chunkDWJJI6RTcjs.SPRING_PRESETS; exports.behaviorProgress = _chunk7B5GTJXBcjs.behaviorProgress; exports.createAnimationPlayer = _chunkSVR5FR7Bcjs.createAnimationPlayer; exports.createInstantPresenceClock = _chunkUJGAA6AKcjs.createInstantPresenceClock; exports.cubicBezierAt = _chunkDWJJI6RTcjs.cubicBezierAt; exports.easingFromInfluence = _chunkDWJJI6RTcjs.easingFromInfluence; exports.easingLabel = _chunkDWJJI6RTcjs.easingLabel; exports.easingToCss = _chunkDWJJI6RTcjs.easingToCss; exports.elasticAt = _chunkDWJJI6RTcjs.elasticAt; exports.evaluateEasing = _chunkDWJJI6RTcjs.evaluateEasing; exports.evaluateTrack = _chunkSVR5FR7Bcjs.evaluateTrack; exports.formatOklab = _chunk5FXOR7F2cjs.formatOklab; exports.fractalWiggle = _chunk7B5GTJXBcjs.fractalWiggle; exports.interpolateAnimationValue = _chunkSVR5FR7Bcjs.interpolateAnimationValue; exports.isAnimationEasing = _chunkDWJJI6RTcjs.isAnimationEasing; exports.isAnimationKeyframe = _chunkSVR5FR7Bcjs.isAnimationKeyframe; exports.isMotionBehavior = _chunk7B5GTJXBcjs.isMotionBehavior; exports.mixColorsOklab = _chunk5FXOR7F2cjs.mixColorsOklab; exports.motionSeedFromId = _chunk7B5GTJXBcjs.motionSeedFromId; exports.normalizeKeyframes = _chunkSVR5FR7Bcjs.normalizeKeyframes; exports.oklabToRgb = _chunk5FXOR7F2cjs.oklabToRgb; exports.pageHidden = _chunkSVR5FR7Bcjs.pageHidden; exports.parseCssEasing = _chunkDWJJI6RTcjs.parseCssEasing; exports.parseOklab = _chunk5FXOR7F2cjs.parseOklab; exports.quinticFade = _chunk7B5GTJXBcjs.quinticFade; exports.realClock = _chunkSVR5FR7Bcjs.realClock; exports.realPresenceClock = _chunkUJGAA6AKcjs.realPresenceClock; exports.resolveEasing = _chunkDWJJI6RTcjs.resolveEasing; exports.reverseCubicBezier = _chunkDWJJI6RTcjs.reverseCubicBezier; exports.rgbToOklab = _chunk5FXOR7F2cjs.rgbToOklab; exports.springAt = _chunkDWJJI6RTcjs.springAt; exports.springSettleMs = _chunkDWJJI6RTcjs.springSettleMs; exports.tweenPresenceCursor = _chunkUJGAA6AKcjs.tweenPresenceCursor; exports.wrapAnimationTime = _chunkSVR5FR7Bcjs.wrapAnimationTime;
101
+ exports.ANIMATION_EASING_LABELS = _chunkDWJJI6RTcjs.ANIMATION_EASING_LABELS; exports.ANIMATION_EASING_PRESETS = _chunkDWJJI6RTcjs.ANIMATION_EASING_PRESETS; exports.ANIMATION_TIME_EPSILON = _chunkUUTTJK77cjs.ANIMATION_TIME_EPSILON; exports.AnimationPlayer = _chunkUUTTJK77cjs.AnimationPlayer; exports.CUBIC_BEZIER_PRESETS = _chunkDWJJI6RTcjs.CUBIC_BEZIER_PRESETS; exports.MOTION_BEHAVIORS = _chunk7B5GTJXBcjs.MOTION_BEHAVIORS; exports.ManualClock = _chunkUUTTJK77cjs.ManualClock; exports.PRESENCE_COLORS = _chunkUJGAA6AKcjs.PRESENCE_COLORS; exports.PerformanceQueue = _chunkUJGAA6AKcjs.PerformanceQueue; exports.PresenceStore = _chunkUJGAA6AKcjs.PresenceStore; exports.SPRING_PRESETS = _chunkDWJJI6RTcjs.SPRING_PRESETS; exports.behaviorProgress = _chunk7B5GTJXBcjs.behaviorProgress; exports.createAnimationPlayer = _chunkUUTTJK77cjs.createAnimationPlayer; exports.createInstantPresenceClock = _chunkUJGAA6AKcjs.createInstantPresenceClock; exports.cubicBezierAt = _chunkDWJJI6RTcjs.cubicBezierAt; exports.easingFromInfluence = _chunkDWJJI6RTcjs.easingFromInfluence; exports.easingLabel = _chunkDWJJI6RTcjs.easingLabel; exports.easingToCss = _chunkDWJJI6RTcjs.easingToCss; exports.elasticAt = _chunkDWJJI6RTcjs.elasticAt; exports.evaluateEasing = _chunkDWJJI6RTcjs.evaluateEasing; exports.evaluateTrack = _chunkUUTTJK77cjs.evaluateTrack; exports.formatOklab = _chunk5FXOR7F2cjs.formatOklab; exports.fractalWiggle = _chunk7B5GTJXBcjs.fractalWiggle; exports.interpolateAnimationValue = _chunkUUTTJK77cjs.interpolateAnimationValue; exports.isAnimationEasing = _chunkDWJJI6RTcjs.isAnimationEasing; exports.isAnimationKeyframe = _chunkUUTTJK77cjs.isAnimationKeyframe; exports.isMotionBehavior = _chunk7B5GTJXBcjs.isMotionBehavior; exports.mixColorsOklab = _chunk5FXOR7F2cjs.mixColorsOklab; exports.motionSeedFromId = _chunk7B5GTJXBcjs.motionSeedFromId; exports.normalizeKeyframes = _chunkUUTTJK77cjs.normalizeKeyframes; exports.oklabToRgb = _chunk5FXOR7F2cjs.oklabToRgb; exports.pageHidden = _chunkUUTTJK77cjs.pageHidden; exports.parseCssEasing = _chunkDWJJI6RTcjs.parseCssEasing; exports.parseOklab = _chunk5FXOR7F2cjs.parseOklab; exports.quinticFade = _chunk7B5GTJXBcjs.quinticFade; exports.realClock = _chunkUUTTJK77cjs.realClock; exports.realPresenceClock = _chunkUJGAA6AKcjs.realPresenceClock; exports.resolveEasing = _chunkDWJJI6RTcjs.resolveEasing; exports.reverseCubicBezier = _chunkDWJJI6RTcjs.reverseCubicBezier; exports.rgbToOklab = _chunk5FXOR7F2cjs.rgbToOklab; exports.springAt = _chunkDWJJI6RTcjs.springAt; exports.springSettleMs = _chunkDWJJI6RTcjs.springSettleMs; exports.tweenPresenceCursor = _chunkUJGAA6AKcjs.tweenPresenceCursor; exports.wrapAnimationTime = _chunkUUTTJK77cjs.wrapAnimationTime;
@@ -26,7 +26,7 @@ import {
26
26
  pageHidden,
27
27
  realClock,
28
28
  wrapAnimationTime
29
- } from "../chunk-I4T4J27S.js";
29
+ } from "../chunk-QX25HWFL.js";
30
30
  import {
31
31
  ANIMATION_EASING_LABELS,
32
32
  ANIMATION_EASING_PRESETS,
@@ -54,6 +54,11 @@ export declare class AnimationPlayer {
54
54
  /** Current timeline length (ms). */
55
55
  get duration(): number;
56
56
  get currentTime(): number;
57
+ /**
58
+ * The playhead at this moment of the clock, between frames too (`currentTime` is the last
59
+ * frame's): what input arriving between frames, like a recorded pointer move, happened at.
60
+ */
61
+ get liveTime(): number;
57
62
  get isPlaying(): boolean;
58
63
  getState(): AnimationPlayerState;
59
64
  subscribe(listener: (state: AnimationPlayerState) => void): () => void;
@@ -54,6 +54,11 @@ export declare class AnimationPlayer {
54
54
  /** Current timeline length (ms). */
55
55
  get duration(): number;
56
56
  get currentTime(): number;
57
+ /**
58
+ * The playhead at this moment of the clock, between frames too (`currentTime` is the last
59
+ * frame's): what input arriving between frames, like a recorded pointer move, happened at.
60
+ */
61
+ get liveTime(): number;
57
62
  get isPlaying(): boolean;
58
63
  getState(): AnimationPlayerState;
59
64
  subscribe(listener: (state: AnimationPlayerState) => void): () => void;
@@ -12,6 +12,7 @@ import type { MotionIssue } from './issues.cjs';
12
12
  import type { MotionScene } from './types.cjs';
13
13
  import { EffectsSlot } from '../effects/helpers.cjs';
14
14
  import type { EffectProvider, EffectValue } from '../effects/types.cjs';
15
+ import { type MotionNodePose, type MotionTake, type MotionTakeOptions, type MotionTakeResult, type MotionTakeSample } from './record.cjs';
15
16
  import { type AppliedMotionEffect } from './effects.cjs';
16
17
  export interface AnimationEditorOptions {
17
18
  /** The scene to open (default: an empty one over a blank 800 × 450 artwork). */
@@ -44,6 +45,38 @@ export interface AnimationEditorSelection {
44
45
  shot: string;
45
46
  command?: number;
46
47
  }
48
+ /** What a stage drag does to a node while recording: move it, scale it about its centre or turn it. */
49
+ export type MotionRecordGestureMode = 'move' | 'scale' | 'rotate';
50
+ export declare const MOTION_RECORD_GESTURE_MODES: readonly MotionRecordGestureMode[];
51
+ /** A take being recorded (see `startRecording`). */
52
+ export interface AnimationEditorRecording {
53
+ /** The id the take's shot will get. */
54
+ shot: string;
55
+ /** Where the shot will go among the shots. */
56
+ at: number;
57
+ /** When the take starts in the scene, ms. */
58
+ start: number;
59
+ /** How long it has run, ms. */
60
+ elapsed: number;
61
+ /** Samples recorded so far. */
62
+ samples: number;
63
+ /** The node a stage drag is changing now, and how. */
64
+ gesture: {
65
+ node: string;
66
+ mode: MotionRecordGestureMode;
67
+ } | null;
68
+ }
69
+ /** What `stopRecording` and `recordTake` return. */
70
+ export type MotionRecordResult = ({
71
+ ok: true;
72
+ } & MotionTakeResult & {
73
+ issues: readonly MotionIssue[];
74
+ }) | {
75
+ ok: false;
76
+ error: string;
77
+ };
78
+ /** The longest take, ms. */
79
+ export declare const MOTION_MAX_TAKE_MS: number;
47
80
  /** A snapshot of the editor. The same object is returned until something changes. */
48
81
  export interface AnimationEditorState {
49
82
  scene: MotionScene;
@@ -71,6 +104,8 @@ export interface AnimationEditorState {
71
104
  revision: number;
72
105
  /** The registered effects provider, or `null`. */
73
106
  effectsProvider: EffectProvider | null;
107
+ /** The take being recorded, or `null`. While recording, frames show the take so far. */
108
+ recording: AnimationEditorRecording | null;
74
109
  }
75
110
  /**
76
111
  * Headless editor for a vector animation (a `MotionScene`): undoable, all-or-nothing edits,
@@ -95,6 +130,7 @@ export declare class AnimationEditorController {
95
130
  private readonly listeners;
96
131
  private readonly unsubscribers;
97
132
  private state;
133
+ private recording;
98
134
  constructor(options?: AnimationEditorOptions);
99
135
  private connect;
100
136
  /**
@@ -178,16 +214,80 @@ export declare class AnimationEditorController {
178
214
  play(): void;
179
215
  pause(): void;
180
216
  toggle(): void;
181
- /** Moves the playhead (ms). */
217
+ /** Moves the playhead (ms). Ignored while recording: a take runs on from where it started. */
182
218
  seek(time: number): void;
183
219
  /** Moves the playhead to the start or end of a shot. Returns false for an unknown shot. */
184
220
  seekShot(id: string, at?: 'start' | 'end'): boolean;
185
221
  undo(): boolean;
186
222
  redo(): boolean;
223
+ /** The scene as shown: while recording, with the take so far as its shot. */
224
+ viewScene(): MotionScene;
187
225
  /** The scene at `time` (default: the playhead). */
188
226
  frame(time?: number, options?: MotionFrameOptions): MotionFrame;
189
227
  /** The scene at `time` (default: the playhead) as SVG. */
190
228
  toSvg(time?: number, options?: MotionSvgOptions & MotionOverlayOptions): string;
229
+ /**
230
+ * Starts recording a take: the playhead goes to where the take's shot will start (default:
231
+ * the end of the scene) and plays on, and every `recordSample` (or stage gesture) is a value
232
+ * at that moment. Frames show the take so far. `stopRecording` turns it into one shot, one
233
+ * undo step. Edits, seeks and undo wait until the recording stops; `pause` pauses the take.
234
+ */
235
+ startRecording(options?: MotionTakeOptions): {
236
+ ok: true;
237
+ recording: AnimationEditorRecording;
238
+ } | {
239
+ ok: false;
240
+ error: string;
241
+ };
242
+ /**
243
+ * Records `values` for `node` at `t` (ms into the take; default now). Returns why a sample was
244
+ * refused (an unknown node, a value out of range), or null.
245
+ */
246
+ recordSample(node: string, values: Omit<MotionTakeSample, 'node' | 't'>, t?: number): string | null;
247
+ /** Where `node` is and how it looks now (while recording: in the take so far), or at `time`. */
248
+ pose(node: string, time?: number): MotionNodePose;
249
+ /** A point on a stage element (client pixels, e.g. a pointer event) in document units, through the camera now. */
250
+ clientToDocument(box: {
251
+ left: number;
252
+ top: number;
253
+ width: number;
254
+ height: number;
255
+ }, clientX: number, clientY: number): {
256
+ x: number;
257
+ y: number;
258
+ };
259
+ /**
260
+ * Starts a stage drag while recording: from `point` (document units), `move` drags the node,
261
+ * `scale` scales it about its centre by how much nearer or farther the pointer is, and
262
+ * `rotate` turns it with the pointer. Returns false when not recording or `node` is unknown.
263
+ */
264
+ beginRecordGesture(node: string, mode: MotionRecordGestureMode, point: {
265
+ x: number;
266
+ y: number;
267
+ }): boolean;
268
+ /** Records the drag's pose with the pointer at `point` (document units). */
269
+ updateRecordGesture(point: {
270
+ x: number;
271
+ y: number;
272
+ }): void;
273
+ /** Ends the stage drag (the take keeps recording). */
274
+ endRecordGesture(): void;
275
+ private recordGesture;
276
+ private endRecording;
277
+ /**
278
+ * Stops recording and adds the take as a shot (one undo step), selected, with the playhead at
279
+ * its start. Returns the shot, or why nothing was added (nothing recorded).
280
+ */
281
+ stopRecording(): MotionRecordResult;
282
+ /** Stops recording and throws the take away. */
283
+ cancelRecording(): void;
284
+ /**
285
+ * Adds a take given as samples (an agent's performance, or one recorded elsewhere) as a shot,
286
+ * one undo step, selected. With `dryRun` it returns the shot and changes nothing.
287
+ */
288
+ recordTake(take: MotionTake, options?: MotionTakeOptions & {
289
+ dryRun?: boolean;
290
+ }): MotionRecordResult;
191
291
  /** The scene as a Flair `SvgMotion`. */
192
292
  toFlairMotion(options?: FlairExportOptions): import("./flair.cjs").FlairMotionExport;
193
293
  /** The scene as a Flair catalog vector effect. */
@@ -12,6 +12,7 @@ import type { MotionIssue } from './issues.js';
12
12
  import type { MotionScene } from './types.js';
13
13
  import { EffectsSlot } from '../effects/helpers.js';
14
14
  import type { EffectProvider, EffectValue } from '../effects/types.js';
15
+ import { type MotionNodePose, type MotionTake, type MotionTakeOptions, type MotionTakeResult, type MotionTakeSample } from './record.js';
15
16
  import { type AppliedMotionEffect } from './effects.js';
16
17
  export interface AnimationEditorOptions {
17
18
  /** The scene to open (default: an empty one over a blank 800 × 450 artwork). */
@@ -44,6 +45,38 @@ export interface AnimationEditorSelection {
44
45
  shot: string;
45
46
  command?: number;
46
47
  }
48
+ /** What a stage drag does to a node while recording: move it, scale it about its centre or turn it. */
49
+ export type MotionRecordGestureMode = 'move' | 'scale' | 'rotate';
50
+ export declare const MOTION_RECORD_GESTURE_MODES: readonly MotionRecordGestureMode[];
51
+ /** A take being recorded (see `startRecording`). */
52
+ export interface AnimationEditorRecording {
53
+ /** The id the take's shot will get. */
54
+ shot: string;
55
+ /** Where the shot will go among the shots. */
56
+ at: number;
57
+ /** When the take starts in the scene, ms. */
58
+ start: number;
59
+ /** How long it has run, ms. */
60
+ elapsed: number;
61
+ /** Samples recorded so far. */
62
+ samples: number;
63
+ /** The node a stage drag is changing now, and how. */
64
+ gesture: {
65
+ node: string;
66
+ mode: MotionRecordGestureMode;
67
+ } | null;
68
+ }
69
+ /** What `stopRecording` and `recordTake` return. */
70
+ export type MotionRecordResult = ({
71
+ ok: true;
72
+ } & MotionTakeResult & {
73
+ issues: readonly MotionIssue[];
74
+ }) | {
75
+ ok: false;
76
+ error: string;
77
+ };
78
+ /** The longest take, ms. */
79
+ export declare const MOTION_MAX_TAKE_MS: number;
47
80
  /** A snapshot of the editor. The same object is returned until something changes. */
48
81
  export interface AnimationEditorState {
49
82
  scene: MotionScene;
@@ -71,6 +104,8 @@ export interface AnimationEditorState {
71
104
  revision: number;
72
105
  /** The registered effects provider, or `null`. */
73
106
  effectsProvider: EffectProvider | null;
107
+ /** The take being recorded, or `null`. While recording, frames show the take so far. */
108
+ recording: AnimationEditorRecording | null;
74
109
  }
75
110
  /**
76
111
  * Headless editor for a vector animation (a `MotionScene`): undoable, all-or-nothing edits,
@@ -95,6 +130,7 @@ export declare class AnimationEditorController {
95
130
  private readonly listeners;
96
131
  private readonly unsubscribers;
97
132
  private state;
133
+ private recording;
98
134
  constructor(options?: AnimationEditorOptions);
99
135
  private connect;
100
136
  /**
@@ -178,16 +214,80 @@ export declare class AnimationEditorController {
178
214
  play(): void;
179
215
  pause(): void;
180
216
  toggle(): void;
181
- /** Moves the playhead (ms). */
217
+ /** Moves the playhead (ms). Ignored while recording: a take runs on from where it started. */
182
218
  seek(time: number): void;
183
219
  /** Moves the playhead to the start or end of a shot. Returns false for an unknown shot. */
184
220
  seekShot(id: string, at?: 'start' | 'end'): boolean;
185
221
  undo(): boolean;
186
222
  redo(): boolean;
223
+ /** The scene as shown: while recording, with the take so far as its shot. */
224
+ viewScene(): MotionScene;
187
225
  /** The scene at `time` (default: the playhead). */
188
226
  frame(time?: number, options?: MotionFrameOptions): MotionFrame;
189
227
  /** The scene at `time` (default: the playhead) as SVG. */
190
228
  toSvg(time?: number, options?: MotionSvgOptions & MotionOverlayOptions): string;
229
+ /**
230
+ * Starts recording a take: the playhead goes to where the take's shot will start (default:
231
+ * the end of the scene) and plays on, and every `recordSample` (or stage gesture) is a value
232
+ * at that moment. Frames show the take so far. `stopRecording` turns it into one shot, one
233
+ * undo step. Edits, seeks and undo wait until the recording stops; `pause` pauses the take.
234
+ */
235
+ startRecording(options?: MotionTakeOptions): {
236
+ ok: true;
237
+ recording: AnimationEditorRecording;
238
+ } | {
239
+ ok: false;
240
+ error: string;
241
+ };
242
+ /**
243
+ * Records `values` for `node` at `t` (ms into the take; default now). Returns why a sample was
244
+ * refused (an unknown node, a value out of range), or null.
245
+ */
246
+ recordSample(node: string, values: Omit<MotionTakeSample, 'node' | 't'>, t?: number): string | null;
247
+ /** Where `node` is and how it looks now (while recording: in the take so far), or at `time`. */
248
+ pose(node: string, time?: number): MotionNodePose;
249
+ /** A point on a stage element (client pixels, e.g. a pointer event) in document units, through the camera now. */
250
+ clientToDocument(box: {
251
+ left: number;
252
+ top: number;
253
+ width: number;
254
+ height: number;
255
+ }, clientX: number, clientY: number): {
256
+ x: number;
257
+ y: number;
258
+ };
259
+ /**
260
+ * Starts a stage drag while recording: from `point` (document units), `move` drags the node,
261
+ * `scale` scales it about its centre by how much nearer or farther the pointer is, and
262
+ * `rotate` turns it with the pointer. Returns false when not recording or `node` is unknown.
263
+ */
264
+ beginRecordGesture(node: string, mode: MotionRecordGestureMode, point: {
265
+ x: number;
266
+ y: number;
267
+ }): boolean;
268
+ /** Records the drag's pose with the pointer at `point` (document units). */
269
+ updateRecordGesture(point: {
270
+ x: number;
271
+ y: number;
272
+ }): void;
273
+ /** Ends the stage drag (the take keeps recording). */
274
+ endRecordGesture(): void;
275
+ private recordGesture;
276
+ private endRecording;
277
+ /**
278
+ * Stops recording and adds the take as a shot (one undo step), selected, with the playhead at
279
+ * its start. Returns the shot, or why nothing was added (nothing recorded).
280
+ */
281
+ stopRecording(): MotionRecordResult;
282
+ /** Stops recording and throws the take away. */
283
+ cancelRecording(): void;
284
+ /**
285
+ * Adds a take given as samples (an agent's performance, or one recorded elsewhere) as a shot,
286
+ * one undo step, selected. With `dryRun` it returns the shot and changes nothing.
287
+ */
288
+ recordTake(take: MotionTake, options?: MotionTakeOptions & {
289
+ dryRun?: boolean;
290
+ }): MotionRecordResult;
191
291
  /** The scene as a Flair `SvgMotion`. */
192
292
  toFlairMotion(options?: FlairExportOptions): import("./flair.js").FlairMotionExport;
193
293
  /** The scene as a Flair catalog vector effect. */