@xtia/timeline 1.1.7 → 1.1.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 +8 -8
- package/internal/point.d.ts +4 -4
- package/internal/point.js +4 -4
- package/internal/timeline.d.ts +4 -1
- package/internal/timeline.js +83 -41
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -515,6 +515,14 @@ Listeners will be invoked with a [`PointEvent`](#pointevent-interface) when a se
|
|
|
515
515
|
|
|
516
516
|
This point's position on the Timeline.
|
|
517
517
|
|
|
518
|
+
##### `forwardOnly: Emitter<PointEvent>`
|
|
519
|
+
|
|
520
|
+
Provides an emitter that forwards emissions triggered by forward-moving seeks.
|
|
521
|
+
|
|
522
|
+
##### `reverseOnly: Emitter<PointEvent>`
|
|
523
|
+
|
|
524
|
+
Provides an emitter that forwards emissions triggered by backward-moving seeks.
|
|
525
|
+
|
|
518
526
|
#### Methods
|
|
519
527
|
|
|
520
528
|
##### `range(duration): TimelineRange`
|
|
@@ -543,14 +551,6 @@ Creates a `Promise` that will be resolved when the Timeline first seeks to/past
|
|
|
543
551
|
|
|
544
552
|
The resolved value indicates the direction of the seek that triggered resolution.
|
|
545
553
|
|
|
546
|
-
##### `forwardOnly(): Emitter<PointEvent>`
|
|
547
|
-
|
|
548
|
-
Creates an emitter that forwards emissions triggered by forward-moving seeks.
|
|
549
|
-
|
|
550
|
-
##### `reverseOnly(): Emitter<PointEvent>`
|
|
551
|
-
|
|
552
|
-
Creates an emitter that forwards emissions triggered by backward-moving seeks.
|
|
553
|
-
|
|
554
554
|
##### `applyDirectional(apply, revert): UnsubscribeFunc`
|
|
555
555
|
|
|
556
556
|
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.
|
package/internal/point.d.ts
CHANGED
|
@@ -46,16 +46,16 @@ export declare class TimelinePoint extends Emitter<PointEvent> {
|
|
|
46
46
|
*/
|
|
47
47
|
seek(duration: number, easer?: Easer): Promise<void>;
|
|
48
48
|
/**
|
|
49
|
-
*
|
|
49
|
+
* An point emitter that only emits on forward-moving seeks
|
|
50
50
|
* @returns Listenable: emits forward-seeking point events
|
|
51
51
|
*/
|
|
52
|
-
forwardOnly(): Emitter<PointEvent>;
|
|
52
|
+
get forwardOnly(): Emitter<PointEvent>;
|
|
53
53
|
private _forwardOnly?;
|
|
54
54
|
/**
|
|
55
|
-
*
|
|
55
|
+
* An point emitter that only emits on backward-moving seeks
|
|
56
56
|
* @returns Listenable: emits backward-seeking point events
|
|
57
57
|
*/
|
|
58
|
-
reverseOnly(): Emitter<PointEvent>;
|
|
58
|
+
get reverseOnly(): Emitter<PointEvent>;
|
|
59
59
|
private _reverseOnly?;
|
|
60
60
|
filter(check: (event: PointEvent) => boolean): Emitter<PointEvent>;
|
|
61
61
|
/**
|
package/internal/point.js
CHANGED
|
@@ -41,19 +41,19 @@ export class TimelinePoint extends Emitter {
|
|
|
41
41
|
return this.timeline.seek(this.position, duration, easer);
|
|
42
42
|
}
|
|
43
43
|
/**
|
|
44
|
-
*
|
|
44
|
+
* An point emitter that only emits on forward-moving seeks
|
|
45
45
|
* @returns Listenable: emits forward-seeking point events
|
|
46
46
|
*/
|
|
47
|
-
forwardOnly() {
|
|
47
|
+
get forwardOnly() {
|
|
48
48
|
if (!this._forwardOnly)
|
|
49
49
|
this._forwardOnly = this.filter(1);
|
|
50
50
|
return this._forwardOnly;
|
|
51
51
|
}
|
|
52
52
|
/**
|
|
53
|
-
*
|
|
53
|
+
* An point emitter that only emits on backward-moving seeks
|
|
54
54
|
* @returns Listenable: emits backward-seeking point events
|
|
55
55
|
*/
|
|
56
|
-
reverseOnly() {
|
|
56
|
+
get reverseOnly() {
|
|
57
57
|
if (!this._reverseOnly)
|
|
58
58
|
this._reverseOnly = this.filter(-1);
|
|
59
59
|
return this._reverseOnly;
|
package/internal/timeline.d.ts
CHANGED
|
@@ -42,7 +42,7 @@ export declare class Timeline {
|
|
|
42
42
|
get end(): TimelinePoint;
|
|
43
43
|
private _currentTime;
|
|
44
44
|
private _endPosition;
|
|
45
|
-
private
|
|
45
|
+
private _pause;
|
|
46
46
|
private points;
|
|
47
47
|
private endAction;
|
|
48
48
|
private ranges;
|
|
@@ -147,6 +147,9 @@ export declare class Timeline {
|
|
|
147
147
|
* Performs a smooth-seek through a range at (1000 × this.timeScale) units per second
|
|
148
148
|
*/
|
|
149
149
|
play(range: TimelineRange, easer?: Easer): Promise<void>;
|
|
150
|
+
private playWithInterval;
|
|
151
|
+
private playWithRAF;
|
|
152
|
+
private next;
|
|
150
153
|
/**
|
|
151
154
|
* Stops normal progression instigated by play()
|
|
152
155
|
*
|
package/internal/timeline.js
CHANGED
|
@@ -3,6 +3,8 @@ import { TimelinePoint } from "./point";
|
|
|
3
3
|
import { TimelineRange } from "./range";
|
|
4
4
|
import { clamp } from "./utils";
|
|
5
5
|
const default_fps = 60;
|
|
6
|
+
const requestAnimFrame = globalThis?.requestAnimationFrame;
|
|
7
|
+
const cancelAnimFrame = globalThis?.cancelAnimationFrame;
|
|
6
8
|
const EndAction = {
|
|
7
9
|
pause: 0,
|
|
8
10
|
continue: 1,
|
|
@@ -27,7 +29,7 @@ export class Timeline {
|
|
|
27
29
|
* Returns true if this Timeline is currently progressing via `play()`, otherwise false
|
|
28
30
|
*/
|
|
29
31
|
get isPlaying() {
|
|
30
|
-
return this.
|
|
32
|
+
return !!this._pause;
|
|
31
33
|
}
|
|
32
34
|
/**
|
|
33
35
|
* Returns a fixed point at the current end of the Timeline
|
|
@@ -71,7 +73,7 @@ export class Timeline {
|
|
|
71
73
|
this.timeScale = 1;
|
|
72
74
|
this._currentTime = 0;
|
|
73
75
|
this._endPosition = 0;
|
|
74
|
-
this.
|
|
76
|
+
this._pause = null;
|
|
75
77
|
this.points = [];
|
|
76
78
|
this.ranges = [];
|
|
77
79
|
this.currentSortDirection = 0;
|
|
@@ -311,9 +313,8 @@ export class Timeline {
|
|
|
311
313
|
? sortTweens
|
|
312
314
|
: sortReverse);
|
|
313
315
|
}
|
|
314
|
-
play(arg
|
|
315
|
-
|
|
316
|
-
this.pause();
|
|
316
|
+
play(arg, easer) {
|
|
317
|
+
this._pause?.();
|
|
317
318
|
if (this.smoothSeeker) {
|
|
318
319
|
this.smoothSeeker.pause();
|
|
319
320
|
this.smoothSeeker.seek(this.smoothSeeker.end);
|
|
@@ -323,44 +324,72 @@ export class Timeline {
|
|
|
323
324
|
this.seek(arg.start);
|
|
324
325
|
return this.seek(arg.end, arg.duration / this.timeScale, easer);
|
|
325
326
|
}
|
|
327
|
+
if (arg !== undefined && requestAnimFrame) {
|
|
328
|
+
this.playWithRAF();
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
331
|
+
this.playWithInterval(arg ?? default_fps);
|
|
332
|
+
}
|
|
333
|
+
playWithInterval(fps) {
|
|
326
334
|
let previousTime = Date.now();
|
|
327
|
-
|
|
335
|
+
const interval = setInterval(() => {
|
|
328
336
|
const newTime = Date.now();
|
|
329
337
|
const elapsed = newTime - previousTime;
|
|
330
338
|
previousTime = newTime;
|
|
331
339
|
let delta = elapsed * this.timeScale;
|
|
332
|
-
|
|
333
|
-
|
|
340
|
+
this.next(delta);
|
|
341
|
+
}, 1000 / fps);
|
|
342
|
+
this._pause = () => clearInterval(interval);
|
|
343
|
+
}
|
|
344
|
+
playWithRAF() {
|
|
345
|
+
let previousTime = null;
|
|
346
|
+
let rafId;
|
|
347
|
+
const frame = (currentTime) => {
|
|
348
|
+
if (previousTime === null) {
|
|
349
|
+
previousTime = currentTime;
|
|
350
|
+
}
|
|
351
|
+
const elapsed = currentTime - previousTime;
|
|
352
|
+
previousTime = currentTime;
|
|
353
|
+
let delta = elapsed * this.timeScale;
|
|
354
|
+
this.next(delta);
|
|
355
|
+
rafId = requestAnimFrame(frame);
|
|
356
|
+
};
|
|
357
|
+
rafId = requestAnimFrame(frame);
|
|
358
|
+
this._pause = () => cancelAnimFrame(rafId);
|
|
359
|
+
}
|
|
360
|
+
next(delta) {
|
|
361
|
+
if (this._currentTime + delta <= this._endPosition) {
|
|
362
|
+
this.currentTime += delta;
|
|
363
|
+
return;
|
|
364
|
+
}
|
|
365
|
+
// overshot; perform restart/pause endAction
|
|
366
|
+
if (this.endAction.type == EndAction.restart) {
|
|
367
|
+
const loopRange = this.endAction.at.to(this._endPosition);
|
|
368
|
+
const loopLen = loopRange.duration;
|
|
369
|
+
if (loopLen <= 0) {
|
|
370
|
+
const target = Math.min(this._currentTime + delta, this._endPosition);
|
|
371
|
+
this.seek(target);
|
|
334
372
|
return;
|
|
335
373
|
}
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
if (loopLen <= 0) {
|
|
341
|
-
const target = Math.min(this._currentTime + delta, this._endPosition);
|
|
342
|
-
this.seek(target);
|
|
374
|
+
while (delta > 0) {
|
|
375
|
+
const distanceToEnd = this._endPosition - this._currentTime;
|
|
376
|
+
if (delta < distanceToEnd) {
|
|
377
|
+
this.seek(this._currentTime + delta);
|
|
343
378
|
return;
|
|
344
379
|
}
|
|
345
|
-
while (delta > 0) {
|
|
346
|
-
const distanceToEnd = this._endPosition - this._currentTime;
|
|
347
|
-
if (delta < distanceToEnd) {
|
|
348
|
-
this.seek(this._currentTime + delta);
|
|
349
|
-
return;
|
|
350
|
-
}
|
|
351
|
-
this.seek(this._endPosition);
|
|
352
|
-
delta -= distanceToEnd;
|
|
353
|
-
this.seek(this.endAction.at);
|
|
354
|
-
}
|
|
355
|
-
return;
|
|
356
|
-
}
|
|
357
|
-
if (this.endAction.type == EndAction.pause) {
|
|
358
380
|
this.seek(this._endPosition);
|
|
359
|
-
|
|
360
|
-
|
|
381
|
+
delta -= distanceToEnd;
|
|
382
|
+
this.seek(this.endAction.at);
|
|
361
383
|
}
|
|
362
|
-
|
|
363
|
-
}
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
386
|
+
if (this.endAction.type == EndAction.pause) {
|
|
387
|
+
this.seek(this._endPosition);
|
|
388
|
+
this.pause();
|
|
389
|
+
return;
|
|
390
|
+
}
|
|
391
|
+
// endaction must be "continue" or "wrap"
|
|
392
|
+
this.currentTime += delta;
|
|
364
393
|
}
|
|
365
394
|
/**
|
|
366
395
|
* Stops normal progression instigated by play()
|
|
@@ -369,10 +398,10 @@ export class Timeline {
|
|
|
369
398
|
*
|
|
370
399
|
*/
|
|
371
400
|
pause() {
|
|
372
|
-
if (this.
|
|
401
|
+
if (this._pause === null)
|
|
373
402
|
return;
|
|
374
|
-
|
|
375
|
-
this.
|
|
403
|
+
this._pause();
|
|
404
|
+
this._pause = null;
|
|
376
405
|
}
|
|
377
406
|
step(delta = 1) {
|
|
378
407
|
this.currentTime += delta * this.timeScale;
|
|
@@ -398,12 +427,25 @@ export class Timeline {
|
|
|
398
427
|
*/
|
|
399
428
|
at(position, action, reverse) {
|
|
400
429
|
const point = typeof position == "number" ? this.point(position) : position;
|
|
401
|
-
if (
|
|
402
|
-
reverse
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
430
|
+
if (!action) {
|
|
431
|
+
if (reverse) {
|
|
432
|
+
if (reverse === true)
|
|
433
|
+
throw new Error("Invalid call");
|
|
434
|
+
point.reverseOnly.apply(reverse);
|
|
435
|
+
}
|
|
436
|
+
return this.createChainingInterface(point.position);
|
|
437
|
+
}
|
|
438
|
+
if (reverse) {
|
|
439
|
+
if (reverse === true) {
|
|
440
|
+
point.apply(action);
|
|
441
|
+
}
|
|
442
|
+
else {
|
|
443
|
+
point.applyDirectional(action, reverse);
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
else {
|
|
447
|
+
point.forwardOnly.apply(action);
|
|
448
|
+
}
|
|
407
449
|
return this.createChainingInterface(point.position);
|
|
408
450
|
}
|
|
409
451
|
createChainingInterface(position) {
|