@weasel-js/animator 1.10.0 → 1.11.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.
package/dist/index.d.ts CHANGED
@@ -1,939 +1,8 @@
1
- import { EasingSpec, SpringPresetName, EasingName, BezierEasing, GlMat3, Path, PolygonPath } from '@weasel-js/geom';
2
- export { BezierEasing, EasingFn, EasingSpec, SpringPreset, SpringPresetName } from '@weasel-js/geom';
1
+ import { V as VertexColorChannel, A as Animator, a as AnimationHandle, S as SampledTrack, T as Target, I as Interpolate, b as TimelineEvent, N as NestedTimeline, c as TargetAxes } from './types-QKD4dhHF.js';
2
+ export { d as AnimationInfo, e as AnimationKind, f as AnimatorEvent, g as AnimatorListener, h as AxisBuffer, i as AxisName, j as AxisRef, C as ColorOverride, k as ColorOverrideFn, l as ColorOverrideRegistry, D as DecayOptions, E as EventBooking, m as EventBookingHandle, n as EventTrack, H as HoldHandle, o as HoldOptions, p as HoldRowsOptions, q as InterpolatorFactory, K as Keyframe, L as LiveAnimation, r as LoopFactory, s as LoopOptions, t as Naming, P as PhysicsHandle, u as PhysicsOptions, R as RowsHoldHandle, v as ShownArray, w as SpringOptions, x as StaggerBuilder, y as StaggerDelay, z as StaggerFactory, B as StaggerItemSpringOptions, F as StaggerItemTweenOptions, G as StaggerOptions, J as StaggerPerItem, M as StaggerSpringOptions, O as StaggerTargetSpringOptions, Q as StaggerTargetTweenOptions, U as StaggerTweenOptions, W as TargetDecayOptions, X as TargetOptions, Y as TargetPhysicsOptions, Z as TargetSpringOptions, _ as TargetTable, $ as TargetTableOptions, a0 as TargetTweenOptions, a1 as TimelineClock, a2 as TimelineHandle, a3 as TimelineOptions, a4 as TimelineTrack, a5 as Track, a6 as TweenLoopOptions, a7 as TweenOptions, a8 as UseAnimatorOptions, a9 as createTarget, aa as createTargetTable } from './types-QKD4dhHF.js';
3
3
  import { ColorSpace } from '@weasel-js/paint';
