@xtia/timeline 1.2.0 → 1.2.2
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/internal/emitters.d.ts +7 -1
- package/internal/emitters.js +7 -1
- package/internal/timeline.d.ts +6 -8
- package/internal/timeline.js +20 -21
- package/package.json +1 -1
package/internal/emitters.d.ts
CHANGED
|
@@ -41,7 +41,7 @@ export declare class Emitter<T> {
|
|
|
41
41
|
*/
|
|
42
42
|
dedupe(compare?: (a: T, b: T) => boolean): Emitter<T>;
|
|
43
43
|
/**
|
|
44
|
-
* Creates a chainable emitter that
|
|
44
|
+
* Creates a chainable emitter that forwards emissions from the parent emitter, invoking the provided callback `cb` as a side effect for each emission.
|
|
45
45
|
*
|
|
46
46
|
* The callback `cb` is called exactly once per parent emission, regardless of how many listeners are attached to the returned emitter.
|
|
47
47
|
* All listeners attached to the returned emitter receive the same values as the parent emitter.
|
|
@@ -70,6 +70,12 @@ export declare class Emitter<T> {
|
|
|
70
70
|
* @param cb
|
|
71
71
|
*/
|
|
72
72
|
fork(...cb: ((branch: this) => void)[]): this;
|
|
73
|
+
/**
|
|
74
|
+
* Creates a chainable emitter that forwards emissions from the parent and any of the provided emitters
|
|
75
|
+
* @param emitters
|
|
76
|
+
*/
|
|
77
|
+
or(...emitters: Emitter<T>[]): Emitter<T>;
|
|
78
|
+
or<U>(...emitters: Emitter<U>[]): Emitter<T | U>;
|
|
73
79
|
}
|
|
74
80
|
export declare class RangeProgression extends Emitter<number> {
|
|
75
81
|
/**
|
package/internal/emitters.js
CHANGED
|
@@ -66,7 +66,7 @@ export class Emitter {
|
|
|
66
66
|
return new Emitter(listen);
|
|
67
67
|
}
|
|
68
68
|
/**
|
|
69
|
-
* Creates a chainable emitter that
|
|
69
|
+
* Creates a chainable emitter that forwards emissions from the parent emitter, invoking the provided callback `cb` as a side effect for each emission.
|
|
70
70
|
*
|
|
71
71
|
* The callback `cb` is called exactly once per parent emission, regardless of how many listeners are attached to the returned emitter.
|
|
72
72
|
* All listeners attached to the returned emitter receive the same values as the parent emitter.
|
|
@@ -104,6 +104,12 @@ export class Emitter {
|
|
|
104
104
|
cb.forEach(cb => cb(this));
|
|
105
105
|
return this;
|
|
106
106
|
}
|
|
107
|
+
or(...emitters) {
|
|
108
|
+
return new Emitter(handler => {
|
|
109
|
+
const unsubs = [this, ...emitters].map(e => e.listen(handler));
|
|
110
|
+
return () => unsubs.forEach(unsub => unsub());
|
|
111
|
+
});
|
|
112
|
+
}
|
|
107
113
|
}
|
|
108
114
|
export class RangeProgression extends Emitter {
|
|
109
115
|
ease(easer) {
|
package/internal/timeline.d.ts
CHANGED
|
@@ -14,20 +14,18 @@ type Period = {
|
|
|
14
14
|
asMilliseconds: number;
|
|
15
15
|
};
|
|
16
16
|
/**
|
|
17
|
-
* Creates an autoplaying
|
|
17
|
+
* Creates an autoplaying one-shot progression emitter
|
|
18
18
|
* @param durationMs Animation duration, in milliseconds
|
|
19
19
|
* @returns Object representing a range on a single-use, autoplaying Timeline
|
|
20
20
|
*/
|
|
21
|
-
export declare function animate(durationMs: number):
|
|
22
|
-
export declare function animate(period: Period):
|
|
21
|
+
export declare function animate(durationMs: number): RangeProgression;
|
|
22
|
+
export declare function animate(period: Period): RangeProgression;
|
|
23
23
|
/**
|
|
24
|
-
* Creates a looping
|
|
25
|
-
*
|
|
26
|
-
* This timeline will play while it has active listeners
|
|
24
|
+
* Creates a looping progression emitter that will play while it has active listeners
|
|
27
25
|
* @param duration Animation duration, in milliseconds, or a Period
|
|
28
|
-
* @returns Object representing a range on a
|
|
26
|
+
* @returns Object representing a range on a looping Timeline
|
|
29
27
|
*/
|
|
30
|
-
export declare function animate(duration: number | Period, looping: true):
|
|
28
|
+
export declare function animate(duration: number | Period, looping: true): RangeProgression;
|
|
31
29
|
type TimelineOptions = {
|
|
32
30
|
atEnd?: {
|
|
33
31
|
wrapAt: number;
|
package/internal/timeline.js
CHANGED
|
@@ -15,8 +15,10 @@ const createRafDriver = (tick) => {
|
|
|
15
15
|
};
|
|
16
16
|
};
|
|
17
17
|
const createIntervalDriver = (tick) => {
|
|
18
|
+
const timeSource = globalThis.performance || globalThis.Date;
|
|
19
|
+
const tickTime = () => tick(timeSource.now());
|
|
18
20
|
return () => {
|
|
19
|
-
const intervalId = setInterval(
|
|
21
|
+
const intervalId = setInterval(tickTime, 1000 / default_interval_fps);
|
|
20
22
|
return () => clearInterval(intervalId);
|
|
21
23
|
};
|
|
22
24
|
};
|
|
@@ -24,9 +26,10 @@ const masterDriver = (() => {
|
|
|
24
26
|
const timelines = new Map();
|
|
25
27
|
let previousTime = null;
|
|
26
28
|
let pause = null;
|
|
27
|
-
const
|
|
29
|
+
const stepAll = (currentTime) => {
|
|
28
30
|
if (previousTime === null) {
|
|
29
31
|
previousTime = currentTime;
|
|
32
|
+
return;
|
|
30
33
|
}
|
|
31
34
|
const delta = currentTime - previousTime;
|
|
32
35
|
previousTime = currentTime;
|
|
@@ -35,22 +38,20 @@ const masterDriver = (() => {
|
|
|
35
38
|
});
|
|
36
39
|
};
|
|
37
40
|
const start = "requestAnimationFrame" in globalThis
|
|
38
|
-
? createRafDriver(
|
|
39
|
-
: createIntervalDriver(
|
|
40
|
-
return {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
},
|
|
48
|
-
remove: (timeline) => {
|
|
41
|
+
? createRafDriver(stepAll)
|
|
42
|
+
: createIntervalDriver(stepAll);
|
|
43
|
+
return (timeline, stepFn) => {
|
|
44
|
+
timelines.set(timeline, stepFn);
|
|
45
|
+
if (timelines.size === 1) {
|
|
46
|
+
previousTime = null;
|
|
47
|
+
pause = start();
|
|
48
|
+
}
|
|
49
|
+
return () => {
|
|
49
50
|
timelines.delete(timeline);
|
|
50
51
|
if (timelines.size === 0) {
|
|
51
52
|
pause();
|
|
52
53
|
}
|
|
53
|
-
}
|
|
54
|
+
};
|
|
54
55
|
};
|
|
55
56
|
})();
|
|
56
57
|
const EndAction = {
|
|
@@ -60,11 +61,11 @@ const EndAction = {
|
|
|
60
61
|
restart: 3,
|
|
61
62
|
};
|
|
62
63
|
export function animate(duration, looping = false) {
|
|
63
|
-
const tl = new Timeline(
|
|
64
|
+
const tl = new Timeline(!looping, looping ? "wrap" : "pause");
|
|
64
65
|
const durationMs = typeof duration == "number"
|
|
65
66
|
? duration
|
|
66
67
|
: duration.asMilliseconds;
|
|
67
|
-
const parentRange = tl.range(0, durationMs)
|
|
68
|
+
const parentRange = tl.range(0, durationMs);
|
|
68
69
|
if (looping) {
|
|
69
70
|
let listeners = 0;
|
|
70
71
|
const range = new TimelineRange(h => {
|
|
@@ -78,11 +79,10 @@ export function animate(duration, looping = false) {
|
|
|
78
79
|
unsub();
|
|
79
80
|
};
|
|
80
81
|
}, tl, tl.start, tl.point(durationMs));
|
|
81
|
-
return range;
|
|
82
|
+
return range.ease(); // empty ease() to coax TimelineRange -> RangeProgression
|
|
82
83
|
}
|
|
83
84
|
else {
|
|
84
|
-
|
|
85
|
-
return parentRange;
|
|
85
|
+
return parentRange.ease();
|
|
86
86
|
}
|
|
87
87
|
}
|
|
88
88
|
export class Timeline {
|
|
@@ -411,8 +411,7 @@ export class Timeline {
|
|
|
411
411
|
this.seek(arg.start);
|
|
412
412
|
return this.seek(arg.end, arg.duration / this.timeScale, easer);
|
|
413
413
|
}
|
|
414
|
-
masterDriver
|
|
415
|
-
this._pause = () => masterDriver.remove(this);
|
|
414
|
+
this._pause = masterDriver(this, n => this.next(n));
|
|
416
415
|
}
|
|
417
416
|
next(delta) {
|
|
418
417
|
if (this._currentTime + delta <= this._endPosition) {
|