@weasel-js/animator 0.0.0-stage → 1.10.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/LICENSE +21 -0
- package/README.md +55 -2
- package/dist/index.d.ts +1415 -0
- package/dist/index.js +4015 -0
- package/dist/index.js.map +1 -0
- package/package.json +51 -4
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,1415 @@
|
|
|
1
|
+
import { EasingSpec, SpringPresetName, EasingName, BezierEasing, GlMat3, Path, PolygonPath } from '@weasel-js/geom';
|
|
2
|
+
export { BezierEasing, EasingFn, EasingSpec, SpringPreset, SpringPresetName } from '@weasel-js/geom';
|
|
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>;
|
|
937
|
+
|
|
938
|
+
/** How a value maps to the flat numbers blits moves, and back. */
|
|
939
|
+
interface Axes<T> {
|
|
940
|
+
count: number;
|
|
941
|
+
/** Equal for two values exactly when their axes line up one for one. */
|
|
942
|
+
shape: string;
|
|
943
|
+
/** A name for each axis where the value has them: a plain object's fields. */
|
|
944
|
+
names?: readonly string[];
|
|
945
|
+
to(v: T): number[];
|
|
946
|
+
/** The value whose `count` axes start at `at` in `a`. */
|
|
947
|
+
from(a: ArrayLike<number>, at?: number): T;
|
|
948
|
+
/** `v` with `delta` added axis by axis. */
|
|
949
|
+
add(v: T, delta: ArrayLike<number>): T;
|
|
950
|
+
/** Puts `v`'s axes into `out` from `at`. */
|
|
951
|
+
write(v: T, out: Float64Array | Float32Array | number[], at: number): void;
|
|
952
|
+
}
|
|
953
|
+
/** The axes of `sample`'s shape: a number, a plain array of numbers, or a plain object whose
|
|
954
|
+
* fields are all numbers. Null for any other shape, which blits cannot move. */
|
|
955
|
+
declare function axesOf<T>(sample: T): Axes<T> | null;
|
|
956
|
+
|
|
957
|
+
/** Most a slewed value may change per second, in its own units, in each
|
|
958
|
+
* direction. A direction left out is unlimited: the value jumps to a target
|
|
959
|
+
* on that side. `0` holds the value where it is. */
|
|
960
|
+
interface SlewRates {
|
|
961
|
+
rise?: number;
|
|
962
|
+
fall?: number;
|
|
963
|
+
}
|
|
964
|
+
/**
|
|
965
|
+
* One step of a slew limiter: `value` moved toward `target` by at most the
|
|
966
|
+
* rate for that direction times `dt` seconds, landing on `target` rather than
|
|
967
|
+
* passing it. A fast `rise` with a slow `fall` is an attack/release envelope.
|
|
968
|
+
*/
|
|
969
|
+
declare function slewToward(value: number, target: number, dt: number, rates: SlewRates): number;
|
|
970
|
+
/** A value that follows `target` at limited rates. Both fields are writable:
|
|
971
|
+
* set `target` to steer it, or write `value` to jump it and let it slew on
|
|
972
|
+
* from there. Nothing moves until `step` is called. */
|
|
973
|
+
interface Slew {
|
|
974
|
+
value: number;
|
|
975
|
+
target: number;
|
|
976
|
+
/** Advance `dt` seconds and return the new value. */
|
|
977
|
+
step(dt: number): number;
|
|
978
|
+
}
|
|
979
|
+
/** A stateful {@link slewToward}. `target` defaults to `value`, so a new slew
|
|
980
|
+
* is at rest. */
|
|
981
|
+
declare function createSlew(options?: SlewRates & {
|
|
982
|
+
value?: number;
|
|
983
|
+
target?: number;
|
|
984
|
+
}): Slew;
|
|
985
|
+
|
|
986
|
+
/**
|
|
987
|
+
* Color interpolator: receives two flat RGBA float arrays (values in
|
|
988
|
+
* 0..1, the renderer's color space — same shape as
|
|
989
|
+
* `stroke.vertexColors`) and a normalized progress `t` in 0..1.
|
|
990
|
+
* Returns the same-length blended array, also in 0..1 floats. Override
|
|
991
|
+
* the default per-channel lerp via `TweenVertexColorsOptions.interpolate`
|
|
992
|
+
* when a custom color-space or shaping is needed.
|
|
993
|
+
*/
|
|
994
|
+
type ColorInterpolate = (from: readonly number[], to: readonly number[], t: number) => number[];
|
|
995
|
+
|
|
996
|
+
/** Options for `tweenVertexColors`. */
|
|
997
|
+
interface TweenVertexColorsOptions {
|
|
998
|
+
id: string;
|
|
999
|
+
channel: VertexColorChannel;
|
|
1000
|
+
/** Per-anchor RGBA, flat, in 0..1 floats (matches the renderer's
|
|
1001
|
+
* `stroke.vertexColors` / `PathDrawCommand.vertexColors` color space).
|
|
1002
|
+
* Length must equal `from.length`. */
|
|
1003
|
+
to: readonly number[];
|
|
1004
|
+
/** Per-anchor RGBA, flat, in 0..1 floats. Length must equal `to.length`
|
|
1005
|
+
* and be a positive multiple of 4. */
|
|
1006
|
+
from: readonly number[];
|
|
1007
|
+
ms: number;
|
|
1008
|
+
easing?: EasingSpec;
|
|
1009
|
+
interpolation?: ColorSpace;
|
|
1010
|
+
interpolate?: ColorInterpolate;
|
|
1011
|
+
onDone?: () => void;
|
|
1012
|
+
}
|
|
1013
|
+
/**
|
|
1014
|
+
* Animate one node's per-anchor colors from `from` to `to` over `ms`.
|
|
1015
|
+
*
|
|
1016
|
+
* It moves the node's color target (`animator.colorOverrides.target`) rather
|
|
1017
|
+
* than writing the scene, so nothing is recorded in history and the node's own
|
|
1018
|
+
* data is untouched. Another tween or stagger on the same node and channel adds
|
|
1019
|
+
* to this one; a spring interrupts it. What it painted is dropped when the last
|
|
1020
|
+
* animation on the node and channel finishes, and held where it was if canceled
|
|
1021
|
+
* until `animator.colorOverrides.clear`.
|
|
1022
|
+
*/
|
|
1023
|
+
declare function tweenVertexColors(animator: Animator, opts: TweenVertexColorsOptions): AnimationHandle;
|
|
1024
|
+
/** Options for `springVertexColors`. */
|
|
1025
|
+
interface SpringVertexColorsOptions {
|
|
1026
|
+
id: string;
|
|
1027
|
+
channel: VertexColorChannel;
|
|
1028
|
+
/** Per-anchor RGBA in 0..1 floats. See `TweenVertexColorsOptions.to`. */
|
|
1029
|
+
to: readonly number[];
|
|
1030
|
+
/** Per-anchor RGBA in 0..1 floats. See `TweenVertexColorsOptions.from`. */
|
|
1031
|
+
from: readonly number[];
|
|
1032
|
+
preset?: SpringPresetName;
|
|
1033
|
+
stiffness?: number;
|
|
1034
|
+
damping?: number;
|
|
1035
|
+
mass?: number;
|
|
1036
|
+
onDone?: () => void;
|
|
1037
|
+
}
|
|
1038
|
+
/**
|
|
1039
|
+
* `tweenVertexColors` driven by a spring instead of a duration. Each number
|
|
1040
|
+
* springs on its own, so an underdamped spring overshoots `to` and the path is
|
|
1041
|
+
* a straight line in RGB.
|
|
1042
|
+
*
|
|
1043
|
+
* It interrupts whatever is animating the node and channel, and starts at the
|
|
1044
|
+
* velocity of the one it interrupts, so retargeting mid-flight does not stall.
|
|
1045
|
+
*/
|
|
1046
|
+
declare function springVertexColors(animator: Animator, opts: SpringVertexColorsOptions): AnimationHandle;
|
|
1047
|
+
/** Options for `staggerVertexColors`. `origin` picks which anchor the wave
|
|
1048
|
+
* starts from and `perAnchorDelay` how far behind each successive anchor
|
|
1049
|
+
* runs. */
|
|
1050
|
+
interface StaggerVertexColorsOptions {
|
|
1051
|
+
id: string;
|
|
1052
|
+
channel: VertexColorChannel;
|
|
1053
|
+
/** Per-anchor RGBA in 0..1 floats. See `TweenVertexColorsOptions.to`. */
|
|
1054
|
+
to: readonly number[];
|
|
1055
|
+
/** Per-anchor RGBA in 0..1 floats. See `TweenVertexColorsOptions.from`. */
|
|
1056
|
+
from: readonly number[];
|
|
1057
|
+
anchorMs: number;
|
|
1058
|
+
perAnchorDelay: number;
|
|
1059
|
+
origin?: 'first' | 'last' | number;
|
|
1060
|
+
easing?: EasingSpec;
|
|
1061
|
+
interpolation?: ColorSpace;
|
|
1062
|
+
interpolate?: ColorInterpolate;
|
|
1063
|
+
onDone?: () => void;
|
|
1064
|
+
}
|
|
1065
|
+
/** Run the same color change across a node's anchors as a wave, each anchor
|
|
1066
|
+
* starting later than the one before it. It moves the same target as
|
|
1067
|
+
* `tweenVertexColors`, and adds to other animations the same way. */
|
|
1068
|
+
declare function staggerVertexColors(animator: Animator, opts: StaggerVertexColorsOptions): AnimationHandle;
|
|
1069
|
+
|
|
1070
|
+
/** Options for `cycleVertexColors`. */
|
|
1071
|
+
interface CycleVertexColorsOptions {
|
|
1072
|
+
id: string;
|
|
1073
|
+
channel: VertexColorChannel;
|
|
1074
|
+
msPerCycle: number;
|
|
1075
|
+
direction?: 1 | -1;
|
|
1076
|
+
easing?: EasingSpec;
|
|
1077
|
+
interpolation?: ColorSpace;
|
|
1078
|
+
/** Custom interpolator. Receives two RGBA arrays in 0..1 floats and a
|
|
1079
|
+
* progress `t` in 0..1; returns the blended array in 0..1 floats. */
|
|
1080
|
+
interpolate?: ColorInterpolate;
|
|
1081
|
+
}
|
|
1082
|
+
/** Removes an installed color cycle. Unlike the other color helpers this is
|
|
1083
|
+
* not an `AnimationHandle`, because a cycle has no progress to pause or
|
|
1084
|
+
* scale — it only ends. */
|
|
1085
|
+
interface CycleHandle {
|
|
1086
|
+
cancel(): void;
|
|
1087
|
+
}
|
|
1088
|
+
/** Register a function override that phase-rotates the base color array
|
|
1089
|
+
* along the path index. Returns a handle whose `cancel()` removes the
|
|
1090
|
+
* override.
|
|
1091
|
+
*
|
|
1092
|
+
* The override computes its value purely from `performance.now()`, so
|
|
1093
|
+
* there's no per-frame progress to register with the animator's tick
|
|
1094
|
+
* loop. To keep the loop alive (so `<SceneCanvas animator>`'s onTick
|
|
1095
|
+
* subscription continues firing redraws while the cycle is installed),
|
|
1096
|
+
* cycleVertexColors holds an `animator.keepAlive()` entry for the
|
|
1097
|
+
* lifetime of the cycle; `cancel()` releases it. */
|
|
1098
|
+
declare function cycleVertexColors(animator: Animator, opts: CycleVertexColorsOptions): CycleHandle;
|
|
1099
|
+
|
|
1100
|
+
/** Build an n-anchor rainbow RGBA array sweeping the hue wheel. The
|
|
1101
|
+
* output is suitable to pass directly into `stroke.vertexColors`,
|
|
1102
|
+
* `tweenVertexColors({ from: rainbowVertexColors(n) })`, or any
|
|
1103
|
+
* other API that wants per-anchor color floats. */
|
|
1104
|
+
declare function rainbowVertexColors(n: number, opts?: {
|
|
1105
|
+
saturation?: number;
|
|
1106
|
+
lightness?: number;
|
|
1107
|
+
alpha?: number;
|
|
1108
|
+
}): number[];
|
|
1109
|
+
/** Build an n-anchor solid RGBA array. Shorthand for
|
|
1110
|
+
* `[r, g, b, a, r, g, b, a, …]` — the array a `tweenVertexColors`
|
|
1111
|
+
* `to`-target typically needs. */
|
|
1112
|
+
declare function solidVertexColors(n: number, r: number, g: number, b: number, a?: number): number[];
|
|
1113
|
+
|
|
1114
|
+
/**
|
|
1115
|
+
* Sample a track at `t`. Pure: no state, no side effects, safe to call for any
|
|
1116
|
+
* `t` in any order — which is what makes scrubbing free.
|
|
1117
|
+
*
|
|
1118
|
+
* `segmentCache` holds what sampling builds from the keys: the track's blits
|
|
1119
|
+
* patch and its `interpolator` factories. Handed another track or a replaced
|
|
1120
|
+
* `keys` array, it rebuilds; a key edited in place needs the cache dropped,
|
|
1121
|
+
* which `createTimeline` does on `edit`. With no cache, every call builds afresh.
|
|
1122
|
+
*/
|
|
1123
|
+
declare function sampleTrack<T>(track: SampledTrack<T>, t: number, segmentCache?: Map<number, (u: number) => T>): T | undefined;
|
|
1124
|
+
|
|
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
|
+
};
|
|
1130
|
+
/** A keyframe as data. Its easing is a built-in's name or bezier control points. */
|
|
1131
|
+
interface ClipKey {
|
|
1132
|
+
t: number;
|
|
1133
|
+
/** A typed array in the live key's value, as a `Path` has, is held as a `TaggedTypedArray`
|
|
1134
|
+
* from `@weasel-js/geom`: `{ __ta: 'f32', data: [...] }`. `bindClip` makes it the array again. */
|
|
1135
|
+
value: ClipValue;
|
|
1136
|
+
easing?: EasingName | BezierEasing;
|
|
1137
|
+
}
|
|
1138
|
+
/** A `SampledTrack` as data: what it moves and how it interpolates are names. */
|
|
1139
|
+
interface ClipSampledTrack {
|
|
1140
|
+
kind: 'sampled';
|
|
1141
|
+
label?: string;
|
|
1142
|
+
/** Resolved by `ClipBinder.target`. A track with none is sampled and moves nothing. */
|
|
1143
|
+
target?: string;
|
|
1144
|
+
keys: ClipKey[];
|
|
1145
|
+
/** Resolved from `ClipBinder.interpolate`. Without one the track is sampled in its
|
|
1146
|
+
* target's axes, or field by field. */
|
|
1147
|
+
interpolate?: string;
|
|
1148
|
+
/** The track's share of its target: a number, or a name for `ClipBinder.weight` to resolve
|
|
1149
|
+
* into a function read each frame, as a crossfade's is. */
|
|
1150
|
+
weight?: number | string;
|
|
1151
|
+
/** The part of the target the track holds: the target's names for its axes, a rig's joints
|
|
1152
|
+
* among them, or positions in its axes where it has no names. */
|
|
1153
|
+
axes?: number[] | string[];
|
|
1154
|
+
}
|
|
1155
|
+
/** An `EventTrack` as data: each event is a name and what to carry with it. */
|
|
1156
|
+
interface ClipEventTrack {
|
|
1157
|
+
kind: 'event';
|
|
1158
|
+
label?: string;
|
|
1159
|
+
events: {
|
|
1160
|
+
t: number;
|
|
1161
|
+
name: string;
|
|
1162
|
+
data?: ClipValue;
|
|
1163
|
+
}[];
|
|
1164
|
+
}
|
|
1165
|
+
/** A `TimelineTrack` as data. */
|
|
1166
|
+
interface ClipTimelineTrack {
|
|
1167
|
+
kind: 'timeline';
|
|
1168
|
+
label?: string;
|
|
1169
|
+
at: number;
|
|
1170
|
+
timeline: ClipTimeline;
|
|
1171
|
+
}
|
|
1172
|
+
/** Any track a clip can hold. */
|
|
1173
|
+
type ClipTrack = ClipSampledTrack | ClipEventTrack | ClipTimelineTrack;
|
|
1174
|
+
/** A `NestedTimeline` as data. */
|
|
1175
|
+
interface ClipTimeline {
|
|
1176
|
+
tracks: ClipTrack[];
|
|
1177
|
+
duration?: number;
|
|
1178
|
+
}
|
|
1179
|
+
/** A timeline as data: what `JSON.stringify` can write, `bindClip` can play, and `toClip`
|
|
1180
|
+
* can read back off a live timeline. */
|
|
1181
|
+
interface Clip extends ClipTimeline {
|
|
1182
|
+
version: 1;
|
|
1183
|
+
}
|
|
1184
|
+
/** What turns the names in a clip into the live things a timeline plays. */
|
|
1185
|
+
interface ClipBinder {
|
|
1186
|
+
/** The target a sampled track names. */
|
|
1187
|
+
target?(name: string): Target<any> | undefined;
|
|
1188
|
+
/** Interpolations by name. */
|
|
1189
|
+
interpolate?: Readonly<Record<string, Interpolate<any>>>;
|
|
1190
|
+
/** The function a track's named weight stands for. */
|
|
1191
|
+
weight?(name: string): (() => number) | undefined;
|
|
1192
|
+
/** What an event does: its `fire`, its `book`, or both. */
|
|
1193
|
+
event?(name: string, data: ClipValue | undefined): Pick<TimelineEvent, 'fire' | 'book'> | undefined;
|
|
1194
|
+
}
|
|
1195
|
+
/**
|
|
1196
|
+
* The live timeline a clip describes, for `animator.timeline`: each sampled track given the
|
|
1197
|
+
* target and interpolation it names, each event what the binder says it does. The tracks
|
|
1198
|
+
* keep those names, so `toClip` can write them back after an editor has changed them.
|
|
1199
|
+
* Throws on a name the binder does not resolve.
|
|
1200
|
+
*/
|
|
1201
|
+
declare function bindClip(clip: Clip, binder: ClipBinder): NestedTimeline;
|
|
1202
|
+
/**
|
|
1203
|
+
* A live timeline as a clip: `{ tracks, duration }` as `animator.timeline` takes them, or
|
|
1204
|
+
* `{ tracks: handle.tracks() }` off a running one. Each track is written by the names it
|
|
1205
|
+
* carries (`targetName`, `interpolateName`, an event's `name`), which `bindClip` sets and a
|
|
1206
|
+
* track written by hand can set too. A typed array in a key's value is written tagged.
|
|
1207
|
+
* Throws, naming the track, on anything a clip cannot hold: a function with no name, an
|
|
1208
|
+
* `onTick`, or a value JSON would not read back.
|
|
1209
|
+
*/
|
|
1210
|
+
declare function toClip(timeline: NestedTimeline): Clip;
|
|
1211
|
+
|
|
1212
|
+
/** A joint's local transform. Deliberately NOT the scene's generic `TPose`:
|
|
1213
|
+
* `TPose` is consumer-defined and may be a bare AABB with no rotation term,
|
|
1214
|
+
* which a joint chain cannot compose through. */
|
|
1215
|
+
interface JointTransform {
|
|
1216
|
+
x: number;
|
|
1217
|
+
y: number;
|
|
1218
|
+
/** Radians. */
|
|
1219
|
+
rotation: number;
|
|
1220
|
+
scaleX: number;
|
|
1221
|
+
scaleY: number;
|
|
1222
|
+
}
|
|
1223
|
+
/** One joint of a `Skeleton`. */
|
|
1224
|
+
interface Joint {
|
|
1225
|
+
name: string;
|
|
1226
|
+
/** Parent joint name, or null for a root. */
|
|
1227
|
+
parent: string | null;
|
|
1228
|
+
/** Local transform at rest. */
|
|
1229
|
+
bind: JointTransform;
|
|
1230
|
+
}
|
|
1231
|
+
/** Joints in topological order: every joint appears after its parent. */
|
|
1232
|
+
interface Skeleton {
|
|
1233
|
+
joints: Joint[];
|
|
1234
|
+
}
|
|
1235
|
+
/** Local deltas from the bind pose, keyed by joint name. Absent joints and
|
|
1236
|
+
* absent fields mean "no change from bind". */
|
|
1237
|
+
type Pose = Record<string, Partial<JointTransform>>;
|
|
1238
|
+
/** The transform that changes nothing: origin, no rotation, unit scale. */
|
|
1239
|
+
declare const IDENTITY_JOINT: JointTransform;
|
|
1240
|
+
|
|
1241
|
+
/**
|
|
1242
|
+
* `pose` reflected across the rig's y axis, as deltas against the same
|
|
1243
|
+
* skeleton — so the mirrored pose still blends, samples, and resolves like any
|
|
1244
|
+
* other, and a rig faces the other way without a negative scale anywhere.
|
|
1245
|
+
*
|
|
1246
|
+
* Each joint's `x` and `rotation` are negated as bind plus delta, so the delta
|
|
1247
|
+
* for a joint the pose leaves at its bind is nonzero whenever the bind is.
|
|
1248
|
+
* Applying it twice gives the original pose back.
|
|
1249
|
+
*/
|
|
1250
|
+
declare function mirrorPose(skeleton: Skeleton, pose: Pose): Pose;
|
|
1251
|
+
|
|
1252
|
+
/**
|
|
1253
|
+
* Resolve every joint's world transform by walking the skeleton once and
|
|
1254
|
+
* composing each joint onto its already-resolved parent.
|
|
1255
|
+
*
|
|
1256
|
+
* `skeleton.joints` must be in topological order — a joint whose parent has not
|
|
1257
|
+
* been resolved yet throws rather than silently resolving against identity,
|
|
1258
|
+
* because that failure is otherwise invisible until a limb renders in the wrong
|
|
1259
|
+
* place.
|
|
1260
|
+
*/
|
|
1261
|
+
declare function resolveSkeleton(skeleton: Skeleton, pose: Pose): Map<string, GlMat3>;
|
|
1262
|
+
|
|
1263
|
+
/**
|
|
1264
|
+
* The axes of `skeletonAxes(skeleton)` that belong to `joints`, as indexes, for a caller with
|
|
1265
|
+
* a skeleton and no target. A hold or a track on a rig's target takes the joints' names
|
|
1266
|
+
* themselves: `animator.hold({ target: rig.target, value: pose, axes: arm })`.
|
|
1267
|
+
*/
|
|
1268
|
+
declare function jointAxes(skeleton: Skeleton, joints: readonly string[]): number[];
|
|
1269
|
+
/**
|
|
1270
|
+
* How a {@link Pose} of `skeleton` maps to the numbers an animation moves: five per joint in
|
|
1271
|
+
* skeleton order (`x`, `y`, `rotation`, `scaleX`, `scaleY`), every rotation an angle, so a pose
|
|
1272
|
+
* blends the short way round. Each axis is named `<joint>.<field>`, so `axes: ['knee']` on a hold
|
|
1273
|
+
* reaches a joint's five and `['knee.rotation']` one of them. A joint or field the pose leaves out reads as its identity, and a
|
|
1274
|
+
* pose read back names every joint in full. Pass it as `axes` to `createTarget` for a pose target
|
|
1275
|
+
* of your own; a bound rig's is `Rig.target`.
|
|
1276
|
+
*/
|
|
1277
|
+
declare function skeletonAxes(skeleton: Skeleton): TargetAxes<Pose>;
|
|
1278
|
+
|
|
1279
|
+
/** A point in the skeleton's space — the space `resolveSkeleton` resolves into. */
|
|
1280
|
+
interface IkPoint {
|
|
1281
|
+
x: number;
|
|
1282
|
+
y: number;
|
|
1283
|
+
}
|
|
1284
|
+
/** Bounds on a joint's rotation delta from its bind, in radians, with
|
|
1285
|
+
* `-PI <= min <= max <= PI`. */
|
|
1286
|
+
interface IkLimit {
|
|
1287
|
+
min: number;
|
|
1288
|
+
max: number;
|
|
1289
|
+
}
|
|
1290
|
+
/** Options for {@link solveIk}. */
|
|
1291
|
+
interface SolveIkOptions {
|
|
1292
|
+
/** The joints the solver may rotate, root first, each the parent of the next. */
|
|
1293
|
+
joints: readonly string[];
|
|
1294
|
+
/** The end effector, in the last joint's local frame — the forearm's length
|
|
1295
|
+
* along its +x for an arm, or a hand joint's bind offset. */
|
|
1296
|
+
tip: IkPoint;
|
|
1297
|
+
/** Where the tip should go, in skeleton space. A rig posed with a `root`
|
|
1298
|
+
* wants the target carried back through that root's inverse first. */
|
|
1299
|
+
target: IkPoint;
|
|
1300
|
+
/** Per-joint limits, keyed by joint name. A joint without one turns freely. */
|
|
1301
|
+
limits?: Readonly<Record<string, IkLimit>>;
|
|
1302
|
+
/** Two-joint chains only: the middle joint bends toward this point, in
|
|
1303
|
+
* skeleton space. Without it the chain keeps the bend the input pose has. */
|
|
1304
|
+
pole?: IkPoint;
|
|
1305
|
+
/** Most CCD sweeps to run. Default 32. */
|
|
1306
|
+
iterations?: number;
|
|
1307
|
+
/** Tip-to-target distance that counts as reached, in skeleton units.
|
|
1308
|
+
* Default 0.01. */
|
|
1309
|
+
tolerance?: number;
|
|
1310
|
+
}
|
|
1311
|
+
/** What {@link solveIk} returns. */
|
|
1312
|
+
interface IkResult {
|
|
1313
|
+
/** The input pose with each chain joint's rotation replaced. */
|
|
1314
|
+
pose: Pose;
|
|
1315
|
+
/** Tip-to-target distance the solve ended at. */
|
|
1316
|
+
distance: number;
|
|
1317
|
+
/** Whether `distance` is within the tolerance. False for a target out of
|
|
1318
|
+
* reach, which leaves the chain pointing straight at it. */
|
|
1319
|
+
reached: boolean;
|
|
1320
|
+
/** CCD sweeps run; 0 when the two-joint solution or the straight-line
|
|
1321
|
+
* answer for an unreachable target settled it. */
|
|
1322
|
+
iterations: number;
|
|
1323
|
+
}
|
|
1324
|
+
/**
|
|
1325
|
+
* Rotate a joint chain so its tip reaches `target`, returning the result as an
|
|
1326
|
+
* ordinary {@link Pose}. Weighting the IK against an animated pose is
|
|
1327
|
+
* `animator.hold({ target: rig.target, value: solved, weight: w })` beside the
|
|
1328
|
+
* clip at weight `1 - w`; with `axes: jointAxes(skeleton, joints)` on both, the
|
|
1329
|
+
* rest of the body is left to whatever else holds it.
|
|
1330
|
+
*
|
|
1331
|
+
* The solver is cyclic coordinate descent, and limits clamp the rotation the
|
|
1332
|
+
* pose stores. A two-joint chain is solved analytically first: of the two bends
|
|
1333
|
+
* that reach the target it takes the one on `pole`'s side, or the input pose's
|
|
1334
|
+
* side, and falls back to the other bend and then to CCD when limits refuse it.
|
|
1335
|
+
* A target beyond the chain's reach straightens the chain toward it.
|
|
1336
|
+
*/
|
|
1337
|
+
declare function solveIk(skeleton: Skeleton, pose: Pose, options: SolveIkOptions): IkResult;
|
|
1338
|
+
|
|
1339
|
+
/**
|
|
1340
|
+
* How much each point of a path follows each joint: one array per joint name, indexed by
|
|
1341
|
+
* point. Point `i` is the `i`-th coordinate pair of a polygon path's `coords`, so anchors and
|
|
1342
|
+
* curve handles are weighted alike; a rect's points are its corners, clockwise from the top
|
|
1343
|
+
* left. A joint left out, and an index past an array's end, weigh nothing. Weights need not
|
|
1344
|
+
* sum to 1: they are normalized per point as they are applied.
|
|
1345
|
+
*/
|
|
1346
|
+
type Skin = Readonly<Record<string, readonly number[]>>;
|
|
1347
|
+
/**
|
|
1348
|
+
* Each joint's motion since the bind pose, in world space: `world * inverse(restWorld)`.
|
|
1349
|
+
* `world` is what `resolveSkeleton` or `Rig.world()` answers.
|
|
1350
|
+
*/
|
|
1351
|
+
declare function motionsFromRest(skeleton: Skeleton, world: ReadonlyMap<string, GlMat3>): Map<string, GlMat3>;
|
|
1352
|
+
/** The path whose points a skin indexes: a rect as its four corners. */
|
|
1353
|
+
declare function skinnable(path: Path): PolygonPath;
|
|
1354
|
+
/**
|
|
1355
|
+
* Bend `path` by linear blend skinning: each point goes where its joints' motions since the
|
|
1356
|
+
* bind pose would carry it, averaged by weight. `path` is the shape at the bind pose, in the
|
|
1357
|
+
* space `motions` are in; it is not modified. A point no joint weighs stays where it is.
|
|
1358
|
+
*/
|
|
1359
|
+
declare function skinPath(path: Path, skin: Skin, motions: ReadonlyMap<string, GlMat3>): PolygonPath;
|
|
1360
|
+
|
|
1361
|
+
/** Options for `autoSkin`. */
|
|
1362
|
+
interface AutoSkinOptions {
|
|
1363
|
+
/** How fast a bone's pull falls off with distance: a weight is `1 / distance ** power`.
|
|
1364
|
+
* Higher keeps the bend closer to the joint. Default 4. */
|
|
1365
|
+
power?: number;
|
|
1366
|
+
/** The most joints a point follows; the nearest are kept. Default 2. */
|
|
1367
|
+
max?: number;
|
|
1368
|
+
}
|
|
1369
|
+
/**
|
|
1370
|
+
* Weights for `path` from how far each of its points is from each bone of `skeleton` at the
|
|
1371
|
+
* bind pose. `path` is in the skeleton's space. A point on a bone follows that bone alone.
|
|
1372
|
+
*/
|
|
1373
|
+
declare function autoSkin(path: Path, skeleton: Skeleton, options?: AutoSkinOptions): Skin;
|
|
1374
|
+
|
|
1375
|
+
/** Where each joint rests, in the skeleton's space and in its order. */
|
|
1376
|
+
declare function jointPositions(skeleton: Skeleton): Map<string, {
|
|
1377
|
+
x: number;
|
|
1378
|
+
y: number;
|
|
1379
|
+
}>;
|
|
1380
|
+
/** The joint resting nearest `(x, y)` and no further than `reach` from it, or `null`. */
|
|
1381
|
+
declare function jointAt(skeleton: Skeleton, x: number, y: number, reach: number): string | null;
|
|
1382
|
+
/** `skeleton` with `name` resting at `(x, y)`. The joints under it keep their offsets from it,
|
|
1383
|
+
* so they move along. */
|
|
1384
|
+
declare function moveJoint(skeleton: Skeleton, name: string, x: number, y: number): Skeleton;
|
|
1385
|
+
/** `skeleton` with a new joint resting at `(x, y)` under `parent`, or as a root for `null`.
|
|
1386
|
+
* Without a `name` it gets the first of `joint`, `joint2`, … not in use. */
|
|
1387
|
+
declare function addJoint(skeleton: Skeleton, parent: string | null, x: number, y: number, name?: string): {
|
|
1388
|
+
skeleton: Skeleton;
|
|
1389
|
+
name: string;
|
|
1390
|
+
};
|
|
1391
|
+
/** `skeleton` without `name` and the joints under it, and the names that went. */
|
|
1392
|
+
declare function removeJoint(skeleton: Skeleton, name: string): {
|
|
1393
|
+
skeleton: Skeleton;
|
|
1394
|
+
removed: string[];
|
|
1395
|
+
};
|
|
1396
|
+
/** `skin` without the weights of `joints`; the same object when it weighs none of them. */
|
|
1397
|
+
declare function dropSkinJoints(skin: Skin, joints: readonly string[]): Skin;
|
|
1398
|
+
|
|
1399
|
+
/**
|
|
1400
|
+
* `skin` with `joint`'s weight set on some points: `weights` maps a point's index to the new
|
|
1401
|
+
* weight, clamped to 0..1. On each of those points the other joints are scaled to share what
|
|
1402
|
+
* is left, so the point still sums to 1; a point no other joint weighs goes wholly to `joint`,
|
|
1403
|
+
* as it would when the skin is applied. Every array comes back `count` long, and a joint left
|
|
1404
|
+
* weighing nothing is dropped.
|
|
1405
|
+
*/
|
|
1406
|
+
declare function setWeights(skin: Skin, count: number, joint: string, weights: ReadonlyMap<number, number>): Skin;
|
|
1407
|
+
/**
|
|
1408
|
+
* What a round brush at `(x, y)` does to one joint's weights: for each point of `coords`
|
|
1409
|
+
* within `radius`, a weight falling off linearly from the center. `'add'` raises a point
|
|
1410
|
+
* toward 1 and `'remove'` lowers it toward 0; neither moves a point the other way. Answers
|
|
1411
|
+
* only the points that change, by index, for {@link setWeights}.
|
|
1412
|
+
*/
|
|
1413
|
+
declare function brushWeights(coords: ArrayLike<number>, x: number, y: number, radius: number, current: readonly number[] | undefined, mode: 'add' | 'remove'): Map<number, number>;
|
|
1414
|
+
|
|
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 };
|