@xtia/timeline 1.1.0 → 1.1.1
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 +60 -13
- package/internal/point.d.ts +39 -1
- package/internal/point.js +63 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Timeline
|
|
2
2
|
|
|
3
|
-
###
|
|
3
|
+
### Not Just Another Animation Library
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Timeline is a type-safe, deterministic choreography system that can control state transitions in any environment, whether that's a simple or complex CSS animation, managing a microcontroller's output, or synchronising complex hardware sequences.
|
|
6
6
|
|
|
7
7
|
* [API Reference](#reference)
|
|
8
8
|
* [Playground](https://stackblitz.com/edit/timeline-string-tween?file=src%2Fmain.ts)
|
|
@@ -29,20 +29,18 @@ timeline
|
|
|
29
29
|
const message = "Hi, planet!";
|
|
30
30
|
timeline
|
|
31
31
|
.range(500, 2000)
|
|
32
|
+
.ease("easeOut")
|
|
32
33
|
.tween(0, message.length)
|
|
33
34
|
.map(n => message.substring(0, n))
|
|
34
35
|
.apply(
|
|
35
36
|
s => element.textContent = s
|
|
36
37
|
);
|
|
37
38
|
|
|
38
|
-
//
|
|
39
|
+
// control anything:
|
|
39
40
|
timeline
|
|
40
|
-
.range(
|
|
41
|
-
.
|
|
42
|
-
.
|
|
43
|
-
.apply(
|
|
44
|
-
value => element.style.marginLeft = value
|
|
45
|
-
);
|
|
41
|
+
.range(1000, 2000)
|
|
42
|
+
.tween(0, 255)
|
|
43
|
+
.listen(value => microcontroller.setPWM(value))
|
|
46
44
|
|
|
47
45
|
// make it go
|
|
48
46
|
timeline.play();
|
|
@@ -129,7 +127,7 @@ Custom easers can be passed to `ease()` as `(progress: number) => number`:
|
|
|
129
127
|
```ts
|
|
130
128
|
timeline
|
|
131
129
|
.range(0, 1000)
|
|
132
|
-
.ease(n =>
|
|
130
|
+
.ease(n => n * n)
|
|
133
131
|
.tween(/*...*/);
|
|
134
132
|
```
|
|
135
133
|
|
|
@@ -491,6 +489,33 @@ Seeks the parent Timeline to this point.
|
|
|
491
489
|
|
|
492
490
|
Smooth-seeks the parent Timeline to this point over a specified duration and resolves the returned Promise on completion.
|
|
493
491
|
|
|
492
|
+
##### `promise(): Promise<-1 | 1>`
|
|
493
|
+
|
|
494
|
+
Creates a `Promise` that will be resolved when the Timeline first seeks to/past this point.
|
|
495
|
+
|
|
496
|
+
The resolved value indicates the direction of the seek that triggered resolution.
|
|
497
|
+
|
|
498
|
+
##### `forwardOnly(): Emitter<PointEvent>`
|
|
499
|
+
|
|
500
|
+
Creates an emitter that forwards emissions triggered by forward-moving seeks.
|
|
501
|
+
|
|
502
|
+
##### `reverseOnly(): Emitter<PointEvent>`
|
|
503
|
+
|
|
504
|
+
Creates an emitter that forwards emissions triggered by backward-moving seeks.
|
|
505
|
+
|
|
506
|
+
##### `applyDirectional(apply, revert): UnsubscribeFunc`
|
|
507
|
+
|
|
508
|
+
Registers an emission handler that calls one function for forward seeks to or past the point, and another for backward seeks from or past the point.
|
|
509
|
+
|
|
510
|
+
```ts
|
|
511
|
+
point
|
|
512
|
+
.applyDirectional(
|
|
513
|
+
element.classList.add("faded"),
|
|
514
|
+
element.classList.remove("faded"),
|
|
515
|
+
);
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
|
|
494
519
|
|
|
495
520
|
|
|
496
521
|
### `PointEvent` interface
|
|
@@ -565,10 +590,22 @@ Creates a new range on the parent Timeline. The location and duration of the new
|
|
|
565
590
|
|
|
566
591
|
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.
|
|
567
592
|
|
|
568
|
-
##### `
|
|
593
|
+
##### `subdivide(n): TimelineRange[]`
|
|
594
|
+
|
|
595
|
+
Creates the specified number of ranges, each of `(parent.duration / count)` duration, spread evenly over this range.
|
|
596
|
+
|
|
597
|
+
##### `shift(delta): TimelineRange`
|
|
598
|
+
|
|
599
|
+
Creates a new range by offsetting the parent by a given time delta.
|
|
600
|
+
|
|
601
|
+
##### `contains(point): boolean`
|
|
569
602
|
|
|
570
603
|
Returns true if the given [`TimelinePoint`](#timelinepoint-interface) sits within this range.
|
|
571
604
|
|
|
605
|
+
##### `overlaps(range): boolean`
|
|
606
|
+
|
|
607
|
+
Returns true if the given range overlaps with this range.
|
|
608
|
+
|
|
572
609
|
|
|
573
610
|
|
|
574
611
|
|
|
@@ -634,9 +671,20 @@ If `check(value)` returns true, the value will be emitted.
|
|
|
634
671
|
|
|
635
672
|
Creates an emitter that discards emitted values that are the same as the last value emitted by the new emitter
|
|
636
673
|
|
|
674
|
+
##### `sample<T>(items): T`
|
|
675
|
+
|
|
676
|
+
Creates a chainable emitter that takes a value from an array according to progression.
|
|
677
|
+
|
|
678
|
+
```ts
|
|
679
|
+
range
|
|
680
|
+
.sample(["a", "b", "c"])
|
|
681
|
+
.apply(v => console.log(v));
|
|
682
|
+
// logs 'b' when a seek lands halfway through range
|
|
683
|
+
```
|
|
684
|
+
|
|
637
685
|
##### `offset(delta): RangeProgression`
|
|
638
686
|
|
|
639
|
-
Creates an emitter that offsets its parent's values by the given delta, wrapping at 1
|
|
687
|
+
Creates an emitter that offsets its parent's values by the given delta, wrapping at 1.
|
|
640
688
|
|
|
641
689
|
##### `fork(cb: (branch) => void): RangeProgression`
|
|
642
690
|
|
|
@@ -657,7 +705,6 @@ range
|
|
|
657
705
|
|
|
658
706
|
|
|
659
707
|
|
|
660
|
-
|
|
661
708
|
### `Emitter<T>` interface
|
|
662
709
|
|
|
663
710
|
#### Methods
|
package/internal/point.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Easer } from "./easing";
|
|
2
|
-
import { Emitter, ListenFunc } from "./emitters";
|
|
2
|
+
import { Emitter, ListenFunc, UnsubscribeFunc } from "./emitters";
|
|
3
3
|
import { TimelineRange } from "./range";
|
|
4
4
|
import { Timeline } from "./timeline";
|
|
5
5
|
export type PointEvent = {
|
|
@@ -41,4 +41,42 @@ export declare class TimelinePoint extends Emitter<PointEvent> {
|
|
|
41
41
|
*/
|
|
42
42
|
seek(): void;
|
|
43
43
|
seek(duration: number, easer?: Easer): Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* Creates an emitter that only emits on forward-moving seeks
|
|
46
|
+
* @returns
|
|
47
|
+
*/
|
|
48
|
+
forwardOnly(): Emitter<PointEvent>;
|
|
49
|
+
/**
|
|
50
|
+
* Creates an emitter that only emits on backward-moving seeks
|
|
51
|
+
* @returns
|
|
52
|
+
*/
|
|
53
|
+
reverseOnly(): Emitter<PointEvent>;
|
|
54
|
+
/**
|
|
55
|
+
* Creates a Promise that will be resolved when the Timeline first seeks to/past this point
|
|
56
|
+
*
|
|
57
|
+
* The resolved value indicates the direction of the seek that triggered resolution
|
|
58
|
+
*
|
|
59
|
+
* @returns A Promise, resolved when the point is triggered by a seek
|
|
60
|
+
*/
|
|
61
|
+
promise(): Promise<1 | -1>;
|
|
62
|
+
/**
|
|
63
|
+
* Registers a pair of functions to handle seeks that reach or pass this point, depending on seek direction
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```
|
|
67
|
+
* point
|
|
68
|
+
* .applyDirectional(
|
|
69
|
+
* element.classList.add("faded"),
|
|
70
|
+
* element.classList.remove("faded"),
|
|
71
|
+
* );
|
|
72
|
+
* ```
|
|
73
|
+
*
|
|
74
|
+
* Note, for deterministic consistency, a forward-seek triggers points when it
|
|
75
|
+
* *passes or reaches* them, while a backward-seek triggers points when it
|
|
76
|
+
* *passes or departs from* them.
|
|
77
|
+
* @param apply Handler for forward-moving seeks that pass or reach this point
|
|
78
|
+
* @param revert Handler for backward-moving seeks that pass this point
|
|
79
|
+
* @returns A function to deregister both handlers
|
|
80
|
+
*/
|
|
81
|
+
applyDirectional(apply: () => void, revert: () => void): UnsubscribeFunc;
|
|
44
82
|
}
|
package/internal/point.js
CHANGED
|
@@ -41,4 +41,67 @@ export class TimelinePoint extends Emitter {
|
|
|
41
41
|
seek(duration = 0, easer) {
|
|
42
42
|
return this.timeline.seek(this.position, duration, easer);
|
|
43
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* Creates an emitter that only emits on forward-moving seeks
|
|
46
|
+
* @returns
|
|
47
|
+
*/
|
|
48
|
+
forwardOnly() {
|
|
49
|
+
return new Emitter(handler => {
|
|
50
|
+
return this.onListen((ev) => {
|
|
51
|
+
if (ev.direction > 0)
|
|
52
|
+
handler(ev);
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Creates an emitter that only emits on backward-moving seeks
|
|
58
|
+
* @returns
|
|
59
|
+
*/
|
|
60
|
+
reverseOnly() {
|
|
61
|
+
return new Emitter(handler => {
|
|
62
|
+
return this.onListen((ev) => {
|
|
63
|
+
if (ev.direction < 0)
|
|
64
|
+
handler(ev);
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Creates a Promise that will be resolved when the Timeline first seeks to/past this point
|
|
70
|
+
*
|
|
71
|
+
* The resolved value indicates the direction of the seek that triggered resolution
|
|
72
|
+
*
|
|
73
|
+
* @returns A Promise, resolved when the point is triggered by a seek
|
|
74
|
+
*/
|
|
75
|
+
promise() {
|
|
76
|
+
return new Promise(resolve => {
|
|
77
|
+
let remove = this.apply((ev) => {
|
|
78
|
+
remove();
|
|
79
|
+
resolve(ev.direction);
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Registers a pair of functions to handle seeks that reach or pass this point, depending on seek direction
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* ```
|
|
88
|
+
* point
|
|
89
|
+
* .applyDirectional(
|
|
90
|
+
* element.classList.add("faded"),
|
|
91
|
+
* element.classList.remove("faded"),
|
|
92
|
+
* );
|
|
93
|
+
* ```
|
|
94
|
+
*
|
|
95
|
+
* Note, for deterministic consistency, a forward-seek triggers points when it
|
|
96
|
+
* *passes or reaches* them, while a backward-seek triggers points when it
|
|
97
|
+
* *passes or departs from* them.
|
|
98
|
+
* @param apply Handler for forward-moving seeks that pass or reach this point
|
|
99
|
+
* @param revert Handler for backward-moving seeks that pass this point
|
|
100
|
+
* @returns A function to deregister both handlers
|
|
101
|
+
*/
|
|
102
|
+
applyDirectional(apply, revert) {
|
|
103
|
+
return this.onListen(eventData => eventData.direction > 0
|
|
104
|
+
? apply()
|
|
105
|
+
: revert());
|
|
106
|
+
}
|
|
44
107
|
}
|