4
-
5
- /**
6
- * What an axis of a `T` goes by: a field of a plain object, or a path into a nested one, as a
7
- * pose's `knee` and `knee.rotation` are. `never` for a number or an array, whose axes have
8
- * indexes only.
9
- */
10
- type AxisName<T> = T extends number | readonly unknown[] ? never : T extends object ? {
11
- [K in keyof T & string]: NonNullable<T[K]> extends number ? K : K | `${K}.${string}`;
12
- }[keyof T & string] : string;
13
- /** One of a target's axes: its index, or its name where the target's axes have names. */
14
- type AxisRef<T = unknown> = number | AxisName<T>;
15
-
16
- /** How a target's value maps to the flat numbers an animation moves, and back. */
17
- interface TargetAxes<T> {
18
- count: number;
19
- to(value: T): number[];
20
- from(axes: ArrayLike<number>): T;
21
- /** Indexes of axes that are angles in radians. An animation starting from one takes the short
22
- * way round to its destination. */
23
- angles?: readonly number[];
24
- /** A name for each axis, in the order `to` answers them, for `axes` options to go by. A dot
25
- * makes a path: `knee.rotation` is also reached as `knee`, with the joint's other axes. */
26
- names?: readonly string[];
27
- /** Optional. `value` with `delta` added axis by axis: what `from` answers for `to(value)`
28
- * plus `delta`, built with no array between. A read of a moving target goes through it. */
29
- add?(value: T, delta: ArrayLike<number>): T;
30
- /** Optional. Puts `value`'s axes into `out` from `at`: what `to` answers, with no array
31
- * built. `readInto` goes through it. */
32
- write?(value: T, out: AxisBuffer, at: number): void;
33
- }
34
- /** Somewhere a target's axes are written as numbers. */
35
- type AxisBuffer = Float64Array | Float32Array | number[];
36
- /** What {@link createTarget} takes. */
37
- interface TargetOptions<T> {
38
- /** The committed value: what shows when nothing is animating. */
39
- get(): T;
40
- /** Commits a value: an animation's destination as it starts, and where a canceled one stopped. */
41
- set(value: T): void;
42
- /** How `T` maps to numbers. Default: a number, an array of numbers, or a plain object whose
43
- * fields are all numbers, read from `get()` when the target is made. */
44
- axes?: TargetAxes<T>;
45
- /** Called once a frame, after the frame's animations, with the value to show: on every frame
46
- * the target is moving, as an animation starts on it or is redirected, and once more as it
47
- * comes to rest. Omit for a target whose reader
48
- * calls `read()` itself. */
49
- show?(value: T): void;
50
- /** Called once a frame, after every target that was shown that frame: for a table that
51
- * publishes many targets at once. Targets passing the same function share one call. */
52
- publish?(): void;
53
- }
54
- /**
55
- * One value an animator can move. Pass it as `target` to `tween`, `spring`, `physics` or `decay`.
56
- *
57
- * An animation on a target commits its destination when it starts and contributes only what is
58
- * left to travel, so several on one target add: a second started mid-flight bends the motion
59
- * toward its own destination and neither cancels the other.
60
- */
61
- interface Target<T> {
62
- /** The value to show: the committed value plus what every running animation has left to travel. */
63
- read(): T;
64
- /**
65
- * As `read`, as numbers: writes the value's `axisCount` axes into `out` from `at` (default 0),
66
- * in the order the target's `axes.to` answers them. For a reader of many targets that wants
67
- * the numbers and no value built for each.
68
- */
69
- readInto(out: AxisBuffer, at?: number): void;
70
- /** How many axes `readInto` writes. */
71
- readonly axisCount: number;
72
- /** How its value maps to numbers. */
73
- readonly axes: TargetAxes<T>;
74
- /**
75
- * The indexes of the axes `axes` names, in the order named: what a hold's or a track's `axes`
76
- * resolves through. A name is one of `axes.names`, or a path over several of them; an index
77
- * passes through. Throws on a name or an index the target has no axis for.
78
- */
79
- axisIndexes(axes: readonly AxisRef<T>[]): number[];
80
- /** The committed value: what shows once nothing is moving it. */
81
- committed(): T;
82
- /** Writes the committed value. Animations moving the target go on adding to the new one. */
83
- commit(value: T): void;
84
- /** Whether any animation is moving it. */
85
- readonly active: boolean;
86
- /**
87
- * Stops every animation moving it. Each commits where it was, so the value on screen stays,
88
- * unless `commit` is false: then the committed value is left as it stands and the target
89
- * shows it. Pass false after something else has written the committed value mid-flight.
90
- */
91
- stop(opts?: {
92
- commit?: boolean;
93
- }): void;
94
- }
95
- /** Make a {@link Target} over a value the caller owns. */
96
- declare function createTarget<T>(opts: TargetOptions<T>): Target<T>;
97
-
98
- /** Which of a node's two per-anchor color arrays an override applies to. */
99
- type VertexColorChannel = 'fill' | 'stroke';
100
- /** Function-form override: receives the consumer-supplied base color
101
- * array and the current animation timestamp (ms, from the animator's
102
- * clock). Returns a flat RGBA float array (values in 0..1, matching
103
- * the renderer's `stroke.vertexColors` / `PathDrawCommand.vertexColors`
104
- * color space) of the same length as `base`. */
105
- type ColorOverrideFn = (base: readonly number[], tMs: number) => number[];
106
- /** Either a static per-anchor RGBA float array (0..1) or a function-form
107
- * override (see {@link ColorOverrideFn}). */
108
- type ColorOverride = readonly number[] | ColorOverrideFn;
109
- /** Per-node, per-channel store of color overrides. Attached to `useAnimator` as
110
- * `animator.colorOverrides`; painted onto scene nodes by `<SceneCanvas animator>`
111
- * and onto a `createPathLayer`'s nodes by its `colorOverrides` option. */
112
- declare class ColorOverrideRegistry {
113
- private readonly map;
114
- private readonly slots;
115
- private readonly tables;
116
- private _version;
117
- set(id: string, channel: VertexColorChannel, override: ColorOverride): void;
118
- /** Drops `id`'s override on `channel`, and the colors a finished or canceled animation on its
119
- * {@link target} left painted. An animation still running goes on. */
120
- clear(id: string, channel: VertexColorChannel): void;
121
- clearAll(): void;
122
- /** What `set` stored for `id`'s `channel`; failing that, the colors its {@link target} paints. */
123
- get(id: string, channel: VertexColorChannel): ColorOverride | undefined;
124
- /** Whether anything overrides `id`, on either channel. */
125
- has(id: string): boolean;
126
- /**
127
- * The {@link Target} for `id`'s colors on `channel`: `length` numbers, flat RGBA per anchor.
128
- * Every caller for one node and channel gets the same one, so their animations add. The
129
- * registry holds its committed colors and nothing writes the scene.
130
- *
131
- * What it paints: with no override from `set`, its colors in place of the painter's own; over
132
- * one, only what its animations have left to travel, added on top. Ask again for each
133
- * animation rather than keeping it: {@link release} and {@link clear} drop a resting one, and
134
- * the target it had throws from then on.
135
- */
136
- target(id: string, channel: VertexColorChannel, length: number): Target<number[]>;
137
- private tableOf;
138
- private drop;
139
- /** Drops the colors `id`'s {@link target} on `channel` left painted, unless an animation is
140
- * still moving it. An override from `set` stays. */
141
- release(id: string, channel: VertexColorChannel): void;
142
- /**
143
- * The colors to paint on `id`'s `channel`, given the colors the painter would
144
- * otherwise paint and the frame's timestamp. A function override needs that
145
- * `base` and must return an array of its length; failing either, `base`
146
- * stands. A {@link target} in motion then adds what it has left to travel.
147
- */
148
- resolve(id: string, channel: VertexColorChannel, base: readonly number[] | undefined, tMs: number): readonly number[] | undefined;
149
- private apply;
150
- version(): number;
151
- }
152
-
153
- /** One keyframe. `easing` shapes the approach INTO this key from the previous
154
- * one, so the first key's easing is never consulted. */
155
- interface Keyframe<T> {
156
- /** Time within the track's timeline, in ms. */
157
- t: number;
158
- value: T;
159
- /** A function, the name of a built-in, or cubic-bezier control points. */
160
- easing?: EasingSpec;
161
- }
162
- /** A track sampled as a pure function of the playhead. Scrubbing one is free
163
- * and order-independent. Give it `onTick`, a `target`, or both. */
164
- interface SampledTrack<T> {
165
- kind: 'sampled';
166
- label?: string;
167
- /** Sorted ascending by `t`. Of keys sharing a time, the last in the array is
168
- * the value at exactly that time. */
169
- keys: Keyframe<T>[];
170
- /** Required unless the track has a `target`, or every key's value is a number, a number
171
- * array or a plain object of numbers, all of one shape; those are lerped field by field. */
172
- interpolate?: Interpolate<T>;
173
- /** Built once per segment and cached. Takes precedence over `interpolate`. */
174
- interpolator?: InterpolatorFactory<T>;
175
- /** Told each sampled value, at any playhead. Optional beside a `target`. */
176
- onTick?: (value: T) => void;
177
- /**
178
- * A value for the track to move. While the playhead is within the track's keys, the target
179
- * shows the sampled value in place of its committed one, as under `animator.hold`, with
180
- * what an animation on the target shows apart from its destination added on top. Once the playhead is past the last key, or the
181
- * timeline finishes or is canceled, the target keeps the value it was showing; before the
182
- * first key the track leaves the target alone.
183
- *
184
- * With no `interpolate` or `interpolator`, the track is sampled in the target's axes: each
185
- * axis lerps on its own, an angle axis the short way round from the key before, and every
186
- * sample is a value the axes built, a key's own included.
187
- */
188
- target?: Target<T>;
189
- /** What `target` goes by in a clip, for `toClip` to write and a `ClipBinder` to resolve.
190
- * A target has no name of its own. */
191
- targetName?: string;
192
- /** What `interpolate` goes by in a clip, as `targetName` is for `target`. */
193
- interpolateName?: string;
194
- /** The track's share among the target's holds, as `HoldOptions.weight`. Default 1. */
195
- weight?: number | (() => number);
196
- /** What a function `weight` goes by in a clip, as `targetName` is for `target`. */
197
- weightName?: string;
198
- /** The axes of the target the track holds, by name or by index, as `HoldOptions.axes`.
199
- * Default: every axis. A clip carries them as they are written here. */
200
- axes?: readonly AxisRef<T>[];
201
- }
202
- /** A clock that events are booked against, reading in ms. An `AudioEngine`
203
- * from `@weasel-js/audio` is one. */
204
- interface TimelineClock {
205
- now(): number;
206
- }
207
- /** What `book` hands back so the booking can be retracted. A `VoiceHandle` from
208
- * `@weasel-js/audio` is one. */
209
- interface EventBookingHandle {
210
- stop(): void;
211
- }
212
- /** One entry on an `EventTrack`. Give it `fire`, `book`, or both. */
213
- interface TimelineEvent {
214
- /** Time within the track's timeline, in ms. */
215
- t: number;
216
- /** What the event goes by in a clip: a `ClipBinder` turns it and `data` into `fire` and
217
- * `book`. */
218
- name?: string;
219
- /** Carried with `name` into a clip. Anything JSON holds. */
220
- data?: unknown;
221
- /** Runs on the frame that crosses the edge, told how far behind the frame it
222
- * was crossed, in ms — never negative, and measured against `duration` on
223
- * the loop seam, where the outgoing lap's tail fires after the wrap. */
224
- fire?: (lateBy: number) => void;
225
- /** Runs up to `booking.lookahead` before the edge on a timeline with a
226
- * `booking`, once per crossing, with the `booking.clock` time the edge lands
227
- * at — never earlier than that clock's `now()`. A returned handle is stopped
228
- * if a pause, seek, rate change, loop change, edit or cancel invalidates the
229
- * booking before the clock reaches `when`; the event is then booked again
230
- * wherever playback next reaches it. A booking with no handle stands. */
231
- book?: (when: number) => EventBookingHandle | void;
232
- }
233
- /** A track of edge crossings, in forward playback only — a `seek` neither
234
- * fires nor books the span it skips. An event the playhead is sitting on,
235
- * after a seek or at the start, fires when playback next advances from there
236
- * and never while paused. */
237
- interface EventTrack {
238
- kind: 'event';
239
- label?: string;
240
- /** Sorted ascending by `t`. */
241
- events: TimelineEvent[];
242
- }
243
- /** How a timeline books its events against an outside clock. */
244
- interface EventBooking {
245
- clock: TimelineClock;
246
- /** How far ahead of the playhead to book, in clock ms. Default 100. An event
247
- * first reached later than this — after a frame longer than it — books late. */
248
- lookahead?: number;
249
- /** An event first reached more than this many clock ms after its edge is
250
- * skipped instead of booked late. Default `Infinity`. */
251
- maxLate?: number;
252
- }
253
- /** A nested timeline, evaluated at `playhead - at`. Children are NOT registered
254
- * with the animator separately; the parent evaluates them. */
255
- interface TimelineTrack {
256
- kind: 'timeline';
257
- label?: string;
258
- at: number;
259
- timeline: NestedTimeline;
260
- }
261
- /** Any track a timeline can hold. */
262
- type Track = SampledTrack<any> | EventTrack | TimelineTrack;
263
- /** What a child timeline may declare. The parent owns playback, so `loop`,
264
- * `autoplay`, `onDone` and `cancelKey` have no meaning below the root. */
265
- interface NestedTimeline {
266
- tracks: Track[];
267
- /** Defaults to the largest end time across `tracks`. */
268
- duration?: number;
269
- }
270
- /** What `animator.timeline` takes: a root timeline, which owns playback. */
271
- interface TimelineOptions extends NestedTimeline {
272
- /** `true` loops forever, `n` loops n additional times. Default false. */
273
- loop?: boolean | number;
274
- /** Default true. When false the timeline registers but holds at t=0 until resumed. */
275
- autoplay?: boolean;
276
- /** Called when playback reaches the end of its last lap. */
277
- onDone?: () => void;
278
- /** Any new animation passed the same `cancelKey` cancels this one. */
279
- cancelKey?: string;
280
- /** Names this timeline in `animator.watch` events and `animator.live()`. */
281
- label?: string;
282
- /** Books each event's `book` against a clock the timeline does not own, so a
283
- * consumer on that clock lands it at its true sub-frame time. The frame
284
- * clock's mapping onto it is smoothed each frame and resynced on a jump. */
285
- booking?: EventBooking;
286
- }
287
- /** What `animator.timeline` returns: playback control plus live editing. */
288
- interface TimelineHandle extends AnimationHandle {
289
- /** Move the playhead. Fires no event itself, at any depth; an event exactly
290
- * at `t` fires when playback next advances. Sampled tracks are sampled at
291
- * `t` at once, so a target they hold reads the new value before the next frame. */
292
- seek(t: number): void;
293
- /** Change the loop policy. `true` loops forever, `n` allows n more laps,
294
- * `false` stops at `duration`. Sets policy only — a timeline already parked
295
- * at `duration` does not restart, because `rearm` declines to revive one.
296
- * Rewind it with `seek(0)` and `resume()` to play it again. */
297
- setLoop(loop: boolean | number): void;
298
- /** The loop policy as it now stands: `true` endless, `false` stopping at
299
- * `duration`, `n` for n laps still allowed. A finite count falls as laps
300
- * are consumed, matching what `setLoop` takes. */
301
- loop(): boolean | number;
302
- /** Current playhead in ms. */
303
- time(): number;
304
- duration(): number;
305
- tracks(): readonly Track[];
306
- /** Run `fn`, then recompute duration, drop cached interpolators, sample the
307
- * tracks again where the playhead stands, and notify.
308
- * Every mutation must go through this — an edited keyframe otherwise keeps
309
- * interpolating toward its old value with no visible error. */
310
- edit(fn: () => void): void;
311
- /** Notified after each `edit`. Returns an unsubscribe. */
312
- subscribe(cb: () => void): () => void;
313
- /** Notified when playback changes other than by time passing: `pause`,
314
- * `resume`, `seek`, `setTimeScale`, `setLoop`, a cancel, and the playhead
315
- * reaching the end. What a view of the playhead listens to, so a change
316
- * made elsewhere reaches it. Returns an unsubscribe. */
317
- subscribePlayback(cb: () => void): () => void;
318
- }
319
-
320
- /** What every animation on a {@link Target} takes. */
321
- interface OnTarget<T> {
322
- /** The value to move. */
323
- target: Target<T>;
324
- /** Told this animation's own value each frame: its destination plus what it has left to travel. */
325
- onTick?: (value: T) => void;
326
- onDone?: () => void;
327
- /** Any new animation passed the same cancelKey cancels the prior one in flight. Leave it off
328
- * to let animations on one target add. */
329
- cancelKey?: string;
330
- /** False to take `cancelKey` without canceling the animations holding it, so it adds to them
331
- * and `cancelKey`, `pauseKey`, and `isActive` reach them all. Default true. */
332
- interrupt?: boolean;
333
- /** Names this animation in {@link AnimatorEvent}s and `animator.live()`. */
334
- label?: string;
335
- }
336
- /** A tween on a {@link Target}. `to` is committed as it starts, and it contributes what is left
337
- * to travel, so it adds to whatever else is moving the target. */
338
- interface TargetTweenOptions<T> extends OnTarget<T> {
339
- to: T;
340
- /** Where its own travel starts. Default: the target's committed value, so the value on screen
341
- * does not move as it starts. */
342
- from?: T;
343
- ms: number;
344
- easing?: EasingSpec;
345
- /** The path from `from` to `to`, where a straight line per axis is not it. */
346
- interpolate?: Interpolate<T>;
347
- /** As `interpolate`, built once at the start. Takes precedence. */
348
- interpolator?: InterpolatorFactory<T>;
349
- }
350
- /** A spring on a {@link Target}. Needs positive stiffness, damping and mass. Interrupting an
351
- * animation on the same target under the same `cancelKey`, it starts at that one's velocity
352
- * unless given its own. */
353
- interface TargetSpringOptions<T> extends OnTarget<T> {
354
- to: T;
355
- /** As {@link TargetTweenOptions.from}. */
356
- from?: T;
357
- /** Initial velocity in T-units per second. */
358
- velocity?: T;
359
- preset?: SpringPresetName;
360
- stiffness?: number;
361
- damping?: number;
362
- mass?: number;
363
- /** Distance from `to` and speed, both in axis units, under which it has come to rest. Default 0.01. */
364
- restThreshold?: number;
365
- }
366
- /** Spring and coast as one animation on a {@link Target}. With `to: null` it coasts on its
367
- * velocity, committing where it is when it stops. */
368
- interface TargetPhysicsOptions<T> extends Omit<TargetSpringOptions<T>, 'to'> {
369
- to?: T | null;
370
- }
371
- /** What `animator.hold` takes. */
372
- interface HoldOptions<T> {
373
- /** The value to hold. */
374
- target: Target<T>;
375
- /** What to show in place of the committed value: a value, or a function read each frame.
376
- * A value is read as the hold starts and again at `touch()`, and costs a frame nothing. */
377
- value: T | (() => T);
378
- /** Its share among the target's holds, 0 to 1: a number, or a function read each frame.
379
- * Default 1. Holds on one target show their weighted average, and whatever their weights
380
- * leave short of 1 is the committed value's. */
381
- weight?: number | (() => number);
382
- /**
383
- * The axes of the target it holds, each by name or by index: a plain object's fields
384
- * (`['y']`), a rig's joints (`['armL', 'foreL']`) or one of a joint's own
385
- * (`['armL.rotation']`), as `target.axisIndexes` resolves them when the hold starts. The
386
- * rest are left to the target's other holds and its committed value, and a release commits
387
- * only these. Default: every axis.
388
- */
389
- axes?: readonly AxisRef<T>[];
390
- /** Any new animation passed the same cancelKey cancels this one. */
391
- cancelKey?: string;
392
- /** Names this hold in {@link AnimatorEvent}s and `animator.live()`. */
393
- label?: string;
394
- /** With `false`, it takes its `cancelKey` without canceling whoever holds it. Default true. */
395
- interrupt?: boolean;
396
- }
397
- /** What `animator.hold` returns. `cancel` commits what the hold was showing, as `release()`
398
- * does; pausing it or scaling its time changes nothing, since it has no clock. */
399
- interface HoldHandle extends AnimationHandle {
400
- /** Says a function-form `value` or `weight` changed outside a frame, so the target shows it
401
- * now rather than at the next frame the animator happens to run. A `value` given as an
402
- * object and then written in place shows only once this is called. */
403
- touch(): void;
404
- /** Ends the hold. By default it commits the value it was showing, so the target stays where
405
- * it is; with `commit: false` the committed value is left alone and the target falls back
406
- * to it. */
407
- release(opts?: {
408
- commit?: boolean;
409
- }): void;
410
- }
411
- /** A coast on a {@link Target}: it commits where it stops. */
412
- interface TargetDecayOptions<T> extends OnTarget<T> {
413
- /** As {@link TargetTweenOptions.from}. */
414
- from?: T;
415
- velocity: T;
416
- /** Per-second velocity multiplier in (0, 1). Default 0.95. */
417
- friction?: number;
418
- /** Speed below which it stops. Default 0.5. */
419
- threshold?: number;
420
- }
421
-
422
- /** A stagger run's own options: the factory form's fourth argument, and part
423
- * of every fluent builder method's options. */
424
- interface StaggerOptions {
425
- /** Cancel-key for the supervising registration. `animator.cancelKey(key)`
426
- * cancels the whole stagger; `animator.isActive(key)` returns true while
427
- * any timer or child is alive. */
428
- cancelKey?: string;
429
- /** Names this stagger in {@link AnimatorEvent}s and `animator.live()`. */
430
- label?: string;
431
- }
432
- /** Per-index delay schedule. Number ⇒ `index * delay` ms. Function ⇒ caller
433
- * decides the absolute delay for each index (e.g. `i => i * i * 30`). */
434
- type StaggerDelay = number | ((index: number) => number);
435
- /** Produces the animation for one staggered item. */
436
- type StaggerFactory<TItem> = (item: TItem, index: number) => AnimationHandle;
437
- /** A `T` value or a function that derives one from the per-item context. Used
438
- * by the fluent builder methods (`.tween`, `.spring`) so each item can
439
- * vary an option (e.g. `to: (_item, i) => (i + 1) * 10`). */
440
- type StaggerPerItem<T, TItem> = T | ((item: TItem, index: number) => T);
441
- /** Options for the stagger builder's `.tween` in its `onTick` form: a tween per item, where
442
- * `from`, `to` and `ms` may each vary by item. `cancelKey` and `label` belong
443
- * to the stagger as a whole, as in {@link StaggerOptions}. */
444
- interface StaggerTweenOptions<T, TItem> extends StaggerOptions {
445
- /** Absent: this form hands values to `onTick`. {@link StaggerTargetTweenOptions} moves targets. */
446
- target?: undefined;
447
- from: StaggerPerItem<T, TItem>;
448
- to: StaggerPerItem<T, TItem>;
449
- ms: StaggerPerItem<number, TItem>;
450
- easing?: EasingSpec;
451
- interpolate?: Interpolate<T>;
452
- interpolator?: InterpolatorFactory<T>;
453
- onTick: (value: T, item: TItem, index: number) => void;
454
- onDone?: (item: TItem, index: number) => void;
455
- }
456
- /** Options for the stagger builder's `.spring` in its `onTick` form: a spring per item, where
457
- * `from`, `to` and `velocity` may each vary by item. */
458
- interface StaggerSpringOptions<T, TItem> extends StaggerOptions, Pick<SpringOptions<T>, 'preset' | 'stiffness' | 'damping' | 'mass' | 'interpolate' | 'add' | 'subtract' | 'scale' | 'magnitude' | 'restThreshold'> {
459
- /** Absent: this form hands values to `onTick`. {@link StaggerTargetSpringOptions} moves targets. */
460
- target?: undefined;
461
- from: StaggerPerItem<T, TItem>;
462
- to: StaggerPerItem<T, TItem>;
463
- velocity?: StaggerPerItem<T, TItem>;
464
- onTick: (value: T, item: TItem, index: number) => void;
465
- onDone?: (item: TItem, index: number) => void;
466
- }
467
- /** What the stagger builder's methods share where each item's animation moves a {@link Target}. */
468
- interface StaggerOnTarget<T, TItem> extends StaggerOptions {
469
- /** The target an item's animation moves: one for them all, or a function of the item.
470
- * Default: the item itself, where the items are targets. */
471
- target?: StaggerPerItem<Target<T>, TItem>;
472
- /** Told an item's animation's own value each frame, as `TargetTweenOptions.onTick` is. */
473
- onTick?: (value: T, item: TItem, index: number) => void;
474
- onDone?: (item: TItem, index: number) => void;
475
- }
476
- /** Options for the stagger builder's `.tween` moving targets: `animator.tween`'s target form
477
- * per item, where `to`, `from` and `ms` may each vary by item. The tweens share no
478
- * `cancelKey`, so each adds to whatever else is moving its target. */
479
- interface StaggerTargetTweenOptions<T, TItem> extends StaggerOnTarget<T, TItem>, Pick<TargetTweenOptions<T>, 'easing' | 'interpolate' | 'interpolator'> {
480
- to: StaggerPerItem<T, TItem>;
481
- from?: StaggerPerItem<T, TItem>;
482
- ms: StaggerPerItem<number, TItem>;
483
- }
484
- /** Options for the stagger builder's `.spring` moving targets: `animator.spring`'s target
485
- * form per item, where `to`, `from` and `velocity` may each vary by item. */
486
- interface StaggerTargetSpringOptions<T, TItem> extends StaggerOnTarget<T, TItem>, Pick<TargetSpringOptions<T>, 'preset' | 'stiffness' | 'damping' | 'mass' | 'restThreshold'> {
487
- to: StaggerPerItem<T, TItem>;
488
- from?: StaggerPerItem<T, TItem>;
489
- velocity?: StaggerPerItem<T, TItem>;
490
- }
491
- /** `.tween`'s options where the items are targets, each moved by its own tween. No options
492
- * fit where they are not. */
493
- type StaggerItemTweenOptions<TItem> = TItem extends Target<infer T> ? StaggerTargetTweenOptions<T, TItem> : never;
494
- /** `.spring`'s options where the items are targets, as {@link StaggerItemTweenOptions}. */
495
- type StaggerItemSpringOptions<TItem> = TItem extends Target<infer T> ? StaggerTargetSpringOptions<T, TItem> : never;
496
- /** Narrows a builder method's target options to the call that names its `target`. */
497
- type Naming = {
498
- target: NonNullable<unknown>;
499
- };
500
- /**
501
- * Fluent form of `Animator.stagger`: pick what to run per item after the
502
- * items and the delay schedule are already fixed.
503
- *
504
- * `.tween` and `.spring` each take three shapes of options. Where the items are targets, each
505
- * item's animation moves the item: `animator.stagger(targets, 80).spring({ to: (t) => ... })`.
506
- * With a `target`, it moves the target that names for the item. With neither, it hands its
507
- * values to `onTick`.
508
- */
509
- interface StaggerBuilder<TItem> {
510
- /** Run an arbitrary per-item factory. */
511
- each(factory: StaggerFactory<TItem>, opts?: StaggerOptions): AnimationHandle;
512
- /** Per-item `animator.tween` with per-item-varying options. */
513
- tween(opts: StaggerItemTweenOptions<TItem>): AnimationHandle;
514
- tween<T>(opts: StaggerTargetTweenOptions<T, TItem> & Naming): AnimationHandle;
515
- tween<T>(opts: StaggerTweenOptions<T, TItem>): AnimationHandle;
516
- /** Per-item `animator.spring` with per-item-varying options. */
517
- spring(opts: StaggerItemSpringOptions<TItem>): AnimationHandle;
518
- spring<T>(opts: StaggerTargetSpringOptions<T, TItem> & Naming): AnimationHandle;
519
- spring<T>(opts: StaggerSpringOptions<T, TItem>): AnimationHandle;
520
- }
521
-
522
- /** Blends two `T` values at eased progress `t`. Called once per frame; see
523
- * {@link InterpolatorFactory} when the blend has setup worth hoisting. */
524
- type Interpolate<T> = (from: T, to: T, t: number) => T;
525
- /** Built ONCE at tween start with (from, to); the returned function is called with `t ∈ [0, 1]`
526
- * each frame. Use for interpolators with expensive setup (color-space conversion, path-string
527
- * parsing) — d3-interpolate's shape exactly. */
528
- type InterpolatorFactory<T> = (from: T, to: T) => (t: number) => T;
529
- /** A running animation. Cancel it, or bend its time — pausing and time-scaling
530
- * act on this animation's own virtual clock, independent of the animator's. */
531
- interface AnimationHandle {
532
- /** Monotonic id assigned by the animator. */
533
- id: number;
534
- /** Cancel this animation. Idempotent — no-op once already finished/canceled. */
535
- cancel(): void;
536
- /** Freeze this animation's virtual clock. Idempotent. */
537
- pause(): void;
538
- /** Resume this animation's virtual clock. Idempotent. */
539
- resume(): void;
540
- /** Multiply this animation's virtual-clock rate by `scale`, 0 or above. 1 = normal. */
541
- setTimeScale(scale: number): void;
542
- /** This animation's own time scale. 1 once it has finished, since the
543
- * animator no longer holds an entry to read. */
544
- timeScale(): number;
545
- /** True iff this handle is currently paused. */
546
- isPaused(): boolean;
547
- }
548
- /** A duration-based animation from `from` to `to` over `ms`, shaped by an
549
- * easing curve. Reach for a spring instead when the motion should respond to
550
- * where the value already is rather than restart from a fixed duration. */
551
- interface TweenOptions<T> {
552
- /** Absent: this form hands values to `onTick`. The `Target` form of these options moves a target. */
553
- target?: undefined;
554
- from: T;
555
- to: T;
556
- ms: number;
557
- easing?: EasingSpec;
558
- /** Required when T is not `number`. For T = number, defaults to linear numeric lerp. */
559
- interpolate?: Interpolate<T>;
560
- /** Factory interpolator built once at tween start. Takes precedence over `interpolate`
561
- * when both are provided. */
562
- interpolator?: InterpolatorFactory<T>;
563
- onTick: (value: T) => void;
564
- onDone?: () => void;
565
- /** Any new animation passed the same cancelKey cancels the prior one in flight. */
566
- cancelKey?: string;
567
- /** Names this animation in {@link AnimatorEvent}s and `animator.live()`. */
568
- label?: string;
569
- }
570
- /** A spring animation: runs until the value settles on `to` rather than for a
571
- * set duration, so it absorbs an initial velocity naturally. Non-numeric `T`
572
- * needs the four vector helpers. */
573
- interface SpringOptions<T> {
574
- /** Absent: this form hands values to `onTick`. The `Target` form of these options moves a target. */
575
- target?: undefined;
576
- from: T;
577
- to: T;
578
- /** Initial velocity in T-units per second. Default: zero (T-shape-aware). */
579
- velocity?: T;
580
- preset?: SpringPresetName;
581
- stiffness?: number;
582
- damping?: number;
583
- mass?: number;
584
- interpolate?: Interpolate<T>;
585
- /** Vector helpers — required for non-numeric T. When `from`, `to` and `velocity` are numbers, number
586
- * arrays or plain objects of numeric fields of one shape, and stiffness, damping and mass are
587
- * positive, the motion is solved in closed form and these only decide when it has come to rest —
588
- * a `subtract` that wraps an angle won't change the path. */
589
- add?: (a: T, b: T) => T;
590
- subtract?: (a: T, b: T) => T;
591
- scale?: (v: T, k: number) => T;
592
- magnitude?: (v: T) => number;
593
- /** Velocity magnitude below which the spring is considered settled. Default 0.01. */
594
- restThreshold?: number;
595
- onTick: (value: T) => void;
596
- onDone?: () => void;
597
- cancelKey?: string;
598
- /** Names this animation in {@link AnimatorEvent}s and `animator.live()`. */
599
- label?: string;
600
- }
601
- /** Spring and decay as one animation. With a `to`, a spring pulls toward it;
602
- * with `to: null`, the value coasts on its velocity. Either can become the
603
- * other mid-flight through the handle. */
604
- interface PhysicsOptions<T> {
605
- /** Absent: this form hands values to `onTick`. The `Target` form of these options moves a target. */
606
- target?: undefined;
607
- from: T;
608
- /** Target. `null` ⇒ no spring force (decay-mode). */
609
- to?: T | null;
610
- /** Initial velocity in T-units per second. */
611
- velocity?: T;
612
- preset?: SpringPresetName;
613
- stiffness?: number;
614
- damping?: number;
615
- mass?: number;
616
- restThreshold?: number;
617
- /** Vector helpers — required for non-numeric T. When `from`, `to` and `velocity` are numbers, number
618
- * arrays or plain objects of numeric fields of one shape, and stiffness, damping and mass are
619
- * positive, the motion is solved in closed form and these only decide when it has come to rest —
620
- * a `subtract` that wraps an angle won't change the path. */
621
- add?: (a: T, b: T) => T;
622
- subtract?: (a: T, b: T) => T;
623
- scale?: (v: T, k: number) => T;
624
- magnitude?: (v: T) => number;
625
- onTick: (value: T) => void;
626
- onDone?: () => void;
627
- cancelKey?: string;
628
- /** Names this animation in {@link AnimatorEvent}s and `animator.live()`. */
629
- label?: string;
630
- }
631
- /** An `AnimationHandle` that can also be steered while it runs — the point of
632
- * the physics primitive. */
633
- interface PhysicsHandle<T = unknown> extends AnimationHandle {
634
- /** Retarget mid-flight. `null` ⇒ switch to decay-mode (no spring force). */
635
- setTarget(to: T | null): void;
636
- /** Replace the current velocity in T-units per second. */
637
- setVelocity(v: T): void;
638
- }
639
- /** Momentum: coast from `from` at `velocity`, slowing by `friction` each
640
- * second until below `threshold`. What a flick-to-pan leaves behind. */
641
- interface DecayOptions<T> {
642
- /** Absent: this form hands values to `onTick`. The `Target` form of these options moves a target. */
643
- target?: undefined;
644
- from: T;
645
- velocity: T;
646
- /** Per-second velocity multiplier in (0, 1). Default 0.95. */
647
- friction?: number;
648
- /** Velocity magnitude below which decay stops. Default 0.5. */
649
- threshold?: number;
650
- /** When `from` and `velocity` are numbers, number arrays or plain objects of numeric fields of one
651
- * shape and `friction` is below 1, the motion is solved in closed form: `add` and `scale` go
652
- * unused and `magnitude` only decides when it has come to rest. */
653
- add: (a: T, b: T) => T;
654
- scale: (v: T, k: number) => T;
655
- magnitude: (v: T) => number;
656
- onTick: (value: T) => void;
657
- onDone?: () => void;
658
- cancelKey?: string;
659
- /** Names this animation in {@link AnimatorEvent}s and `animator.live()`. */
660
- label?: string;
661
- }
662
- /** Options for `useAnimator`. Everything here is an injection seam for tests;
663
- * the defaults are the real clock and rAF. */
664
- interface UseAnimatorOptions {
665
- /** Optional clock injection for tests. Returns ms since some epoch. */
666
- now?: () => number;
667
- /** Optional rAF / cAF injection for tests. Defaults to window.requestAnimationFrame. */
668
- requestFrame?: (cb: (t: number) => void) => number;
669
- cancelFrame?: (handle: number) => void;
670
- }
671
- /**
672
- * Owns every running animation on a canvas and drives them from one rAF loop.
673
- * Beyond the primitives (`tween`, `spring`, `decay`, `physics`) it offers
674
- * composition — `loop`, `stagger` — and bulk control by handle, by cancel-key,
675
- * or over everything at once.
676
- *
677
- * An animator does not know about the scene. An animation either reports values
678
- * through `onTick` and the caller decides what to do with them, or moves a
679
- * {@link Target}, where several on one target add.
680
- */
681
- interface Animator {
682
- tween<T>(opts: TweenOptions<T> | TargetTweenOptions<T>): AnimationHandle;
683
- spring<T>(opts: SpringOptions<T> | TargetSpringOptions<T>): AnimationHandle;
684
- decay<T>(opts: DecayOptions<T> | TargetDecayOptions<T>): AnimationHandle;
685
- /** With `to` set, behaves as a spring; with `to: null`, as a velocity-driven decay.
686
- * Retarget mid-flight via the returned handle's `setTarget`. */
687
- physics<T>(opts: PhysicsOptions<T> | TargetPhysicsOptions<T>): PhysicsHandle<T>;
688
- /** Shows a value on a {@link Target} in place of its committed one until canceled or released.
689
- * It covers an animation's move to a destination; a coast, push, or `from` offset adds on top. */
690
- hold<T>(opts: HoldOptions<T>): HoldHandle;
691
- /** Cancel a specific animation by handle. Pose stays at current value (no jump). */
692
- cancel(handle: AnimationHandle): void;
693
- /** Cancel every animation currently active under `key`. */
694
- cancelKey(key: string): void;
695
- /** Cancel everything. Useful from a destructor or "reset scene" path. */
696
- cancelAll(): void;
697
- /** True iff at least one animation is active. With `key`, scoped to that cancelKey. */
698
- isActive(key?: string): boolean;
699
- /**
700
- * True while the animator is executing an animation tick. Lets an adapter wrapper detect a
701
- * `setPose` called from inside another animation's onTick and avoid scheduling a new
702
- * animation that would fight the caller.
703
- */
704
- isTicking(): boolean;
705
- /** Freeze every animation managed by this animator. */
706
- pause(): void;
707
- /** Resume every animation managed by this animator. */
708
- resume(): void;
709
- /** True iff the animator is currently globally paused. */
710
- isPaused(): boolean;
711
- /** Multiply every animation's virtual-clock rate by `scale`, 0 or above. 1 = normal. */
712
- setTimeScale(scale: number): void;
713
- /** The global time scale. Per-animation scales multiply on top of it. */
714
- timeScale(): number;
715
- /** Freeze every animation whose `cancelKey` matches. */
716
- pauseKey(key: string): void;
717
- /** Resume every animation whose `cancelKey` matches. */
718
- resumeKey(key: string): void;
719
- /** Set per-animation timeScale for every animation whose `cancelKey` matches. */
720
- setTimeScaleByKey(key: string, scale: number): void;
721
- /**
722
- * Repeatedly invokes `factory` to produce a child animation. The factory must wire its
723
- * returned handle's `onDone` to call `next` so the loop advances. The returned handle's
724
- * pause/resume/setTimeScale/cancel delegate to the in-flight child, and
725
- * `animator.cancel(handle)`, `animator.cancelKey(opts.cancelKey)`, and
726
- * `animator.isActive(opts.cancelKey)` all work for it.
727
- */
728
- loop(factory: LoopFactory, opts?: LoopOptions): AnimationHandle;
729
- /** Sugar over `loop`: a tween between two values, repeated per `direction`. Registered
730
- * with the animator like `loop`. */
731
- tweenLoop<T>(opts: TweenLoopOptions<T>): AnimationHandle;
732
- /**
733
- * Schedules a per-item animation, offset by `delay` ms per index (or a custom function of
734
- * the index). Pass `factory` and get a composite `AnimationHandle`; omit it and get a
735
- * `StaggerBuilder` for fluent `.each` / `.tween` / `.spring` calls, the last two of which
736
- * move the items themselves where they are targets.
737
- *
738
- * The composite handle's `cancel` cancels the items still waiting AND the in-flight
739
- * children. The delays run on the animator's clock, not the wall's: a pause or a time
740
- * scale holds or stretches the waiting items along with the children, and a hidden tab
741
- * holds both. `animator.cancel(handle)`, `animator.cancelKey(opts.cancelKey)`, and
742
- * `animator.isActive(opts.cancelKey)` all work for it.
743
- */
744
- stagger<TItem>(items: readonly TItem[], delay: StaggerDelay): StaggerBuilder<TItem>;
745
- stagger<TItem>(items: readonly TItem[], delay: StaggerDelay, factory: StaggerFactory<TItem>, opts?: StaggerOptions): AnimationHandle;
746
- /**
747
- * Keyframe timeline. Registered like any other animation, so its playhead
748
- * responds to `pause`, `setTimeScale` and `cancelKey`. Sampled tracks are a
749
- * pure function of the playhead; event tracks fire only on forward playback.
750
- */
751
- timeline(opts: TimelineOptions): TimelineHandle;
752
- /** Per-node, per-channel color override registry, painted onto scene nodes by
753
- * `<SceneCanvas animator>` and read by `createPathLayer`. Only this animator can move its
754
- * per-node targets. Cleared automatically on animator unmount. */
755
- colorOverrides: ColorOverrideRegistry;
756
- /**
757
- * Subscribe to a callback fired once per RAF frame while any animation is active; returns
758
- * an unsubscribe. For consumers that repaint from a non-scene channel such as
759
- * `colorOverrides`, whose writes do not trigger a repaint the way scene mutations do.
760
- * Fires AFTER the frame's animations have ticked.
761
- */
762
- onTick(cb: () => void): () => void;
763
- /**
764
- * Keeps the animator's RAF loop running until the returned cancel function is called. For
765
- * effects read on every frame that have no progress state of their own; without it the
766
- * loop would idle and `onTick` would stop firing.
767
- */
768
- keepAlive(): () => void;
769
- /**
770
- * Subscribe to the lifecycle of every animation this animator runs, the
771
- * composites and timelines included. Returns an unsubscribe. Events arrive
772
- * synchronously, as each thing happens — see {@link AnimatorEvent} for the
773
- * order. With no listener attached nothing is built or delivered, so an
774
- * unwatched animator pays nothing for this.
775
- */
776
- watch(listener: AnimatorListener): () => void;
777
- /** What is running right now, in registration order: a fresh snapshot per
778
- * call, for a debug overlay to draw. */
779
- live(): LiveAnimation[];
780
- }
781
- /** Which animator call started an animation. A loop, tween loop or stagger is
782
- * an entry of its own beside the children it runs; `keepAlive` holds the
783
- * frame loop open and animates nothing. */
784
- type AnimationKind = 'tween' | 'spring' | 'decay' | 'physics' | 'timeline' | 'loop' | 'tweenLoop' | 'stagger' | 'keepAlive' | 'hold';
785
- /** Who an {@link AnimatorEvent} is about. One object per registration, so the
786
- * same animation's events share it by identity. */
787
- interface AnimationInfo {
788
- /** The id on the animation's handle. */
789
- readonly id: number;
790
- readonly kind: AnimationKind;
791
- /** The animation's `cancelKey`. Pose helpers key by node, as `pose:<id>`. */
792
- readonly key?: string;
793
- /** The animation's `label` option. */
794
- readonly label?: string;
795
- }
796
- /** One row of `animator.live()`. */
797
- interface LiveAnimation extends AnimationInfo {
798
- /** Paused on its own handle. The animator-wide pause is `animator.isPaused()`. */
799
- readonly paused: boolean;
800
- /** Its own time scale; the animator's multiplies on top. */
801
- readonly timeScale: number;
802
- /** Virtual ms its clock has advanced since it started. */
803
- readonly elapsed: number;
804
- /** 0 to 1, for a tween or a timeline (the playhead over its duration).
805
- * Absent where there is no end to measure against: physics, composites. */
806
- readonly progress?: number;
807
- }
808
- /**
809
- * One thing happening to an animation, as `animator.watch` delivers it.
810
- *
811
- * - `start` — registered. A finished timeline that `seek` or `edit` revives
812
- * starts again, under the same id.
813
- * - `end` — finished on its own. Delivered once every animation has ticked
814
- * that frame, in registration order.
815
- * - `cancel` — stopped by its handle, `cancel`, `cancelKey` or `cancelAll`.
816
- * - `interrupt` — stopped because `by` claimed its `cancelKey`. Delivered
817
- * before `by`'s `start`.
818
- * - `error` — its tick threw (an `onTick`, `onDone` or interpolator), so it was
819
- * taken off the table, after the frame's other animations ticked. In place of
820
- * `cancel`, or after `end` when `onDone` threw. The error is also logged.
821
- * - `lap` — a looping timeline wrapped; `lap` counts wraps since it started.
822
- * - `fire` — an event on a timeline's event track was crossed, at any depth.
823
- * `path` indexes from the root timeline's `tracks()` down through each
824
- * nested timeline to the event track. Delivered after the event's own `fire`.
825
- */
826
- type AnimatorEvent = {
827
- readonly type: 'start' | 'end' | 'cancel';
828
- readonly animation: AnimationInfo;
829
- } | {
830
- readonly type: 'interrupt';
831
- readonly animation: AnimationInfo;
832
- readonly by: AnimationInfo;
833
- } | {
834
- readonly type: 'error';
835
- readonly animation: AnimationInfo;
836
- readonly error: unknown;
837
- } | {
838
- readonly type: 'lap';
839
- readonly animation: AnimationInfo;
840
- readonly lap: number;
841
- } | {
842
- readonly type: 'fire';
843
- readonly animation: AnimationInfo;
844
- readonly track: EventTrack;
845
- readonly path: readonly number[];
846
- readonly event: TimelineEvent;
847
- /** As the event's own `fire` is told: ms behind the frame it was crossed. */
848
- readonly lateBy: number;
849
- };
850
- /** Receives what `animator.watch` delivers. */
851
- type AnimatorListener = (event: AnimatorEvent) => void;
852
- /** Options for `Animator.loop`. */
853
- interface LoopOptions {
854
- /** Maximum number of iterations. Default Infinity. */
855
- count?: number;
856
- /** Invoked when the loop reaches `count` iterations naturally (not on cancel). */
857
- onDone?: () => void;
858
- /** Any new animation passed the same cancelKey cancels the prior one in flight.
859
- * Also enables `animator.cancelKey` / `animator.isActive(key)` for this loop. */
860
- cancelKey?: string;
861
- /** Names this loop in {@link AnimatorEvent}s and `animator.live()`. */
862
- label?: string;
863
- }
864
- /** Produces one iteration of a loop. Must arrange for `next` to be called when
865
- * the animation it returns finishes, or the loop stalls after one pass. */
866
- type LoopFactory = (iteration: number, next: () => void) => AnimationHandle;
867
- /** Options for `Animator.tweenLoop` — a tween's options plus how each
868
- * iteration relates to the last. */
869
- interface TweenLoopOptions<T> {
870
- from: T;
871
- to: T;
872
- ms: number;
873
- easing?: EasingSpec;
874
- /** `restart` (default): from→to every iteration.
875
- * `reverse`: to→from every iteration.
876
- * `alternate`: even iterations from→to, odd iterations to→from. */
877
- direction?: 'restart' | 'reverse' | 'alternate';
878
- count?: number;
879
- interpolate?: Interpolate<T>;
880
- onTick: (value: T) => void;
881
- onDone?: () => void;
882
- cancelKey?: string;
883
- /** Names this animation in {@link AnimatorEvent}s and `animator.live()`. */
884
- label?: string;
885
- }
886
-
887
- /** Create the animator for a canvas. One rAF loop drives every animation it
888
- * owns, and everything still running is canceled on unmount. */
889
- declare function useAnimator(opts?: UseAnimatorOptions): Animator;
890
-
891
- /** The arrays a table can keep its rows' values on screen in. */
892
- type ShownArray = Float64Array | Float32Array;
893
- /** What {@link createTargetTable} takes. */
894
- interface TargetTableOptions<S extends ShownArray = Float64Array> {
895
- /** How many numbers a row holds. */
896
- axes: number;
897
- /** The kind of array to keep `shown` in. Default `Float64Array`. Pass `Float32Array` for a
898
- * painter that uploads it: the table then fills that each frame, and no copy is made. */
899
- shown?: new (length: number) => S;
900
- /** Rows to make room for at first. The table grows past it. Default 64. */
901
- capacity?: number;
902
- /** Called after `row` is committed: by `set`, by an animation starting on it, and by one
903
- * canceled on it. */
904
- set?(row: number): void;
905
- /** Called once a frame, after the animator has filled `shown` for the rows it is moving. */
906
- show?(): void;
907
- }
908
- /**
909
- * Many like values an animator can move, kept as rows of numbers in flat arrays: for thousands
910
- * of particles, dots, or vertex colors, where a `Target` apiece costs a read apiece. Each row
911
- * is a target (`target(row)`), so it tweens, springs, coasts, and holds like any other, and
912
- * every row's value on screen is in `shown` after each frame, with no call per row.
913
- */
914
- interface TargetTable<S extends ShownArray = Float64Array> {
915
- readonly axes: number;
916
- /** How many rows are in use. */
917
- readonly size: number;
918
- /** Every row's committed value, row `r` at `r * axes`. A new array once the table grows, so
919
- * read it from the table each time. Write a row through `set`. */
920
- readonly committed: Float64Array;
921
- /** Every row's value on screen, laid out as `committed`: current after each frame of the
922
- * animator moving the rows, and whenever it is read between frames. A new array once the
923
- * table grows. A `Float32Array` where the table was made with `shown: Float32Array`. */
924
- readonly shown: S;
925
- /** Adds a row at `value` and answers its index, which a removed row's index is reused for. */
926
- add(value: ArrayLike<number>): number;
927
- /** Stops whatever is moving `row` and frees it. Its target is dead from here: a row added
928
- * later may take the index, and gets a target of its own. */
929
- remove(row: number): void;
930
- /** Commits `value` to `row`. A row that is moving keeps what its animations have left on top. */
931
- set(row: number, value: ArrayLike<number>): void;
932
- /** Row `row` as a target, the same one on every call. */
933
- target(row: number): Target<number[]>;
934
- }
935
- /** Make a {@link TargetTable} whose rows each hold `axes` numbers. */
936
- declare function createTargetTable<S extends ShownArray = Float64Array>(opts: TargetTableOptions<S>): TargetTable<S>;
4
+ import { SpringPresetName, EasingSpec, EasingName, BezierEasing, GlMat3, Path, PolygonPath } from '@weasel-js/geom';
5
+ export { BezierEasing, EasingFn, EasingSpec, SpringPreset, SpringPresetName } from '@weasel-js/geom';
937
6
 
