chnobli 0.1.9 → 0.1.11
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/dist/animation/Animation.d.ts +37 -0
- package/dist/animation/Animation.d.ts.map +1 -0
- package/dist/animation/Animation.js +232 -0
- package/dist/animation/Animation.js.map +1 -0
- package/dist/animation/public.d.ts +68 -0
- package/dist/animation/public.d.ts.map +1 -0
- package/dist/animation/public.js +115 -0
- package/dist/animation/public.js.map +1 -0
- package/dist/animator/Animator.d.ts +30 -0
- package/dist/animator/Animator.d.ts.map +1 -0
- package/dist/animator/Animator.js +97 -0
- package/dist/animator/Animator.js.map +1 -0
- package/dist/animator/index.d.ts +5 -0
- package/dist/animator/index.d.ts.map +1 -0
- package/dist/animator/index.js +53 -0
- package/dist/animator/index.js.map +1 -0
- package/dist/animator/public.d.ts +16 -0
- package/dist/animator/public.d.ts.map +1 -0
- package/dist/animator/public.js +50 -0
- package/dist/animator/public.js.map +1 -0
- package/dist/chnobli.d.ts +15 -0
- package/dist/chnobli.d.ts.map +1 -0
- package/dist/chnobli.js +59 -0
- package/dist/chnobli.js.map +1 -0
- package/dist/property/BasicProperty.d.ts +38 -0
- package/dist/property/BasicProperty.d.ts.map +1 -0
- package/dist/property/BasicProperty.js +72 -0
- package/dist/property/BasicProperty.js.map +1 -0
- package/dist/property/ClassProperty.d.ts +32 -0
- package/dist/property/ClassProperty.d.ts.map +1 -0
- package/dist/property/ClassProperty.js +108 -0
- package/dist/property/ClassProperty.js.map +1 -0
- package/dist/property/Property.d.ts +13 -0
- package/dist/property/Property.d.ts.map +1 -0
- package/dist/property/Property.js +22 -0
- package/dist/property/Property.js.map +1 -0
- package/dist/property/StyleProperty.d.ts +25 -0
- package/dist/property/StyleProperty.d.ts.map +1 -0
- package/dist/property/StyleProperty.js +221 -0
- package/dist/property/StyleProperty.js.map +1 -0
- package/dist/property/TransformProperty.d.ts +15 -0
- package/dist/property/TransformProperty.d.ts.map +1 -0
- package/dist/property/TransformProperty.js +43 -0
- package/dist/property/TransformProperty.js.map +1 -0
- package/dist/property/TransformXYProperty.d.ts +28 -0
- package/dist/property/TransformXYProperty.d.ts.map +1 -0
- package/dist/property/TransformXYProperty.js +65 -0
- package/dist/property/TransformXYProperty.js.map +1 -0
- package/dist/responsive/ResponsiveEvent.d.ts +17 -0
- package/dist/responsive/ResponsiveEvent.d.ts.map +1 -0
- package/dist/responsive/ResponsiveEvent.js +45 -0
- package/dist/responsive/ResponsiveEvent.js.map +1 -0
- package/dist/responsive/TestEvent.d.ts +11 -0
- package/dist/responsive/TestEvent.d.ts.map +1 -0
- package/dist/responsive/TestEvent.js +26 -0
- package/dist/responsive/TestEvent.js.map +1 -0
- package/dist/scroll/Scroll.d.ts +61 -0
- package/dist/scroll/Scroll.d.ts.map +1 -0
- package/dist/scroll/Scroll.js +280 -0
- package/dist/scroll/Scroll.js.map +1 -0
- package/dist/scroll/ScrollEvent.d.ts +17 -0
- package/dist/scroll/ScrollEvent.d.ts.map +1 -0
- package/dist/scroll/ScrollEvent.js +40 -0
- package/dist/scroll/ScrollEvent.js.map +1 -0
- package/dist/scroll/index.d.ts +8 -0
- package/dist/scroll/index.d.ts.map +1 -0
- package/dist/scroll/index.js +9 -0
- package/dist/scroll/index.js.map +1 -0
- package/dist/scroll/public.d.ts +35 -0
- package/dist/scroll/public.d.ts.map +1 -0
- package/dist/scroll/public.js +50 -0
- package/dist/scroll/public.js.map +1 -0
- package/dist/stagger/stagger.d.ts +20 -0
- package/dist/stagger/stagger.d.ts.map +1 -0
- package/dist/stagger/stagger.js +43 -0
- package/dist/stagger/stagger.js.map +1 -0
- package/dist/target/BaseTarget.old.d.ts +33 -0
- package/dist/target/BaseTarget.old.d.ts.map +1 -0
- package/dist/target/BaseTarget.old.js +73 -0
- package/dist/target/BaseTarget.old.js.map +1 -0
- package/dist/target/DomTarget.d.ts +41 -0
- package/dist/target/DomTarget.d.ts.map +1 -0
- package/dist/target/DomTarget.js +230 -0
- package/dist/target/DomTarget.js.map +1 -0
- package/dist/target/ObjectTarget.d.ts +31 -0
- package/dist/target/ObjectTarget.d.ts.map +1 -0
- package/dist/target/ObjectTarget.js +108 -0
- package/dist/target/ObjectTarget.js.map +1 -0
- package/dist/target/Target.d.ts +25 -0
- package/dist/target/Target.d.ts.map +1 -0
- package/dist/target/Target.js +25 -0
- package/dist/target/Target.js.map +1 -0
- package/dist/target/TestDomNode.d.ts +14 -0
- package/dist/target/TestDomNode.d.ts.map +1 -0
- package/dist/target/TestDomNode.js +55 -0
- package/dist/target/TestDomNode.js.map +1 -0
- package/dist/timeline/Nested.d.ts +30 -0
- package/dist/timeline/Nested.d.ts.map +1 -0
- package/dist/timeline/Nested.js +51 -0
- package/dist/timeline/Nested.js.map +1 -0
- package/dist/timeline/Timeline.d.ts +42 -0
- package/dist/timeline/Timeline.d.ts.map +1 -0
- package/dist/timeline/Timeline.js +306 -0
- package/dist/timeline/Timeline.js.map +1 -0
- package/dist/timeline/public.d.ts +167 -0
- package/dist/timeline/public.d.ts.map +1 -0
- package/dist/timeline/public.js +396 -0
- package/dist/timeline/public.js.map +1 -0
- package/dist/timing/AnimationFrameTicker.d.ts +32 -0
- package/dist/timing/AnimationFrameTicker.d.ts.map +1 -0
- package/dist/timing/AnimationFrameTicker.js +138 -0
- package/dist/timing/AnimationFrameTicker.js.map +1 -0
- package/dist/timing/Ease.d.ts +6 -0
- package/dist/timing/Ease.d.ts.map +1 -0
- package/dist/timing/Ease.js +15 -0
- package/dist/timing/Ease.js.map +1 -0
- package/dist/timing/TestTicker.d.ts +19 -0
- package/dist/timing/TestTicker.d.ts.map +1 -0
- package/dist/timing/TestTicker.js +85 -0
- package/dist/timing/TestTicker.js.map +1 -0
- package/dist/timing/Ticker.d.ts +16 -0
- package/dist/timing/Ticker.d.ts.map +1 -0
- package/dist/timing/Ticker.js +2 -0
- package/dist/timing/Ticker.js.map +1 -0
- package/dist/timing/Timing.d.ts +116 -0
- package/dist/timing/Timing.d.ts.map +1 -0
- package/dist/timing/Timing.js +310 -0
- package/dist/timing/Timing.js.map +1 -0
- package/dist/timing/easing.d.ts +158 -0
- package/dist/timing/easing.d.ts.map +1 -0
- package/dist/timing/easing.js +273 -0
- package/dist/timing/easing.js.map +1 -0
- package/dist/utils/Events.d.ts +9 -0
- package/dist/utils/Events.d.ts.map +1 -0
- package/dist/utils/Events.js +35 -0
- package/dist/utils/Events.js.map +1 -0
- package/dist/utils/internal.d.ts +5 -0
- package/dist/utils/internal.d.ts.map +1 -0
- package/dist/utils/internal.js +9 -0
- package/dist/utils/internal.js.map +1 -0
- package/dist/utils/motionpath.d.ts +16 -0
- package/dist/utils/motionpath.d.ts.map +1 -0
- package/dist/utils/motionpath.js +41 -0
- package/dist/utils/motionpath.js.map +1 -0
- package/dist/utils/utils.d.ts +44 -0
- package/dist/utils/utils.d.ts.map +1 -0
- package/dist/utils/utils.js +88 -0
- package/dist/utils/utils.js.map +1 -0
- package/dist/values/ColorValue.d.ts +12 -0
- package/dist/values/ColorValue.d.ts.map +1 -0
- package/dist/values/ColorValue.js +134 -0
- package/dist/values/ColorValue.js.map +1 -0
- package/dist/values/StyleValue.d.ts +41 -0
- package/dist/values/StyleValue.d.ts.map +1 -0
- package/dist/values/StyleValue.js +159 -0
- package/dist/values/StyleValue.js.map +1 -0
- package/dist/values/Value.d.ts +13 -0
- package/dist/values/Value.d.ts.map +1 -0
- package/dist/values/Value.js +38 -0
- package/dist/values/Value.js.map +1 -0
- package/dist/values/defaultcolors.d.ts +2 -0
- package/dist/values/defaultcolors.d.ts.map +1 -0
- package/dist/values/defaultcolors.js +149 -0
- package/dist/values/defaultcolors.js.map +1 -0
- package/eslint.config.js +23 -0
- package/package.json +10 -3
- package/src/animation/Animation.ts +6 -3
- package/src/animator/Animator.ts +130 -0
- package/src/animator/index.ts +56 -0
- package/src/animator/public.ts +66 -0
- package/src/chnobli.ts +3 -2
- package/src/property/ClassProperty.ts +1 -1
- package/src/property/TransformXYProperty.ts +1 -1
- package/src/scroll/Scroll.ts +202 -51
- package/src/scroll/ScrollEvent.ts +1 -0
- package/src/scroll/index.ts +3 -0
- package/src/scroll/public.ts +35 -2
- package/src/target/DomTarget.ts +1 -1
- package/src/target/ObjectTarget.ts +19 -13
- package/src/tests/properties.test.ts +44 -3
- package/src/tests/timeline.test.ts +1 -1
- package/src/tests/timing.test.ts +32 -0
- package/src/tests/usecases.test.ts +40 -2
- package/src/tests/values.test.ts +9 -9
- package/src/timeline/Timeline.ts +5 -4
- package/src/timeline/public.ts +34 -12
- package/src/timing/AnimationFrameTicker.ts +6 -1
- package/src/timing/TestTicker.ts +7 -1
- package/src/timing/Ticker.ts +5 -1
- package/src/timing/Timing.ts +127 -91
- package/src/utils/Events.ts +1 -1
- package/src/utils/motionpath.ts +5 -5
- package/src/utils/utils.ts +0 -10
- package/src/values/ColorValue.ts +1 -0
- package/src/values/Value.ts +1 -1
- package/.eslintrc.cjs +0 -39
- package/src/animator.js +0 -187
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { describe, expect, it } from 'vitest';
|
|
2
2
|
import TestTicker from '../timing/TestTicker.js';
|
|
3
3
|
import TestResponsiveEvent from '../responsive/TestEvent.js';
|
|
4
|
-
import {
|
|
5
|
-
import { responsive } from '../utils/utils.js';
|
|
4
|
+
import { timeline } from '../chnobli.js';
|
|
5
|
+
import { fromTo, responsive } from '../utils/utils.js';
|
|
6
6
|
import { el } from '../target/TestDomNode.js';
|
|
7
7
|
|
|
8
8
|
describe('usecases', () => {
|
|
@@ -64,4 +64,42 @@ describe('usecases', () => {
|
|
|
64
64
|
expect(ctn.style.maxHeight).toBe(undefined);
|
|
65
65
|
expect(itm.classList.contains('open')).toBe(false);
|
|
66
66
|
});
|
|
67
|
+
|
|
68
|
+
it('accordion2', () => {
|
|
69
|
+
const ticker = new TestTicker();
|
|
70
|
+
const _respEv = new TestResponsiveEvent();
|
|
71
|
+
|
|
72
|
+
const ctn = el();
|
|
73
|
+
ctn.computedStyle.maxHeight = 'none';
|
|
74
|
+
// @ts-ignore
|
|
75
|
+
ctn.scrollHeight = '100px';
|
|
76
|
+
|
|
77
|
+
const tl = timeline({ reversed: true }).add(ctn, {
|
|
78
|
+
height: fromTo(
|
|
79
|
+
0,
|
|
80
|
+
responsive(el => el.scrollHeight),
|
|
81
|
+
),
|
|
82
|
+
duration: 100,
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
const toggle = () => {
|
|
86
|
+
tl.reverse();
|
|
87
|
+
tl.play();
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
// on click reverse or not
|
|
91
|
+
toggle();
|
|
92
|
+
ticker.run(1);
|
|
93
|
+
expect(ctn.style.height).toBe('1.000px');
|
|
94
|
+
ticker.run(49);
|
|
95
|
+
expect(ctn.style.height).toBe('50.000px');
|
|
96
|
+
toggle();
|
|
97
|
+
ticker.run(1);
|
|
98
|
+
expect(ctn.style.height).toBe('49.000px');
|
|
99
|
+
ticker.run(29);
|
|
100
|
+
expect(ctn.style.height).toBe('20.000px');
|
|
101
|
+
toggle();
|
|
102
|
+
ticker.run(1);
|
|
103
|
+
expect(ctn.style.height).toBe('21.000px');
|
|
104
|
+
});
|
|
67
105
|
});
|
package/src/tests/values.test.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { describe, expect, it } from 'vitest';
|
|
2
2
|
import TestTicker from '../timing/TestTicker.js';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { timeline } from '../chnobli.js';
|
|
4
|
+
import { from, fromTo } from '../utils/utils.js';
|
|
5
5
|
import { el, getRootElement } from '../target/TestDomNode.js';
|
|
6
6
|
|
|
7
7
|
describe('values', () => {
|
|
@@ -12,7 +12,7 @@ describe('values', () => {
|
|
|
12
12
|
root.computedStyle.fontSize = '13px';
|
|
13
13
|
|
|
14
14
|
const div = el();
|
|
15
|
-
const
|
|
15
|
+
const _tl = timeline()
|
|
16
16
|
.add(div, {
|
|
17
17
|
width: '10rem',
|
|
18
18
|
duration: 5,
|
|
@@ -35,7 +35,7 @@ describe('values', () => {
|
|
|
35
35
|
|
|
36
36
|
const div = el();
|
|
37
37
|
div.computedStyle.width = '10px';
|
|
38
|
-
const
|
|
38
|
+
const _tl = timeline()
|
|
39
39
|
.add(div, {
|
|
40
40
|
x: '10%',
|
|
41
41
|
width: '50%',
|
|
@@ -62,7 +62,7 @@ describe('values', () => {
|
|
|
62
62
|
|
|
63
63
|
const div = el();
|
|
64
64
|
div.computedStyle.padding = '5px';
|
|
65
|
-
const
|
|
65
|
+
const _tl = timeline()
|
|
66
66
|
.add(div, {
|
|
67
67
|
padding: '10px 20rem',
|
|
68
68
|
duration: 10,
|
|
@@ -81,7 +81,7 @@ describe('values', () => {
|
|
|
81
81
|
|
|
82
82
|
const div = el();
|
|
83
83
|
div.computedStyle.display = 'block';
|
|
84
|
-
const
|
|
84
|
+
const _tl = timeline()
|
|
85
85
|
.add(div, {
|
|
86
86
|
display: 'none',
|
|
87
87
|
position: from('absolute'),
|
|
@@ -100,7 +100,7 @@ describe('values', () => {
|
|
|
100
100
|
expect(div.style.position).toBe(undefined);
|
|
101
101
|
expect(div.style.visibility).toBe('visible');
|
|
102
102
|
|
|
103
|
-
|
|
103
|
+
_tl.seek(-1);
|
|
104
104
|
ticker.run();
|
|
105
105
|
expect(div.style.display).toBe(undefined);
|
|
106
106
|
expect(div.style.position).toBe(undefined);
|
|
@@ -112,7 +112,7 @@ describe('values', () => {
|
|
|
112
112
|
const div = el();
|
|
113
113
|
div.computedStyle.color = 'rgb(120, 130, 20)';
|
|
114
114
|
|
|
115
|
-
const
|
|
115
|
+
const _tl = timeline()
|
|
116
116
|
.add(div, {
|
|
117
117
|
color: 'black',
|
|
118
118
|
backgroundColor: 'hsl(10, 80%, 40%)',
|
|
@@ -139,7 +139,7 @@ describe('values', () => {
|
|
|
139
139
|
div.computedStyle['--color'] = 'rgb(120, 130, 20)';
|
|
140
140
|
div.computedStyle['--border'] = '20px';
|
|
141
141
|
|
|
142
|
-
const
|
|
142
|
+
const _tl = timeline()
|
|
143
143
|
.add(div, {
|
|
144
144
|
'--color': 'black',
|
|
145
145
|
'--border': '1px 20px',
|
package/src/timeline/Timeline.ts
CHANGED
|
@@ -10,6 +10,7 @@ import Timing, {
|
|
|
10
10
|
import Ticker from '../timing/Ticker.js';
|
|
11
11
|
import Animation from '../animation/Animation.js';
|
|
12
12
|
import AnimationFrameTicker from '../timing/AnimationFrameTicker.js';
|
|
13
|
+
import { DestroyOptions } from './public.js';
|
|
13
14
|
|
|
14
15
|
type Entry = {
|
|
15
16
|
type: 'label' | 'animation' | 'timeline';
|
|
@@ -185,7 +186,7 @@ export default class Timeline {
|
|
|
185
186
|
|
|
186
187
|
const pos = this.entries[i - 1 - entry.relativeOffset]?.end ?? 0;
|
|
187
188
|
|
|
188
|
-
|
|
189
|
+
const start = offset.calculate(pos);
|
|
189
190
|
if (start < 0) throw new Error('cannot go in the past start < 0');
|
|
190
191
|
|
|
191
192
|
let end = start;
|
|
@@ -325,17 +326,17 @@ export default class Timeline {
|
|
|
325
326
|
this.ticker.applyTargets();
|
|
326
327
|
}
|
|
327
328
|
|
|
328
|
-
destroy() {
|
|
329
|
+
destroy(opts: DestroyOptions) {
|
|
329
330
|
for (const entry of this.entries) {
|
|
330
331
|
if (entry.type === 'timeline') {
|
|
331
|
-
entry.value.destroy();
|
|
332
|
+
entry.value.destroy(opts);
|
|
332
333
|
continue;
|
|
333
334
|
}
|
|
334
335
|
|
|
335
336
|
if (entry.type !== 'animation') continue;
|
|
336
337
|
|
|
337
338
|
const animation = entry.value;
|
|
338
|
-
animation.destroy();
|
|
339
|
+
animation.destroy(opts);
|
|
339
340
|
}
|
|
340
341
|
|
|
341
342
|
this.entries = [];
|
package/src/timeline/public.ts
CHANGED
|
@@ -38,12 +38,21 @@ export type TimelineProps = {
|
|
|
38
38
|
// alternate
|
|
39
39
|
// reversed
|
|
40
40
|
|
|
41
|
+
/**
|
|
42
|
+
* When set will keep all values when destroy is called
|
|
43
|
+
*/
|
|
44
|
+
keepValues?: boolean;
|
|
45
|
+
|
|
41
46
|
// other properties
|
|
42
47
|
[key: string]: any;
|
|
43
48
|
};
|
|
44
49
|
|
|
45
50
|
export type Offset = number | string | Stagger<number | string>;
|
|
46
51
|
|
|
52
|
+
export type DestroyOptions = {
|
|
53
|
+
keepValues?: boolean;
|
|
54
|
+
};
|
|
55
|
+
|
|
47
56
|
export default class PublicTimeline {
|
|
48
57
|
/**
|
|
49
58
|
* @ignore
|
|
@@ -60,13 +69,14 @@ export default class PublicTimeline {
|
|
|
60
69
|
private _triggeredStart: boolean;
|
|
61
70
|
|
|
62
71
|
private _state: number;
|
|
63
|
-
private _renderedOnce: boolean;
|
|
64
72
|
private _runningTicker: any;
|
|
65
73
|
private _responsiveBlocks: { responsive: () => void }[];
|
|
66
74
|
private _responsiveEvent: any;
|
|
67
75
|
private _smoothSeek: SmoothSeek | null;
|
|
68
76
|
private _seekTo: number;
|
|
69
77
|
|
|
78
|
+
private _destroyOpts: DestroyOptions;
|
|
79
|
+
|
|
70
80
|
constructor(props: TimelineProps = {}) {
|
|
71
81
|
this._defaults = takeProp(props, 'defaults', {});
|
|
72
82
|
this._responsive = takeProp(props, 'responsive', true);
|
|
@@ -81,6 +91,12 @@ export default class PublicTimeline {
|
|
|
81
91
|
);
|
|
82
92
|
this._seekTo = 0;
|
|
83
93
|
|
|
94
|
+
this._destroyOpts = {
|
|
95
|
+
// we set this to undefined so we can have other default values
|
|
96
|
+
// for example in chnobli-svelte
|
|
97
|
+
keepValues: takeProp(props, 'keepValues', undefined),
|
|
98
|
+
};
|
|
99
|
+
|
|
84
100
|
this._inner = new Timeline(props);
|
|
85
101
|
|
|
86
102
|
// 'start', 'end'
|
|
@@ -88,7 +104,6 @@ export default class PublicTimeline {
|
|
|
88
104
|
this._triggeredStart = false;
|
|
89
105
|
|
|
90
106
|
this._state = STATE_PAUSED;
|
|
91
|
-
this._renderedOnce = false;
|
|
92
107
|
this._runningTicker = null;
|
|
93
108
|
this._responsiveBlocks = [];
|
|
94
109
|
if (this._responsive) {
|
|
@@ -227,7 +242,7 @@ export default class PublicTimeline {
|
|
|
227
242
|
this._inner.init();
|
|
228
243
|
|
|
229
244
|
if (this._smoothSeek) {
|
|
230
|
-
this._smoothSeek.update(this._inner.timing.
|
|
245
|
+
this._smoothSeek.update(this._inner.timing.positionAbsolute(), pos);
|
|
231
246
|
|
|
232
247
|
if (this._state !== STATE_PLAYING) this._state = STATE_SEEK;
|
|
233
248
|
} else {
|
|
@@ -331,9 +346,11 @@ export default class PublicTimeline {
|
|
|
331
346
|
/**
|
|
332
347
|
* Destroys this timeline and resets all props
|
|
333
348
|
*/
|
|
334
|
-
destroy() {
|
|
349
|
+
destroy(opts: DestroyOptions = {}) {
|
|
350
|
+
opts.keepValues = opts.keepValues ?? this._destroyOpts.keepValues;
|
|
351
|
+
|
|
335
352
|
this._stopTicker();
|
|
336
|
-
this._inner.destroy();
|
|
353
|
+
this._inner.destroy(opts);
|
|
337
354
|
this._events.destroy();
|
|
338
355
|
this._responsiveEvent?.remove();
|
|
339
356
|
this._responsiveBlocks = [];
|
|
@@ -360,7 +377,7 @@ export default class PublicTimeline {
|
|
|
360
377
|
const smoothSeekEnded = () =>
|
|
361
378
|
!this._smoothSeek || this._smoothSeek.state >= STATE_ENDED;
|
|
362
379
|
|
|
363
|
-
this._runningTicker = this._inner.ticker.add(change => {
|
|
380
|
+
this._runningTicker = this._inner.ticker.add((change, api) => {
|
|
364
381
|
if (!this._triggeredStart) {
|
|
365
382
|
// todo check that we are at the start
|
|
366
383
|
if (this._inner.timing.state <= STATE_BEFORE) {
|
|
@@ -385,11 +402,19 @@ export default class PublicTimeline {
|
|
|
385
402
|
}
|
|
386
403
|
|
|
387
404
|
this._inner.render();
|
|
405
|
+
const pos = this._inner.timing.position;
|
|
406
|
+
api.onApplied(() => {
|
|
407
|
+
this._events.trigger('update', pos);
|
|
408
|
+
});
|
|
388
409
|
|
|
389
410
|
// we rendered once let's stop
|
|
390
411
|
const renderOnce = this._state === STATE_RENDER_ONCE;
|
|
391
412
|
|
|
392
|
-
if (
|
|
413
|
+
if (
|
|
414
|
+
renderOnce ||
|
|
415
|
+
(smoothSeekEnded() &&
|
|
416
|
+
(this._state === STATE_SEEK || timingEnded()))
|
|
417
|
+
) {
|
|
393
418
|
this._maybeTriggerEndEvent();
|
|
394
419
|
|
|
395
420
|
this._state = STATE_PAUSED;
|
|
@@ -413,12 +438,9 @@ export default class PublicTimeline {
|
|
|
413
438
|
* @ignore
|
|
414
439
|
*/
|
|
415
440
|
_onResponsive(
|
|
416
|
-
|
|
417
|
-
|
|
441
|
+
_a: { width: number; height: number },
|
|
442
|
+
_b: { remove: () => void },
|
|
418
443
|
) {
|
|
419
|
-
// // make sure we don't render something if we never did
|
|
420
|
-
// if (!this._renderedOnce)
|
|
421
|
-
// return;
|
|
422
444
|
this._inner.update();
|
|
423
445
|
}
|
|
424
446
|
}
|
|
@@ -91,16 +91,21 @@ export default class AnimationFrameTicker implements Ticker {
|
|
|
91
91
|
this._previousTick = elapsed;
|
|
92
92
|
|
|
93
93
|
// const changes = new PropertyChanges;
|
|
94
|
+
const onApplied: (() => void)[] = [];
|
|
94
95
|
|
|
95
96
|
for (const fn of this._listeners) {
|
|
96
97
|
fn(change, {
|
|
97
|
-
// changes,
|
|
98
98
|
remove: () => this.remove(fn),
|
|
99
|
+
onApplied: fnOnApplied => onApplied.push(fnOnApplied),
|
|
99
100
|
});
|
|
100
101
|
}
|
|
101
102
|
|
|
102
103
|
this._targets.apply();
|
|
103
104
|
|
|
105
|
+
for (const fn of onApplied) {
|
|
106
|
+
fn();
|
|
107
|
+
}
|
|
108
|
+
|
|
104
109
|
requestAnimationFrame(a => this._tick(a));
|
|
105
110
|
}
|
|
106
111
|
}
|
package/src/timing/TestTicker.ts
CHANGED
|
@@ -81,15 +81,21 @@ export default class TestTicker implements Ticker {
|
|
|
81
81
|
}
|
|
82
82
|
this._previousTick = elapsed;
|
|
83
83
|
|
|
84
|
+
const onApplied: (() => void)[] = [];
|
|
85
|
+
|
|
84
86
|
for (const fn of this._listeners) {
|
|
85
87
|
fn(change, {
|
|
86
|
-
// changes,
|
|
87
88
|
remove: () => this.remove(fn),
|
|
89
|
+
onApplied: fn => onApplied.push(fn),
|
|
88
90
|
});
|
|
89
91
|
}
|
|
90
92
|
|
|
91
93
|
this.targets.apply();
|
|
92
94
|
|
|
95
|
+
for (const fn of onApplied) {
|
|
96
|
+
fn();
|
|
97
|
+
}
|
|
98
|
+
|
|
93
99
|
if (this._listeners.size === 0) {
|
|
94
100
|
this.running = false;
|
|
95
101
|
this._previousTick = null;
|
package/src/timing/Ticker.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { Target } from '../target/Target.js';
|
|
2
2
|
|
|
3
|
-
export type
|
|
3
|
+
export type CallbackApi = {
|
|
4
|
+
remove: () => void;
|
|
5
|
+
onApplied: (fn: () => void) => void;
|
|
6
|
+
};
|
|
7
|
+
export type Callback = (change: number, api: CallbackApi) => void;
|
|
4
8
|
|
|
5
9
|
export default interface Ticker {
|
|
6
10
|
registerTarget(target: any): Target;
|
package/src/timing/Timing.ts
CHANGED
|
@@ -36,67 +36,84 @@ export type TimingProps = {
|
|
|
36
36
|
* because it is like one frame, so it's an image
|
|
37
37
|
*/
|
|
38
38
|
export default class Timing {
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
/**
|
|
40
|
+
* The duration of a single iteration
|
|
41
|
+
*/
|
|
41
42
|
iterDuration: number;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* The total duration of the timing
|
|
46
|
+
*/
|
|
42
47
|
duration: number;
|
|
43
48
|
|
|
44
49
|
ease: (t: number) => number;
|
|
50
|
+
/**
|
|
51
|
+
* The number of repeats
|
|
52
|
+
*
|
|
53
|
+
* -1 is infinite
|
|
54
|
+
*/
|
|
45
55
|
repeat: number;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* If the iteration should alternate
|
|
59
|
+
*/
|
|
46
60
|
alternate: boolean;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* If the iteration should be reversed
|
|
64
|
+
*/
|
|
47
65
|
reversed: boolean;
|
|
48
66
|
|
|
67
|
+
/**
|
|
68
|
+
* The position of the current iteration
|
|
69
|
+
*
|
|
70
|
+
* will never be outside of the range 0-1 (inclusive)
|
|
71
|
+
*/
|
|
49
72
|
position: number;
|
|
73
|
+
/**
|
|
74
|
+
* The state of the timing
|
|
75
|
+
*/
|
|
50
76
|
state: number;
|
|
51
77
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
seek will only control the current iteration
|
|
58
|
-
if repeat is finite
|
|
59
|
-
seek will control the entire time
|
|
60
|
-
|
|
78
|
+
/**
|
|
79
|
+
* Progress is a value which always counts up
|
|
80
|
+
* does not take alternate or easing into account
|
|
81
|
+
*/
|
|
82
|
+
private progress: number;
|
|
61
83
|
|
|
62
|
-
{
|
|
63
|
-
duration: in ms
|
|
64
|
-
ease: easeFunction
|
|
65
|
-
repeat: -1 - x,
|
|
66
|
-
alternate
|
|
67
|
-
}
|
|
68
|
-
*/
|
|
69
84
|
constructor(props: TimingProps) {
|
|
70
85
|
// these vars are only readonly
|
|
71
86
|
// use functions to update them
|
|
72
87
|
|
|
73
|
-
this.iterDuration = props.duration;
|
|
74
|
-
this.duration = props.duration;
|
|
75
|
-
|
|
76
88
|
this.ease = props.ease ?? (t => t);
|
|
77
89
|
this.repeat = props.repeat ?? 0;
|
|
78
90
|
this.alternate = props.alternate ?? true;
|
|
79
91
|
this.reversed = props.reversed ?? false;
|
|
80
92
|
|
|
81
|
-
this.
|
|
82
|
-
this.
|
|
83
|
-
|
|
84
|
-
// progress does not take alternation into account and has no easing
|
|
85
|
-
// this always increments up
|
|
86
|
-
this._progress = 0;
|
|
93
|
+
this.iterDuration = 0;
|
|
94
|
+
this.duration = 0;
|
|
95
|
+
this.setDuration(props.duration);
|
|
87
96
|
|
|
88
|
-
|
|
97
|
+
this.position = 0;
|
|
98
|
+
this.state = STATE_BEFORE;
|
|
99
|
+
this.progress = 0;
|
|
100
|
+
this.seek(-1);
|
|
89
101
|
}
|
|
90
102
|
|
|
91
103
|
setDuration(iterDuration: number) {
|
|
92
104
|
this.iterDuration = iterDuration;
|
|
93
105
|
|
|
94
106
|
this.duration = this.iterDuration;
|
|
95
|
-
if (this.
|
|
107
|
+
if (this.isFinite()) {
|
|
96
108
|
this.duration = (this.repeat + 1) * this.iterDuration;
|
|
97
109
|
}
|
|
98
110
|
}
|
|
99
111
|
|
|
112
|
+
/**
|
|
113
|
+
* Returns the current position in milliseconds
|
|
114
|
+
*
|
|
115
|
+
* This is equivalent to position * iteration duration
|
|
116
|
+
*/
|
|
100
117
|
positionMs() {
|
|
101
118
|
// todo should this not return pos * duration?
|
|
102
119
|
return this.position * this.iterDuration;
|
|
@@ -110,13 +127,19 @@ export default class Timing {
|
|
|
110
127
|
* required
|
|
111
128
|
*/
|
|
112
129
|
positionMsUnbounded() {
|
|
113
|
-
|
|
114
|
-
|
|
130
|
+
let reversed = this.reversed;
|
|
131
|
+
|
|
132
|
+
if (this._shouldInvert()) reversed = !reversed;
|
|
115
133
|
|
|
116
|
-
|
|
134
|
+
let pos = this.position;
|
|
135
|
+
|
|
136
|
+
if (this.state <= STATE_BEFORE) {
|
|
137
|
+
pos = reversed ? 2 : -1;
|
|
138
|
+
} else if (this.state >= STATE_AFTER) {
|
|
139
|
+
pos = reversed ? -1 : 2;
|
|
140
|
+
}
|
|
117
141
|
|
|
118
|
-
|
|
119
|
-
return this.position * this.iterDuration + 1;
|
|
142
|
+
return pos * this.iterDuration;
|
|
120
143
|
}
|
|
121
144
|
|
|
122
145
|
isFinite() {
|
|
@@ -131,56 +154,60 @@ export default class Timing {
|
|
|
131
154
|
return;
|
|
132
155
|
}
|
|
133
156
|
|
|
134
|
-
this.
|
|
157
|
+
if (this.isFinite()) {
|
|
158
|
+
this._updateProgress(
|
|
159
|
+
this.positionAbsolute() + change / this.iterDuration,
|
|
160
|
+
);
|
|
161
|
+
} else {
|
|
162
|
+
// to make sure we don't mess up the alternate
|
|
163
|
+
this._updateProgress(
|
|
164
|
+
Math.max(0, this.progress) + change / this.iterDuration,
|
|
165
|
+
);
|
|
166
|
+
}
|
|
135
167
|
}
|
|
136
168
|
|
|
137
169
|
seekMs(ms: number) {
|
|
138
|
-
|
|
139
|
-
this._updateProgress(Math.sign(ms));
|
|
140
|
-
return;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
this._updateProgress(ms / this.iterDuration);
|
|
144
|
-
|
|
145
|
-
// return this.seek(this.normalizeMs(ms));
|
|
170
|
+
return this.seek(this.normalizeMs(ms));
|
|
146
171
|
}
|
|
147
172
|
|
|
173
|
+
/**
|
|
174
|
+
* Returns the position of time (ms) position
|
|
175
|
+
*/
|
|
148
176
|
normalizeMs(ms: number) {
|
|
149
177
|
if (this.iterDuration <= 0) {
|
|
150
178
|
return Math.sign(ms);
|
|
151
179
|
}
|
|
152
180
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
if (this.isFinite()) {
|
|
156
|
-
return pos / (this.repeat + 1);
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
return pos;
|
|
181
|
+
return ms / this.duration;
|
|
160
182
|
}
|
|
161
183
|
|
|
162
|
-
//
|
|
163
|
-
|
|
184
|
+
// Returns the position without easing or reversing
|
|
185
|
+
//
|
|
186
|
+
// Returns 0..=(repeat + 1)
|
|
187
|
+
positionAbsolute(): number {
|
|
164
188
|
if (this.isFinite()) {
|
|
165
|
-
return
|
|
189
|
+
return Math.min(this.repeat + 1, Math.max(0, this.progress));
|
|
166
190
|
}
|
|
167
191
|
|
|
168
|
-
|
|
192
|
+
// the iterations should be inclusive
|
|
193
|
+
const prog = Math.max(0, this.progress) % 1;
|
|
194
|
+
if (prog === 0 && this.progress > 0) return 1;
|
|
195
|
+
return prog;
|
|
169
196
|
}
|
|
170
197
|
|
|
171
198
|
// should be between 0-1 if outside might change the state
|
|
172
199
|
seek(pos: number) {
|
|
173
|
-
if (this.
|
|
174
|
-
this._updateProgress(pos);
|
|
175
|
-
} else {
|
|
176
|
-
// finite
|
|
200
|
+
if (this.isFinite()) {
|
|
177
201
|
this._updateProgress(pos * (this.repeat + 1));
|
|
202
|
+
} else {
|
|
203
|
+
// to make sure we don't mess up the alternate
|
|
204
|
+
this._updateProgress(Math.floor(this.progress) + pos);
|
|
178
205
|
}
|
|
179
206
|
}
|
|
180
207
|
|
|
181
208
|
savePosition(): Position {
|
|
182
209
|
return {
|
|
183
|
-
progress: this.
|
|
210
|
+
progress: this.progress,
|
|
184
211
|
};
|
|
185
212
|
}
|
|
186
213
|
|
|
@@ -188,48 +215,46 @@ export default class Timing {
|
|
|
188
215
|
this._updateProgress(pos.progress);
|
|
189
216
|
}
|
|
190
217
|
|
|
218
|
+
/**
|
|
219
|
+
* Sets the alternate
|
|
220
|
+
*/
|
|
191
221
|
setAlternate(alternate: boolean) {
|
|
192
222
|
if (this.alternate == alternate) return;
|
|
193
223
|
|
|
194
|
-
|
|
195
|
-
this.reversed = alternate == this._shouldInvert();
|
|
224
|
+
this.reversed = !this.reversed;
|
|
196
225
|
this.alternate = alternate;
|
|
197
226
|
}
|
|
198
227
|
|
|
199
228
|
reverse() {
|
|
200
229
|
this.reversed = !this.reversed;
|
|
201
230
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
return p;
|
|
205
|
-
};
|
|
206
|
-
|
|
207
|
-
let p;
|
|
208
|
-
if (this.state <= STATE_BEFORE) {
|
|
209
|
-
p = 2;
|
|
210
|
-
} else if (this.state >= STATE_AFTER) {
|
|
211
|
-
p = -1;
|
|
212
|
-
// check if the values should be reversed
|
|
213
|
-
} else if (this.reversed != this._shouldInvert()) {
|
|
214
|
-
let decimal = 1 - (this._progress % 1);
|
|
215
|
-
p = wrapAround(Math.floor(this._progress) + decimal);
|
|
231
|
+
if (this.isFinite()) {
|
|
232
|
+
this._updateProgress(this.repeat + 1 - this.progress);
|
|
216
233
|
} else {
|
|
217
|
-
|
|
234
|
+
const fract = this.progress % 1;
|
|
235
|
+
this._updateProgress(Math.floor(this.progress) + 1 - fract);
|
|
218
236
|
}
|
|
219
|
-
|
|
220
|
-
this._updateProgress(p);
|
|
221
237
|
}
|
|
222
238
|
|
|
223
239
|
_shouldInvert() {
|
|
224
|
-
return
|
|
240
|
+
return (
|
|
241
|
+
this.alternate &&
|
|
242
|
+
Math.floor(this.progress) % 2 === 1 &&
|
|
243
|
+
this.progress % 1 !== 0
|
|
244
|
+
);
|
|
225
245
|
}
|
|
226
246
|
|
|
247
|
+
/**
|
|
248
|
+
* Updates the progress and the state
|
|
249
|
+
*
|
|
250
|
+
* newProgress should follow the same rules as _progress
|
|
251
|
+
*/
|
|
227
252
|
_updateProgress(newProgress: number) {
|
|
228
253
|
// if duration is zero the position is always 1
|
|
229
254
|
// and the state is either BEFORE or AFTER
|
|
230
255
|
if (this.iterDuration <= 0) {
|
|
231
256
|
newProgress = Math.sign(newProgress);
|
|
232
|
-
this.
|
|
257
|
+
this.progress = newProgress;
|
|
233
258
|
this.position = 1;
|
|
234
259
|
|
|
235
260
|
if (newProgress < 0) this.state = STATE_BEFORE;
|
|
@@ -238,15 +263,19 @@ export default class Timing {
|
|
|
238
263
|
return;
|
|
239
264
|
}
|
|
240
265
|
|
|
241
|
-
this.
|
|
266
|
+
this.progress = newProgress;
|
|
242
267
|
|
|
268
|
+
// update state
|
|
269
|
+
//
|
|
270
|
+
// is this not wrong if we are in reversed?
|
|
271
|
+
//
|
|
243
272
|
// since infinite repeat can never end let's ignore it
|
|
244
|
-
if (this.
|
|
273
|
+
if (this.isFinite()) {
|
|
245
274
|
const end = this.repeat + 1;
|
|
246
|
-
if (this.
|
|
247
|
-
this.
|
|
275
|
+
if (this.progress > end) {
|
|
276
|
+
this.progress = end + 1;
|
|
248
277
|
this.state = STATE_AFTER;
|
|
249
|
-
} else if (this.
|
|
278
|
+
} else if (this.progress === end) {
|
|
250
279
|
this.state = STATE_ENDED;
|
|
251
280
|
} else {
|
|
252
281
|
this.state = STATE_RUNNING;
|
|
@@ -256,20 +285,27 @@ export default class Timing {
|
|
|
256
285
|
}
|
|
257
286
|
|
|
258
287
|
// override state if not running
|
|
259
|
-
if (this.
|
|
260
|
-
this.
|
|
288
|
+
if (this.progress < 0) {
|
|
289
|
+
this.progress = -1;
|
|
261
290
|
this.state = STATE_BEFORE;
|
|
262
|
-
} else if (this.
|
|
291
|
+
} else if (this.progress === 0) {
|
|
263
292
|
this.state = STATE_START;
|
|
264
293
|
}
|
|
265
294
|
|
|
266
295
|
// now calculate the position
|
|
267
|
-
this.position = this.
|
|
296
|
+
this.position = this.positionAbsolute() % 1;
|
|
297
|
+
|
|
298
|
+
// the iterations should be inclusive
|
|
299
|
+
if (this.position === 0 && this.progress > 0) {
|
|
300
|
+
this.position = 1;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// alternate
|
|
304
|
+
if (this._shouldInvert()) this.position = 1 - this.position;
|
|
268
305
|
|
|
269
306
|
// calc if we are in a reversed iteration or not
|
|
270
307
|
// and we are we should invert the position
|
|
271
|
-
if (this.reversed
|
|
272
|
-
this.position = 1 - this.position;
|
|
308
|
+
if (this.reversed) this.position = 1 - this.position;
|
|
273
309
|
|
|
274
310
|
this.position = this.ease(this.position);
|
|
275
311
|
}
|