@xtia/timeline 1.0.6 → 1.0.8
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/README.md +464 -13
- package/index.js +5 -8
- package/internal/easing.js +1 -4
- package/internal/emitters.d.ts +21 -30
- package/internal/emitters.js +241 -100
- package/internal/point.d.ts +15 -6
- package/internal/point.js +41 -2
- package/internal/range.d.ts +14 -4
- package/internal/range.js +96 -2
- package/internal/timeline.d.ts +3 -3
- package/internal/timeline.js +11 -75
- package/internal/tween.d.ts +3 -0
- package/internal/tween.js +3 -6
- package/internal/utils.d.ts +0 -2
- package/internal/utils.js +1 -13
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
**Timeline** is a general‑purpose, environment-agnostic choreography engine that lets you orchestrate any sequence of value changes; numbers, vectors, colour tokens, custom blendable objects, or arbitrary data structures.
|
|
6
6
|
|
|
7
|
+
* [API Reference](#reference)
|
|
7
8
|
|
|
8
9
|
## Basic Use:
|
|
9
10
|
|
|
@@ -33,8 +34,9 @@ timeline
|
|
|
33
34
|
);
|
|
34
35
|
|
|
35
36
|
// use an easing function
|
|
36
|
-
|
|
37
|
+
timeline
|
|
37
38
|
.end
|
|
39
|
+
.delta(500)
|
|
38
40
|
.range(3000)
|
|
39
41
|
.ease("bounce")
|
|
40
42
|
.tween("50%", "0%")
|
|
@@ -83,27 +85,41 @@ asPercent
|
|
|
83
85
|
n => progressBar.style.width = n
|
|
84
86
|
);
|
|
85
87
|
|
|
86
|
-
// apply easing
|
|
88
|
+
// apply easing
|
|
87
89
|
const eased = firstFiveSeconds.ease("easeInOut");
|
|
88
90
|
eased.listen(
|
|
89
91
|
v => console.log(`Eased value: ${v}`)
|
|
90
92
|
);
|
|
91
93
|
|
|
92
|
-
//
|
|
93
|
-
|
|
94
|
+
// chain them
|
|
95
|
+
range
|
|
94
96
|
.tween(0, 30)
|
|
95
97
|
.map(Math.floor)
|
|
96
98
|
.dedupe()
|
|
97
99
|
.tap(n => console.log("Showing frame #", n))
|
|
98
100
|
.map(n => `animation-frame-${n}.png`)
|
|
99
101
|
.listen(filename => img.src = filename);
|
|
102
|
+
|
|
103
|
+
// each step in the chain is a 'pure', independent emitter that emits
|
|
104
|
+
// a transformation of its parent's emissions
|
|
105
|
+
const filenameEmitter = range
|
|
106
|
+
.tween(0, 3)
|
|
107
|
+
.map(Math.floor)
|
|
108
|
+
.dedupe()
|
|
109
|
+
.map(n => `animation-frame-${n}.png`);
|
|
110
|
+
|
|
111
|
+
// filenameEmitter will emit filenames as the Timeline passes through 'range'.
|
|
112
|
+
// it can be listened directly or further transformed
|
|
113
|
+
const urlEmitter = filenameEmitter
|
|
114
|
+
.map(filename => `http://www.example.com/${filename}`);
|
|
115
|
+
|
|
100
116
|
```
|
|
101
117
|
|
|
102
118
|
Range objects also provide a `play()` method that instructs the Timeline to play through that particular range:
|
|
103
119
|
|
|
104
120
|
```ts
|
|
105
121
|
// play through the first two seconds of the Timeline
|
|
106
|
-
timeline
|
|
122
|
+
await timeline
|
|
107
123
|
.range(0, 2000)
|
|
108
124
|
.play();
|
|
109
125
|
```
|
|
@@ -156,7 +172,41 @@ timeline
|
|
|
156
172
|
|
|
157
173
|
## More on tweening
|
|
158
174
|
|
|
159
|
-
Tween emitters can interpolate numbers, arrays of numbers, strings, and objects with a method `blend(from: this, to: this): this
|
|
175
|
+
Tween emitters can interpolate numbers, arrays of numbers, strings, and objects with a method `blend(from: this, to: this): this`, by the progression value emitted by their parent.
|
|
176
|
+
|
|
177
|
+
```ts
|
|
178
|
+
const range = timeline.range(0, 2000);
|
|
179
|
+
|
|
180
|
+
// numbers
|
|
181
|
+
range
|
|
182
|
+
.ease("overshootIn")
|
|
183
|
+
.tween(300, 500)
|
|
184
|
+
.listen(v => element.scrollTop = v);
|
|
185
|
+
|
|
186
|
+
// number arrays
|
|
187
|
+
range
|
|
188
|
+
.tween([0, 180], [360, 180])
|
|
189
|
+
.listen((angles) => pieChart.setValues(angles));
|
|
190
|
+
|
|
191
|
+
// strings
|
|
192
|
+
range
|
|
193
|
+
.tween("#000000", "#ff00ff")
|
|
194
|
+
.listen(v => element.style.color = v);
|
|
195
|
+
|
|
196
|
+
// blendable objects
|
|
197
|
+
// (T extends { blend(from: this, to: this): this })
|
|
198
|
+
import { RGBA } from "@xtia/rgba";
|
|
199
|
+
range
|
|
200
|
+
.tween(RGBA.parse("#c971a7"), RGBA.parse("#fff"))
|
|
201
|
+
.listen(v => element.style.background = v.hexCode);
|
|
202
|
+
|
|
203
|
+
import { Angle } from "@xtia/mezr";
|
|
204
|
+
range
|
|
205
|
+
.tween(Angle.degrees(45), Angle.turns(.5))
|
|
206
|
+
.map(a => `rotate(${a.asDegrees}deg)`)
|
|
207
|
+
.listen(v => element.style.transform = v);
|
|
208
|
+
|
|
209
|
+
```
|
|
160
210
|
|
|
161
211
|
#### String interpolation
|
|
162
212
|
* If the strings contain tweenable tokens (numbers, colour codes) and are otherwise identical, those tokens are interpolated
|
|
@@ -174,10 +224,11 @@ timeline
|
|
|
174
224
|
timeline
|
|
175
225
|
.range(0, 2000)
|
|
176
226
|
.tween("--------", "########")
|
|
227
|
+
.dedupe()
|
|
177
228
|
.listen(v => document.title = v);
|
|
178
229
|
```
|
|
179
230
|
|
|
180
|
-
|
|
231
|
+
Try out the [shadow tweening example at StackBlitz](https://stackblitz.com/edit/timeline-string-tween?file=src%2Fmain.ts)
|
|
181
232
|
|
|
182
233
|
## Autoplay and Looping Strategies
|
|
183
234
|
|
|
@@ -187,13 +238,13 @@ To create a Timeline that immediately starts playing, pass `true` to its constru
|
|
|
187
238
|
// immediately fade in an element
|
|
188
239
|
new Timeline(true)
|
|
189
240
|
.range(0, 1000)
|
|
190
|
-
.
|
|
241
|
+
.listen(v => element.style.opacity = v);
|
|
191
242
|
|
|
192
243
|
// note, an `animate(duration)` function is exported for
|
|
193
244
|
// disposable, single-use animations such as this:
|
|
194
245
|
import { animate } from "@xtia/timeline";
|
|
195
246
|
animate(1000)
|
|
196
|
-
.
|
|
247
|
+
.listen(v => element.style.opacity = v);
|
|
197
248
|
```
|
|
198
249
|
|
|
199
250
|
Normally a Timeline will simply stop playing when it reaches the end. This can be changed by passing a second argument (`endAction`) to the constructor.
|
|
@@ -260,10 +311,12 @@ loadingTimeline
|
|
|
260
311
|
.tween("0%", "100%");
|
|
261
312
|
.listen(v => progressBar.style.width = v);
|
|
262
313
|
|
|
314
|
+
// and do something when they're loaded
|
|
263
315
|
loadingTimeline
|
|
264
316
|
.end
|
|
265
317
|
.listen(startGame);
|
|
266
318
|
|
|
319
|
+
// to drive it, just seek forward by 1 for each loaded resource
|
|
267
320
|
resourceUrls.forEach(url => {
|
|
268
321
|
preload(url).then(
|
|
269
322
|
() => loadingTimeline.currentTime++
|
|
@@ -274,12 +327,12 @@ resourceUrls.forEach(url => {
|
|
|
274
327
|
We can pass a second argument to `seek()` to perform a 'smooth seek' over the given duration. A third argument can provide an easing function for the smooth seek process:
|
|
275
328
|
|
|
276
329
|
```ts
|
|
277
|
-
timeline.seek(timeline.end, 400, "overshootIn");
|
|
330
|
+
await timeline.seek(timeline.end, 400, "overshootIn");
|
|
278
331
|
```
|
|
279
332
|
|
|
280
333
|
## Backward-compatibility
|
|
281
334
|
|
|
282
|
-
Despite the massive overhaul, the previous API is present and expanded
|
|
335
|
+
Despite the massive overhaul, the previous API is present and expanded and upgrading to 1.0.0 should be frictionless in the vast majority of cases.
|
|
283
336
|
|
|
284
337
|
#### Breaking changes
|
|
285
338
|
|
|
@@ -288,7 +341,7 @@ Despite the massive overhaul, the previous API is present and expanded and upgr
|
|
|
288
341
|
#### Mitigation
|
|
289
342
|
|
|
290
343
|
* `timeline.tween()` now accepts TimelinePoint as a starting position, and provides an overload that replaces the `duration: number` parameter with `end: TimelinePoint`.
|
|
291
|
-
* Should you encounter a case where this change still causes issue, eg `
|
|
344
|
+
* Should you encounter a case where this change still causes issue, eg `timeline.tween(0, timeline.end / 2, ...)`, `timeline.end.position` is equivalent to the old API's `timeline.end`.
|
|
292
345
|
|
|
293
346
|
#### Enhancements (non-breaking)
|
|
294
347
|
|
|
@@ -299,4 +352,402 @@ Despite the massive overhaul, the previous API is present and expanded and upgr
|
|
|
299
352
|
|
|
300
353
|
* `timeline.position` will be replaced with `timeline.currentTime` to be consistent with other seekable concepts.
|
|
301
354
|
* `"loop"` endAction is now `"restart"` to disambiguate from new looping strategies.
|
|
302
|
-
* `timeline.step()` is redundant now that `currentTime` is writable; use `timeline.currentTime += delta` instead.
|
|
355
|
+
* `timeline.step()` is redundant now that `currentTime` is writable; use `timeline.currentTime += delta` instead.
|
|
356
|
+
|
|
357
|
+
|
|
358
|
+
|
|
359
|
+
## Reference
|
|
360
|
+
|
|
361
|
+
### `Timeline` class
|
|
362
|
+
|
|
363
|
+
A self-contained collection of points and ranges that trigger events as the Timeline seeks to and through them.
|
|
364
|
+
|
|
365
|
+
#### Properties
|
|
366
|
+
|
|
367
|
+
##### `currentTime: number`
|
|
368
|
+
|
|
369
|
+
Reads or sets the Timeline's current time position. Setting this property will perform a `seek()`, triggering any listener that is passed or landed on.
|
|
370
|
+
|
|
371
|
+
##### `timeScale: number`
|
|
372
|
+
|
|
373
|
+
Controls the speed at which a Timeline will progress when driven by the `play()` method (including by autoplay).
|
|
374
|
+
|
|
375
|
+
##### `isPlaying: boolean`
|
|
376
|
+
|
|
377
|
+
Returns true if the Timeline is actively being driven by the `play()` method (including by autoplay).
|
|
378
|
+
|
|
379
|
+
##### `end: `[`TimelinePoint`](#timelinepoint-interface)
|
|
380
|
+
|
|
381
|
+
Returns the **current** final point in the Timeline.
|
|
382
|
+
|
|
383
|
+
##### `start: `[`TimelinePoint`](#timelinepoint-interface)
|
|
384
|
+
|
|
385
|
+
Returns a point representing position 0.
|
|
386
|
+
|
|
387
|
+
#### Methods
|
|
388
|
+
|
|
389
|
+
##### `point(position): `[`TimelinePoint`](#timelinepoint-interface)
|
|
390
|
+
|
|
391
|
+
Returns a point that represents a specific position on the Timeline.
|
|
392
|
+
|
|
393
|
+
If `position` is greater than that Timeline's end-position, the end-position will be extended to `position`.
|
|
394
|
+
|
|
395
|
+
*Note*, for deterministic consistency, points will be triggered if a forward-moving seek lands exactly on the point's position (or passes it entirely), while a backward-moving seek will trigger points that are passed or moved from.
|
|
396
|
+
|
|
397
|
+
##### `range(start, duration): `[`TimelineRange`](#timelinerange-interface)
|
|
398
|
+
|
|
399
|
+
Returns a range that represents a section of the Timeline.
|
|
400
|
+
|
|
401
|
+
If the end of the range is beyond the Timeline's end-position, the end-position will be extended to the end of the range.
|
|
402
|
+
|
|
403
|
+
If `duration` is omitted, the range will extend from `start` to the **current** end-position of the Timeline.
|
|
404
|
+
|
|
405
|
+
If `start` is omitted, the range will start at 0 and represent the full **current** range of the Timeline.
|
|
406
|
+
|
|
407
|
+
##### `seek(toPosition): void`
|
|
408
|
+
|
|
409
|
+
Sets the Timeline's internal position (`currentTime`), triggering in chronological order listeners attached to any [`TimelinePoint`](#timelinepoint-interface) or [`TimelineRange`](#timelinerange-interface) that are passed or landed on.
|
|
410
|
+
|
|
411
|
+
##### `seek(toPosition, duration, easer?): Promise<void>`
|
|
412
|
+
|
|
413
|
+
Performs an interruptable 'smooth seek' to a specified position, lasting `duration` milliseconds, with optional easing.
|
|
414
|
+
|
|
415
|
+
Returns a Promise that will be resolved when the smooth seek is completed (or is interrupted by another seek\*).
|
|
416
|
+
|
|
417
|
+
\* Resolution on interruption is not finalised in the library's design and the effect should be considered exceptional; relying on it is not recommended. Future versions might reject the promise when its seek is interrupted.
|
|
418
|
+
|
|
419
|
+
##### `play(): void`
|
|
420
|
+
|
|
421
|
+
Begins playing through the Timeline, from its current position, at (1000 x `timeScale`) units per second, updating 60 times per second.
|
|
422
|
+
|
|
423
|
+
##### `play(fps): void`
|
|
424
|
+
|
|
425
|
+
Begins playing through the Timeline, from its current position, at (1000 x `timeScale`) units per second, updating `fps` times per second.
|
|
426
|
+
|
|
427
|
+
##### `tween<T>(start, duration, apply, from, to, easer?): `[`ChainingInterface`](#chaininginterface-interface)
|
|
428
|
+
|
|
429
|
+
Creates a [`TimelineRange`](#timelinerange-interface) and attaches a tweening listener.
|
|
430
|
+
|
|
431
|
+
Equivalent to
|
|
432
|
+
|
|
433
|
+
```ts
|
|
434
|
+
timeline
|
|
435
|
+
.range(start, duration)
|
|
436
|
+
.ease(easer)
|
|
437
|
+
.tween(from, to)
|
|
438
|
+
.listen(apply);
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
Returns a [`ChainingInterface`](#chaininginterface-interface) representing the point at which the tween ends.
|
|
442
|
+
|
|
443
|
+
##### `tween<T>(start, end, apply, from, to, easer?): `[`ChainingInterface`](#chaininginterface-interface)
|
|
444
|
+
|
|
445
|
+
As above, but if the second argument is a [`TimelinePoint`](#timelinepoint-interface), it will specify when on the Timeline the tween will *end*.
|
|
446
|
+
|
|
447
|
+
##### `at(position, apply, reverse?): `[`ChainingInterface`](#chaininginterface-interface)
|
|
448
|
+
|
|
449
|
+
Creates a [`TimelinePoint`](#timelinepoint-interface) and attaches a listener that will trigger when the Timeline seeks past or to that point.
|
|
450
|
+
|
|
451
|
+
If `reverse` is a function, that will be called instead of `apply` when the seek that triggered the event was moving backwards. If `reverse` is `true`, `apply` will be called regardless of which direction the seek moved. If `reverse` is false or omitted, this listener will ignore backward-moving seeks.
|
|
452
|
+
|
|
453
|
+
|
|
454
|
+
|
|
455
|
+
|
|
456
|
+
### `TimelinePoint` interface
|
|
457
|
+
|
|
458
|
+
Represents a single point on a [`Timeline`](#timeline-class).
|
|
459
|
+
|
|
460
|
+
##### Inherits [`Emitter<PointEvent>`](#emittert-interface)
|
|
461
|
+
|
|
462
|
+
Listeners will be invoked with a [`PointEvent`](#pointevent-interface) when a seek passes or lands on the point.
|
|
463
|
+
|
|
464
|
+
*Note*, during a point event, the parent Timeline's `currentTime` property will return that point's position, even if the Timeline is configured with a [*wrap* end action](#autoplay-and-looping-strategies) and its true position is beyond its end. For deterministic consistency, ranges will emit values for the point's position before the point emits.
|
|
465
|
+
|
|
466
|
+
#### Properties
|
|
467
|
+
|
|
468
|
+
##### `position: number`
|
|
469
|
+
|
|
470
|
+
This point's position on the Timeline.
|
|
471
|
+
|
|
472
|
+
#### Methods
|
|
473
|
+
|
|
474
|
+
##### `range(duration): TimelineRange`
|
|
475
|
+
|
|
476
|
+
Creates a [`TimelineRange`](#timelinerange-interface) on the Timeline to which the point belongs, of the specified duration.
|
|
477
|
+
|
|
478
|
+
##### `to(endPoint): TimelineRange`
|
|
479
|
+
|
|
480
|
+
Creates a [`TimelineRange`](#timelinerange-interface) on the Timeline to which the point belongs, ending at the specified point.
|
|
481
|
+
|
|
482
|
+
##### `delta(timeOffset): TimelinePoint`
|
|
483
|
+
|
|
484
|
+
Creates a `TimelinePoint` at an offset from the this point.
|
|
485
|
+
|
|
486
|
+
|
|
487
|
+
|
|
488
|
+
|
|
489
|
+
### `PointEvent` interface
|
|
490
|
+
|
|
491
|
+
Provides information relevant to [`TimelinePoint`](#timelinepoint-interface) events.
|
|
492
|
+
|
|
493
|
+
#### Properties
|
|
494
|
+
|
|
495
|
+
##### `direction: -1 | 1`
|
|
496
|
+
|
|
497
|
+
Provides the direction of the seek that triggered a point event. `direction === 1` indicates that the seek moved forward and `direction === -1` indicates that the seek was moving backwards.
|
|
498
|
+
|
|
499
|
+
Allows point listeners to undo effects when the Timeline is reversed.
|
|
500
|
+
|
|
501
|
+
```ts
|
|
502
|
+
timeline
|
|
503
|
+
.point(4000)
|
|
504
|
+
.listen(
|
|
505
|
+
event => element.classList.toggle(
|
|
506
|
+
"visible",
|
|
507
|
+
event.direction > 0
|
|
508
|
+
)
|
|
509
|
+
);
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
|
|
513
|
+
|
|
514
|
+
|
|
515
|
+
### `TimelineRange` interface
|
|
516
|
+
|
|
517
|
+
Represents a fixed-length, fixed position section of a [`Timeline`](#timeline-class).
|
|
518
|
+
|
|
519
|
+
##### Inherits [`RangeProgression`](#rangeprogression-interface)
|
|
520
|
+
|
|
521
|
+
Emits a normalised progression (0..1) of the range when the parent Timeline seeks over or into it.
|
|
522
|
+
|
|
523
|
+
#### Properties
|
|
524
|
+
|
|
525
|
+
##### `start: `[`TimelinePoint`](#timelinepoint-interface)
|
|
526
|
+
|
|
527
|
+
The point on the Timeline at which this range starts.
|
|
528
|
+
|
|
529
|
+
##### `end: `[`TimelinePoint`](#timelinepoint-interface)
|
|
530
|
+
|
|
531
|
+
The point on the Timeline at which this range ends.
|
|
532
|
+
|
|
533
|
+
##### `duration: number`
|
|
534
|
+
|
|
535
|
+
The length of the range.
|
|
536
|
+
|
|
537
|
+
#### Methods
|
|
538
|
+
|
|
539
|
+
##### `bisect(position?): [TimelineRange, TimelineRange]`
|
|
540
|
+
|
|
541
|
+
Creates two ranges representing two distinct sections of the parent. `position` is relative to the parent's start.
|
|
542
|
+
|
|
543
|
+
##### `spread(count): `[`TimelinePoint`](#timelinepoint-interface)[]
|
|
544
|
+
|
|
545
|
+
Creates and returns `count` points spread evenly over the range.
|
|
546
|
+
|
|
547
|
+
##### `play(easer?): Promise<void>`
|
|
548
|
+
|
|
549
|
+
Instructs the Timeline to which this range belongs to play through the represented range. This playthrough counts as a smooth seek for seek interruption purposes.
|
|
550
|
+
|
|
551
|
+
Returns a Promise that will be resolved when the range playthrough completes.
|
|
552
|
+
|
|
553
|
+
##### `grow(delta, anchor?): TimelineRange`
|
|
554
|
+
|
|
555
|
+
Creates a new range on the parent Timeline. The location and duration of the new range are copied from this range and grown from an anchor point, specified as a normalised (0..1) progression of the parent range.
|
|
556
|
+
|
|
557
|
+
##### `grow(delta, anchor?): TimelineRange`
|
|
558
|
+
|
|
559
|
+
Creates a new range on the parent Timeline. The location and duration of the new range are copied from this range and scaled multiplicatively from an anchor point, specified as a normalised (0..1) progression of the parent range.
|
|
560
|
+
|
|
561
|
+
##### `contains(point)`
|
|
562
|
+
|
|
563
|
+
Returns true if the given [`TimelinePoint`](#timelinepoint-interface) sits within this range.
|
|
564
|
+
|
|
565
|
+
|
|
566
|
+
|
|
567
|
+
|
|
568
|
+
### `RangeProgression` interface
|
|
569
|
+
|
|
570
|
+
Represents a step in an immutable [`TimelineRange`](#timelinerange-interface) event transformation pipeline.
|
|
571
|
+
|
|
572
|
+
##### Inherits [`Emitter<number>`](#emittert-interface)
|
|
573
|
+
|
|
574
|
+
Listeners will be invoked when a seek passes or lands within a range.
|
|
575
|
+
|
|
576
|
+
#### Methods
|
|
577
|
+
|
|
578
|
+
##### `ease(easer?): RangeProgression`
|
|
579
|
+
|
|
580
|
+
Creates an emitter that applies an easing function to parent emissions.
|
|
581
|
+
|
|
582
|
+
##### `tween<T>(from, to): `[`Emitter<T>`](#emittert-interface)
|
|
583
|
+
|
|
584
|
+
Creates an emitter blends two values, biased by progression emitted by the parent.
|
|
585
|
+
|
|
586
|
+
`T` may be `string`, `number`, `number[]` or an object type that includes
|
|
587
|
+
|
|
588
|
+
```ts
|
|
589
|
+
blend(from: this, to: this, progress: number): this
|
|
590
|
+
```
|
|
591
|
+
|
|
592
|
+
##### `snap(steps): RangeProgression`
|
|
593
|
+
|
|
594
|
+
Creates an emitter that quantises progression emitted by the parent to the nearest of `steps` discrete values.
|
|
595
|
+
|
|
596
|
+
##### `threshold(threshold): RangeProgression`
|
|
597
|
+
|
|
598
|
+
Creates an emitter that emits 0 when the parent emits a value below `threshold` and 1 when a parent emission is equal to or greater than `threshold`.
|
|
599
|
+
|
|
600
|
+
```ts
|
|
601
|
+
emittedValue = parentEmission < threshold ? 0 : 1
|
|
602
|
+
```
|
|
603
|
+
|
|
604
|
+
##### `clamp(min?, max?): RangeProgression`
|
|
605
|
+
|
|
606
|
+
Creates an emitter that clamps progression between `min` and `max`.
|
|
607
|
+
|
|
608
|
+
##### `repeat(count): RangeProgression`
|
|
609
|
+
|
|
610
|
+
Creates an emitter that multiplies progression and wraps at 1, thereby mapping to a repeating scale.
|
|
611
|
+
|
|
612
|
+
##### `tap(cb): RangeProgression`
|
|
613
|
+
|
|
614
|
+
Creates an emitter that mirrors emissions from the parent emitter, invoking the provided callback `cb` as a side effect for each emission.
|
|
615
|
+
|
|
616
|
+
##### `filter(check: (value) => boolean): RangeProgression`
|
|
617
|
+
|
|
618
|
+
Creates an emitter that selectively discards parent emissions.
|
|
619
|
+
|
|
620
|
+
If `check(value)` returns true, the value will be emitted.
|
|
621
|
+
|
|
622
|
+
##### `dedupe(): RangeProgression`
|
|
623
|
+
|
|
624
|
+
Creates an emitter that discards emitted values that are the same as the last value emitted by the new emitter
|
|
625
|
+
|
|
626
|
+
##### `offset(delta): RangeProgression`
|
|
627
|
+
|
|
628
|
+
Creates an emitter that offsets its parent's values by the given delta, wrapping at 1
|
|
629
|
+
|
|
630
|
+
##### `fork(cb: (branch) => void): RangeProgression`
|
|
631
|
+
|
|
632
|
+
Immediately invokes `cb` with this emitter and returns this emitter for further chaining.
|
|
633
|
+
|
|
634
|
+
Allows branching without breaking a composition chain, eg:
|
|
635
|
+
|
|
636
|
+
```ts
|
|
637
|
+
range
|
|
638
|
+
.tween("0%", "100%")
|
|
639
|
+
.fork(branch => {
|
|
640
|
+
branch
|
|
641
|
+
.map(s => `Loading: ${s}`)
|
|
642
|
+
.listen(s => document.title = s)
|
|
643
|
+
})
|
|
644
|
+
.listen(v => progressBar.style.width = v);
|
|
645
|
+
```
|
|
646
|
+
|
|
647
|
+
|
|
648
|
+
|
|
649
|
+
|
|
650
|
+
### `Emitter<T>` interface
|
|
651
|
+
|
|
652
|
+
#### Methods
|
|
653
|
+
|
|
654
|
+
##### `listen(handler: Handler<T>): UnsubscribeFunc`
|
|
655
|
+
|
|
656
|
+
Attaches a handler to the emitter and returns a function that will unsubscribe the handler.
|
|
657
|
+
|
|
658
|
+
##### `map<R>(mapFunc: (value: T) => R): Emitter<R>`
|
|
659
|
+
|
|
660
|
+
Creates an emitter that performs an arbitrary transformation.
|
|
661
|
+
|
|
662
|
+
##### `filter(check: (value: T) => boolean): Emitter<T>`
|
|
663
|
+
|
|
664
|
+
Creates an emitter that selectively discards parent emissions.
|
|
665
|
+
|
|
666
|
+
If `check(value)` returns true, the value will be emitted.
|
|
667
|
+
|
|
668
|
+
##### `dedupe(compare?: (a: T, b: T) => boolean): Emitter<T>`
|
|
669
|
+
|
|
670
|
+
Creates an emitter that discards emitted values that are the same as the last value emitted by the new emitter
|
|
671
|
+
|
|
672
|
+
##### `tap(cb: Handler<T>): Emitter<T>`
|
|
673
|
+
|
|
674
|
+
Creates an emitter that mirrors emissions from the parent emitter, invoking the provided callback `cb` as a side effect for each emission.
|
|
675
|
+
|
|
676
|
+
##### `fork(cb: (branch: Emitter<T>) => void): Emitter<T>`
|
|
677
|
+
|
|
678
|
+
Immediately invokes `cb` with this emitter and returns this emitter for further chaining.
|
|
679
|
+
|
|
680
|
+
Allows branching without breaking a composition chain, eg:
|
|
681
|
+
|
|
682
|
+
```ts
|
|
683
|
+
range
|
|
684
|
+
.tween("0%", "100%")
|
|
685
|
+
.fork(branch => {
|
|
686
|
+
branch
|
|
687
|
+
.map(s => `Loading: ${s}`)
|
|
688
|
+
.listen(s => document.title = s)
|
|
689
|
+
})
|
|
690
|
+
.listen(v => progressBar.style.width = v);
|
|
691
|
+
```
|
|
692
|
+
|
|
693
|
+
|
|
694
|
+
|
|
695
|
+
|
|
696
|
+
### `animate(duration)` function
|
|
697
|
+
|
|
698
|
+
Creates and returns a [`TimelineRange`](#timelinerange-interface) that will automatically play over `duration` milliseconds.
|
|
699
|
+
|
|
700
|
+
### `ChainingInterface` interface
|
|
701
|
+
|
|
702
|
+
Conveys composable sequential tweens and events with the simplified API. Each instance represents a specific point on the parent Timeline.
|
|
703
|
+
|
|
704
|
+
```ts
|
|
705
|
+
timeline
|
|
706
|
+
.tween(0, 1000, doThing, 0, 100)
|
|
707
|
+
.thenWait(500)
|
|
708
|
+
.then(doOtherThing)
|
|
709
|
+
.thenWait(250)
|
|
710
|
+
.thenTween(2000, dothing, 100, 0);
|
|
711
|
+
```
|
|
712
|
+
|
|
713
|
+
#### Properties
|
|
714
|
+
|
|
715
|
+
##### `end: `[`TimelinePoint`](#timelinepoint-interface)
|
|
716
|
+
|
|
717
|
+
The point on the Timeline at which the effect of the previous chained call ends.
|
|
718
|
+
|
|
719
|
+
#### Methods
|
|
720
|
+
|
|
721
|
+
##### `thenTween(duration, apply, from, to, easer): ChainingInterface`
|
|
722
|
+
|
|
723
|
+
Adds a tween, beginning at the point the interface represents. Returns a new `ChainingInterface` representing the end of the new tween.
|
|
724
|
+
|
|
725
|
+
##### `then(action: () => void): ChainingInterface`
|
|
726
|
+
|
|
727
|
+
Adds a point event at the point the interface represents.
|
|
728
|
+
|
|
729
|
+
##### `thenWait(duration): ChainingInterface`
|
|
730
|
+
|
|
731
|
+
Creates a new `ChainingInterface` by offsetting the parent by `duration`.
|
|
732
|
+
|
|
733
|
+
|
|
734
|
+
|
|
735
|
+
### `easers` const
|
|
736
|
+
|
|
737
|
+
The following easers are provided:
|
|
738
|
+
|
|
739
|
+
`linear`, `easeIn`, `easeIn4`, `easeOut`, `easeOut4`, `circleIn`, `circleIn4`, `circleOut`, `circleOut4`, `easeInOut`, `elastic`, `overshootIn`, `sine`, `invert`, `bounce`, `noise`, `pingpong`
|
|
740
|
+
|
|
741
|
+
Methods that accept an easing function accept both `(progress: number) => number` and any of the names above.
|
|
742
|
+
|
|
743
|
+
```ts
|
|
744
|
+
timeline
|
|
745
|
+
.tween(s, e, a, f, t, v => Math.sqrt(v))
|
|
746
|
+
.thenTween(s, e, a, f, t, c, "elastic");
|
|
747
|
+
|
|
748
|
+
timeline
|
|
749
|
+
.range(0, 1000)
|
|
750
|
+
.ease("circleOut")
|
|
751
|
+
.ease(easers.easeIn)
|
|
752
|
+
// ...
|
|
753
|
+
```
|
package/index.js
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
Object.defineProperty(exports, "animate", { enumerable: true, get: function () { return timeline_1.animate; } });
|
|
7
|
-
var easing_1 = require("./internal/easing");
|
|
8
|
-
Object.defineProperty(exports, "easers", { enumerable: true, get: function () { return easing_1.easers; } });
|
|
1
|
+
export { Timeline, animate } from "./internal/timeline";
|
|
2
|
+
export { TimelinePoint } from "./internal/point";
|
|
3
|
+
export { TimelineRange } from "./internal/range";
|
|
4
|
+
export { Emitter, RangeProgression } from "./internal/emitters";
|
|
5
|
+
export { easers } from "./internal/easing";
|
package/internal/easing.js
CHANGED