938
7
  /** How a value maps to the flat numbers blits moves, and back. */
939
8
  interface Axes<T> {
@@ -1122,11 +191,11 @@ declare function solidVertexColors(n: number, r: number, g: number, b: number, a
1122
191
  */
1123
192
  declare function sampleTrack<T>(track: SampledTrack<T>, t: number, segmentCache?: Map<number, (u: number) => T>): T | undefined;
1124
193
 
1125
- /** A value a clip can hold: what `JSON.stringify` writes and `JSON.parse` reads back. An
1126
- * object's `undefined` members are left out, as JSON leaves them. */
1127
- type ClipValue = number | string | boolean | null | ClipValue[] | {
1128
- [key: string]: ClipValue | undefined;
1129
- };
194
+ /** A value a clip can hold: what `JSON.stringify` writes and `JSON.parse` reads back. The
195
+ * object arm is any object, so a pose typed by an interface is one; `toClip` is what refuses
196
+ * a member JSON cannot round-trip. An object's `undefined` members are left out, as JSON
197
+ * leaves them. */
198
+ type ClipValue = number | string | boolean | null | ClipValue[] | object;
1130
199
  /** A keyframe as data. Its easing is a built-in's name or bezier control points. */
1131
200
  interface ClipKey {
1132
201
  t: number;
@@ -1412,4 +481,4 @@ declare function setWeights(skin: Skin, count: number, joint: string, weights: R
1412
481
  */
1413
482
  declare function brushWeights(coords: ArrayLike<number>, x: number, y: number, radius: number, current: readonly number[] | undefined, mode: 'add' | 'remove'): Map<number, number>;
1414
483
 
1415
- export { type AnimationHandle, type AnimationInfo, type AnimationKind, type Animator, type AnimatorEvent, type AnimatorListener, type AutoSkinOptions, type Axes, type AxisBuffer, type AxisName, type AxisRef, type Clip, type ClipBinder, type ClipEventTrack, type ClipKey, type ClipSampledTrack, type ClipTimeline, type ClipTimelineTrack, type ClipTrack, type ClipValue, type ColorInterpolate, type ColorOverride, type ColorOverrideFn, ColorOverrideRegistry, type CycleHandle, type CycleVertexColorsOptions, type DecayOptions, type EventBooking, type EventBookingHandle, type EventTrack, type HoldHandle, type HoldOptions, IDENTITY_JOINT, type IkLimit, type IkPoint, type IkResult, type Interpolate, type InterpolatorFactory, type Joint, type JointTransform, type Keyframe, type LiveAnimation, type LoopFactory, type LoopOptions, type Naming, type NestedTimeline, type PhysicsHandle, type PhysicsOptions, type Pose, type SampledTrack, type ShownArray, type Skeleton, type Skin, type Slew, type SlewRates, type SolveIkOptions, type SpringOptions, type SpringVertexColorsOptions, type StaggerBuilder, type StaggerDelay, type StaggerFactory, type StaggerItemSpringOptions, type StaggerItemTweenOptions, type StaggerOptions, type StaggerPerItem, type StaggerSpringOptions, type StaggerTargetSpringOptions, type StaggerTargetTweenOptions, type StaggerTweenOptions, type StaggerVertexColorsOptions, type Target, type TargetAxes, type TargetDecayOptions, type TargetOptions, type TargetPhysicsOptions, type TargetSpringOptions, type TargetTable, type TargetTableOptions, type TargetTweenOptions, type TimelineClock, type TimelineEvent, type TimelineHandle, type TimelineOptions, type TimelineTrack, type Track, type TweenLoopOptions, type TweenOptions, type TweenVertexColorsOptions, type UseAnimatorOptions, type VertexColorChannel, addJoint, autoSkin, axesOf, bindClip, brushWeights, createSlew, createTarget, createTargetTable, cycleVertexColors, dropSkinJoints, jointAt, jointAxes, jointPositions, mirrorPose, motionsFromRest, moveJoint, rainbowVertexColors, removeJoint, resolveSkeleton, sampleTrack, setWeights, skeletonAxes, skinPath, skinnable, slewToward, solidVertexColors, solveIk, springVertexColors, staggerVertexColors, toClip, tweenVertexColors, useAnimator };
484
+ export { AnimationHandle, Animator, type AutoSkinOptions, type Axes, type Clip, type ClipBinder, type ClipEventTrack, type ClipKey, type ClipSampledTrack, type ClipTimeline, type ClipTimelineTrack, type ClipTrack, type ClipValue, type ColorInterpolate, type CycleHandle, type CycleVertexColorsOptions, IDENTITY_JOINT, type IkLimit, type IkPoint, type IkResult, Interpolate, type Joint, type JointTransform, NestedTimeline, type Pose, SampledTrack, type Skeleton, type Skin, type Slew, type SlewRates, type SolveIkOptions, type SpringVertexColorsOptions, type StaggerVertexColorsOptions, Target, TargetAxes, TimelineEvent, type TweenVertexColorsOptions, VertexColorChannel, addJoint, autoSkin, axesOf, bindClip, brushWeights, createSlew, cycleVertexColors, dropSkinJoints, jointAt, jointAxes, jointPositions, mirrorPose, motionsFromRest, moveJoint, rainbowVertexColors, removeJoint, resolveSkeleton, sampleTrack, setWeights, skeletonAxes, skinPath, skinnable, slewToward, solidVertexColors, solveIk, springVertexColors, staggerVertexColors, toClip, tweenVertexColors };