chnobli 0.1.2 → 0.1.4

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.
@@ -0,0 +1,178 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import TestTicker from '../timing/testticker.js';
3
+ import TestResponsiveEvent from '../responsive/testevent.js';
4
+ import { animate, timeline } from '../chnobli.js';
5
+ import { responsive, curve } from '../utils/utils.js';
6
+ import { el } from '../target/testdomnode.js';
7
+ import { timeout } from 'fire/util.js';
8
+
9
+ describe('properties', () => {
10
+ it('resetprops', () => {
11
+ const ticker = new TestTicker;
12
+
13
+ const div = el();
14
+ const tl = timeline()
15
+ .add(div, {
16
+ x: 100,
17
+ width: 100,
18
+ duration: 10
19
+ })
20
+ .play();
21
+
22
+ ticker.run();
23
+ expect(div.style.transform)
24
+ .toBe('translate3d(100.000px,0.000px,0.000px)');
25
+ expect(div.style.width).toBe('100.000px');
26
+
27
+ tl.resetProps();
28
+ expect(div.style.transform).toBe('');
29
+ expect(div.style.width).toBe(undefined);
30
+ });
31
+
32
+ it('destroy', async () => {
33
+ const ticker = new TestTicker;
34
+
35
+ function runDestroyTest(cleanup, ticker) {
36
+
37
+ const div = el();
38
+ cleanup.register(div, 'div');
39
+ expect(ticker.targets.size()).toBe(0);
40
+ const tl = timeline()
41
+ .add(div, {
42
+ x: 100,
43
+ width: 100,
44
+ duration: 10
45
+ })
46
+ .play();
47
+
48
+ expect(ticker.targets.size()).toBe(1);
49
+
50
+ ticker.run();
51
+ expect(div.style.transform)
52
+ .toBe('translate3d(100.000px,0.000px,0.000px)');
53
+ expect(div.style.width).toBe('100.000px');
54
+
55
+ tl.destroy();
56
+ expect(div.style.transform).toBe('');
57
+ expect(div.style.width).toBe(undefined);
58
+ expect(ticker.targets.size()).toBe(0);
59
+ }
60
+
61
+ let resolveCleanupProm;
62
+ let cleanupProm = new Promise(resolve => resolveCleanupProm = resolve);
63
+ const cleanup = new FinalizationRegistry(key => {
64
+ resolveCleanupProm(key);
65
+ });
66
+
67
+ runDestroyTest(cleanup, ticker);
68
+
69
+ global.gc();
70
+
71
+ const res = await Promise.race([
72
+ cleanupProm,
73
+ timeout(2000).then(() => 'timedout')
74
+ ]);
75
+ expect(res).toBe('div');
76
+ });
77
+
78
+ it('update timeline', () => {
79
+ const ticker = new TestTicker;
80
+ const respEv = new TestResponsiveEvent;
81
+
82
+ const div = el();
83
+ div.computedStyle.width = '10px';
84
+
85
+ const tl = timeline()
86
+ .add(div, {
87
+ width: 100,
88
+ duration: 10
89
+ });
90
+
91
+ tl.seek(0);
92
+ ticker.run();
93
+ expect(div.style.width).toBe('10.000px');
94
+
95
+ tl.play();
96
+ ticker.run(1);
97
+ expect(div.style.width).toBe('19.000px');
98
+
99
+ // on resize the div changes it's size
100
+ div.computedStyle.width = '20px';
101
+ tl.update();
102
+ expect(div.style.width).toBe('28.000px');
103
+
104
+ ticker.run(1);
105
+ expect(div.style.width).toBe('36.000px');
106
+ ticker.run();
107
+ expect(div.style.width).toBe('100.000px');
108
+
109
+ tl.reverse();
110
+ tl.play();
111
+ ticker.run(5);
112
+ expect(div.style.width).toBe('60.000px');
113
+
114
+ div.computedStyle.width = '30px';
115
+ respEv.resize();
116
+ expect(div.style.width).toBe('65.000px');
117
+ });
118
+
119
+ it('responsive', () => {
120
+ const ticker = new TestTicker;
121
+ const respEv = new TestResponsiveEvent;
122
+
123
+ const div = el();
124
+ div.computedStyle.width = '10px';
125
+
126
+ let windowWidth = 16;
127
+
128
+ let windowAspectRatio;
129
+ const resp1 = responsive(() => {
130
+ windowAspectRatio = windowWidth / 9;
131
+ });
132
+
133
+ const tl = timeline()
134
+ .add(div, {
135
+ width: responsive(e => 20 * windowAspectRatio),
136
+ duration: 10
137
+ })
138
+ .addResponsive(resp1);
139
+
140
+ expect(windowAspectRatio).toBe(undefined);
141
+
142
+ tl.play();
143
+ ticker.run();
144
+ expect(div.style.width).toBe('35.556px');
145
+
146
+ windowWidth = 15;
147
+ respEv.resize();
148
+ expect(div.style.width).toBe('33.333px');
149
+ });
150
+
151
+ it('xy', () => {
152
+ const ticker = new TestTicker;
153
+
154
+ const div = el();
155
+ const tl = timeline()
156
+ .add(div, {
157
+ xy: curve([
158
+ { x: 0, y: 10 },
159
+ { x: 100, y: 10 },
160
+ { x: 50, y: 20 }
161
+ ]),
162
+ duration: 10
163
+ });
164
+
165
+ tl.play();
166
+ ticker.run(0);
167
+ expect(div.style.transform)
168
+ .toBe('translate3d(0.000px,10.000px,0.000px)');
169
+
170
+ ticker.run(5);
171
+ expect(div.style.transform)
172
+ .toBe('translate3d(100.000px,10.000px,0.000px)');
173
+
174
+ ticker.run();
175
+ expect(div.style.transform)
176
+ .toBe('translate3d(50.000px,20.000px,0.000px)');
177
+ });
178
+ });
@@ -0,0 +1,234 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import TestTicker from '../timing/testticker.js';
3
+ import { animate, timeline } from '../chnobli.js';
4
+ import { el } from '../target/testdomnode.js';
5
+
6
+ describe('timeline', () => {
7
+ it('empty timeline', () => {
8
+ const ticker = new TestTicker;
9
+
10
+ const tl = timeline();
11
+ tl.play();
12
+ const finished = ticker.run();
13
+ expect(finished).toBe(true);
14
+ });
15
+
16
+ it('single timeline', () => {
17
+ const ticker = new TestTicker;
18
+
19
+ const tl = timeline();
20
+ const target = el();
21
+ tl.add(target, {
22
+ x: 10,
23
+ duration: 10
24
+ });
25
+ tl.play();
26
+
27
+ ticker.run(0);
28
+ expect(target.style.transform)
29
+ .toBe('translate3d(0.000px,0.000px,0.000px)');
30
+
31
+ ticker.run();
32
+ expect(target.style.transform)
33
+ .toBe('translate3d(10.000px,0.000px,0.000px)');
34
+
35
+ tl.reverse();
36
+ tl.play();
37
+ ticker.run();
38
+ expect(target.style.transform).toBe('');
39
+ });
40
+
41
+ it('timeline set', () => {
42
+ const ticker = new TestTicker;
43
+
44
+ const target = el();
45
+ const tl = timeline()
46
+ .set(target, {
47
+ x: 10
48
+ });
49
+ tl.play();
50
+
51
+ ticker.run(0);
52
+ expect(target.style.transform)
53
+ .toBe('translate3d(10.000px,0.000px,0.000px)');
54
+
55
+ ticker.run();
56
+ expect(target.style.transform)
57
+ .toBe('translate3d(10.000px,0.000px,0.000px)');
58
+
59
+ tl.reverse();
60
+ tl.play();
61
+ ticker.run();
62
+ expect(target.style.transform)
63
+ .toBe('translate3d(10.000px,0.000px,0.000px)');
64
+ });
65
+
66
+ it('offsetTimeline timeline', () => {
67
+ const ticker = new TestTicker;
68
+
69
+ const tl = timeline();
70
+ const target = el();
71
+ tl.add(target, {
72
+ x: 10,
73
+ duration: 10
74
+ });
75
+ tl.add(target, {
76
+ x: 20,
77
+ duration: 10
78
+ })
79
+ tl.play();
80
+
81
+ ticker.run(10);
82
+ expect(target.style.transform)
83
+ .toBe('translate3d(10.000px,0.000px,0.000px)');
84
+ ticker.run(1);
85
+ expect(target.style.transform)
86
+ .toBe('translate3d(11.000px,0.000px,0.000px)');
87
+
88
+ ticker.run();
89
+ expect(target.style.transform)
90
+ .toBe('translate3d(20.000px,0.000px,0.000px)');
91
+ });
92
+
93
+ it('timeline seeking', () => {
94
+ const ticker = new TestTicker;
95
+
96
+ const tl = timeline();
97
+ const target = el();
98
+ tl.add(target, {
99
+ x: 10,
100
+ duration: 10
101
+ });
102
+ tl.add(target, {
103
+ x: 20,
104
+ duration: 10
105
+ })
106
+
107
+ tl.seekMs(10);
108
+ ticker.run();
109
+ expect(target.style.transform)
110
+ .toBe('translate3d(10.000px,0.000px,0.000px)');
111
+
112
+ tl.seekMs(11);
113
+ ticker.run();
114
+ expect(target.style.transform)
115
+ .toBe('translate3d(11.000px,0.000px,0.000px)');
116
+
117
+ tl.seekMs(20);
118
+ ticker.run();
119
+ expect(target.style.transform)
120
+ .toBe('translate3d(20.000px,0.000px,0.000px)');
121
+
122
+ tl.seekMs(8);
123
+ ticker.run();
124
+ expect(target.style.transform)
125
+ .toBe('translate3d(8.000px,0.000px,0.000px)');
126
+ });
127
+
128
+ it('seeking after', () => {
129
+ const ticker = new TestTicker;
130
+
131
+ const target = el();
132
+ const ani = animate(target, {
133
+ autoplay: false,
134
+ duration: 10,
135
+ x: 10
136
+ });
137
+ ani.seek(2);
138
+
139
+ ticker.run();
140
+ expect(target.style.transform)
141
+ .toBe('translate3d(10.000px,0.000px,0.000px)');
142
+ });
143
+
144
+ it('timeline controls', () => {
145
+ const ticker = new TestTicker;
146
+
147
+ const tl = timeline();
148
+ const target = el();
149
+ tl.add(target, {
150
+ x: 10,
151
+ duration: 10
152
+ });
153
+ tl.add(target, {
154
+ x: 20,
155
+ duration: 10
156
+ })
157
+
158
+ tl.seekMs(10);
159
+ ticker.run();
160
+ expect(target.style.transform)
161
+ .toBe('translate3d(10.000px,0.000px,0.000px)');
162
+
163
+ tl.play();
164
+ ticker.run();
165
+ expect(target.style.transform)
166
+ .toBe('translate3d(20.000px,0.000px,0.000px)');
167
+
168
+ tl.reset();
169
+ tl.play();
170
+ ticker.run(10);
171
+ expect(target.style.transform)
172
+ .toBe('translate3d(10.000px,0.000px,0.000px)');
173
+
174
+ tl.reverse();
175
+ ticker.run(5);
176
+ expect(target.style.transform)
177
+ .toBe('translate3d(5.000px,0.000px,0.000px)');
178
+
179
+ tl.reverse();
180
+ ticker.run();
181
+ expect(target.style.transform)
182
+ .toBe('translate3d(20.000px,0.000px,0.000px)');
183
+
184
+ tl.reverse();
185
+ tl.play();
186
+ ticker.run();
187
+ expect(target.style.transform).toBe('');
188
+ });
189
+
190
+ it('timeline events', () => {
191
+ const ticker = new TestTicker;
192
+
193
+ const target = el();
194
+ const tl = timeline()
195
+ .add(target, {
196
+ x: 50,
197
+ duration: 10
198
+ })
199
+ .add(target, {
200
+ y: 50,
201
+ duration: 10
202
+ });
203
+
204
+ let endCounter = 0;
205
+ tl.on('end', () => endCounter += 1);
206
+
207
+ tl.play();
208
+ ticker.run(5);
209
+ expect(endCounter).toBe(0);
210
+
211
+ ticker.run();
212
+ expect(endCounter).toBe(1);
213
+
214
+ tl.play();
215
+ ticker.run();
216
+ // not sure this is the behaviour we wan't
217
+ expect(endCounter).toBe(2);
218
+
219
+ tl.reverse();
220
+ ticker.run();
221
+ expect(endCounter).toBe(2);
222
+ expect(target.style.transform)
223
+ .toBe('translate3d(50.000px,50.000px,0.000px)');
224
+
225
+ tl.play();
226
+ ticker.run();
227
+ expect(endCounter).toBe(3);
228
+ expect(target.style.transform).toBe('');
229
+
230
+ tl.play();
231
+ ticker.run();
232
+ expect(endCounter).toBe(4);
233
+ });
234
+ });
@@ -0,0 +1,270 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import Timing, {
3
+ STATE_BEFORE, STATE_START, STATE_RUNNING, STATE_ENDED, STATE_AFTER
4
+ } from '../timing/timing.js';
5
+
6
+ describe('timing', () => {
7
+ it('zero duration', () => {
8
+ // if duration is zero the position is always 1
9
+ // and the state is either BEFORE or AFTER
10
+ const timing = new Timing({
11
+ duration: 0
12
+ });
13
+ expect(timing.duration).toBe(0);
14
+ expect(timing.state).toBe(STATE_BEFORE);
15
+
16
+ timing.seek(-1);
17
+ expect(timing.position).toBe(1);
18
+ expect(timing.state).toBe(STATE_BEFORE);
19
+
20
+ timing.seek(0);
21
+ expect(timing.position).toBe(1);
22
+ expect(timing.state).toBe(STATE_AFTER);
23
+
24
+ timing.seek(.5);
25
+ expect(timing.position).toBe(1);
26
+ expect(timing.state).toBe(STATE_AFTER);
27
+
28
+ timing.seek(1);
29
+ expect(timing.position).toBe(1);
30
+ expect(timing.state).toBe(STATE_AFTER);
31
+
32
+ timing.seek(2);
33
+ expect(timing.position).toBe(1);
34
+ expect(timing.state).toBe(STATE_AFTER);
35
+
36
+ timing.seekMs(-1);
37
+ expect(timing.position).toBe(1);
38
+ expect(timing.state).toBe(STATE_BEFORE);
39
+
40
+ timing.seekMs(0);
41
+ expect(timing.position).toBe(1);
42
+ expect(timing.state).toBe(STATE_AFTER);
43
+
44
+ timing.seekMs(.5);
45
+ expect(timing.position).toBe(1);
46
+ expect(timing.state).toBe(STATE_AFTER);
47
+
48
+ timing.seekMs(1);
49
+ expect(timing.position).toBe(1);
50
+ expect(timing.state).toBe(STATE_AFTER);
51
+ });
52
+
53
+ it('short timing', () => {
54
+ const timing = new Timing({
55
+ duration: 1
56
+ });
57
+ expect(timing.duration).toBe(1);
58
+ expect(timing.state).toBe(STATE_BEFORE);
59
+
60
+ timing.seek(-1);
61
+ expect(timing.position).toBe(0);
62
+ expect(timing.state).toBe(STATE_BEFORE);
63
+
64
+ timing.seek(0);
65
+ expect(timing.position).toBe(0);
66
+ expect(timing.state).toBe(STATE_START);
67
+
68
+ timing.seek(.5);
69
+ expect(timing.position).toBe(.5);
70
+ expect(timing.state).toBe(STATE_RUNNING);
71
+
72
+ timing.seek(1);
73
+ expect(timing.position).toBe(1);
74
+ expect(timing.state).toBe(STATE_ENDED);
75
+
76
+ timing.seek(2);
77
+ expect(timing.position).toBe(1);
78
+ expect(timing.state).toBe(STATE_AFTER);
79
+
80
+ timing.seekMs(-1);
81
+ expect(timing.position).toBe(0);
82
+ expect(timing.state).toBe(STATE_BEFORE);
83
+
84
+ timing.seekMs(0);
85
+ expect(timing.position).toBe(0);
86
+ expect(timing.state).toBe(STATE_START);
87
+
88
+ timing.seekMs(.5);
89
+ expect(timing.position).toBe(.5);
90
+ expect(timing.state).toBe(STATE_RUNNING);
91
+
92
+ timing.seekMs(1);
93
+ expect(timing.position).toBe(1);
94
+ expect(timing.state).toBe(STATE_ENDED);
95
+
96
+ timing.seekMs(2);
97
+ expect(timing.position).toBe(1);
98
+ expect(timing.state).toBe(STATE_AFTER);
99
+ });
100
+
101
+ it('state management', () => {
102
+ const timing = new Timing({
103
+ duration: 100
104
+ });
105
+
106
+ timing.advance(20);
107
+ expect(timing.state).toBe(STATE_RUNNING);
108
+ expect(timing.position).toBe(.2);
109
+
110
+ timing.advance(20);
111
+ expect(timing.positionMs()).toBe(40);
112
+ expect(timing.state).toBe(STATE_RUNNING);
113
+ expect(timing.position).toBe(.4);
114
+
115
+ timing.advance(20);
116
+ expect(timing.state).toBe(STATE_RUNNING);
117
+ expect(Math.floor(timing.position * 10) / 10).toBe(.6);
118
+
119
+ timing.advance(20);
120
+ expect(timing.state).toBe(STATE_RUNNING);
121
+ expect(timing.position).toBe(.8);
122
+
123
+ timing.advance(20);
124
+ expect(timing.state).toBe(STATE_ENDED);
125
+ expect(timing.position).toBe(1);
126
+
127
+ timing.advance(20);
128
+ expect(timing.state).toBe(STATE_AFTER);
129
+ expect(timing.position).toBe(1);
130
+ });
131
+
132
+ it('reverse', () => {
133
+ const timing = new Timing({
134
+ duration: 100
135
+ });
136
+
137
+ expect(timing.state).toBe(STATE_BEFORE);
138
+ expect(timing.position).toBe(0);
139
+
140
+ // <
141
+ timing.reverse();
142
+ expect(timing.state).toBe(STATE_AFTER);
143
+ expect(timing.position).toBe(0);
144
+
145
+ // >
146
+ timing.reverse();
147
+ expect(timing.state).toBe(STATE_BEFORE);
148
+ expect(timing.position).toBe(0);
149
+
150
+ // >
151
+ timing.advance(25);
152
+ expect(timing.state).toBe(STATE_RUNNING);
153
+ expect(timing.position).toBe(0.25);
154
+
155
+ // <
156
+ timing.reverse();
157
+ expect(timing.state).toBe(STATE_RUNNING);
158
+ expect(timing.position).toBe(0.25);
159
+
160
+ // <
161
+ timing.advance(24);
162
+ expect(timing.state).toBe(STATE_RUNNING);
163
+ expect(timing.position.toFixed(3)).toBe('0.010');
164
+
165
+ // <
166
+ timing.advance(1);
167
+ expect(timing.state).toBe(STATE_ENDED);
168
+ expect(timing.position).toBe(0);
169
+
170
+ // >
171
+ timing.reverse();
172
+ expect(timing.state).toBe(STATE_START);
173
+ expect(timing.position).toBe(0);
174
+
175
+ // ><
176
+ timing.seek(0.75);
177
+ timing.reverse();
178
+ expect(timing.position).toBe(0.75);
179
+
180
+ // <
181
+ timing.advance(10);
182
+ expect(timing.position).toBe(0.65);
183
+
184
+
185
+ const timing2 = new Timing({
186
+ duration: 100
187
+ });
188
+
189
+ timing2.advance(100);
190
+ expect(timing2.state).toBe(STATE_ENDED);
191
+ expect(timing2.position).toBe(1);
192
+
193
+ timing2.reverse();
194
+ expect(timing2.state).toBe(STATE_START);
195
+ expect(timing2.position).toBe(1);
196
+
197
+ timing2.seek(-1);
198
+ expect(timing2.state).toBe(STATE_BEFORE);
199
+ expect(timing2.position).toBe(1);
200
+
201
+ timing2.seek(.25);
202
+ expect(timing2.state).toBe(STATE_RUNNING);
203
+ expect(timing2.position).toBe(.75);
204
+ });
205
+
206
+ it('repeat', () => {
207
+ const timing = new Timing({
208
+ duration: 100,
209
+ repeat: -1
210
+ });
211
+
212
+ // >
213
+ timing.advance(25);
214
+ expect(timing.state).toBe(STATE_RUNNING);
215
+ expect(timing.position).toBe(0.25);
216
+
217
+ // ><
218
+ timing.advance(100);
219
+ expect(timing.position).toBe(0.75);
220
+
221
+ // <
222
+ timing.advance(50);
223
+ expect(timing.position).toBe(0.25);
224
+
225
+ // <>
226
+ timing.advance(50);
227
+ expect(timing.position).toBe(0.25);
228
+
229
+ // >
230
+ timing.advance(50);
231
+ expect(timing.position).toBe(0.75);
232
+
233
+ // <
234
+ timing.reverse();
235
+ expect(timing.position).toBe(0.75);
236
+
237
+ timing.advance(50);
238
+ expect(timing.position).toBe(0.25);
239
+
240
+ // <>
241
+ timing.advance(50);
242
+ expect(timing.position).toBe(0.25);
243
+
244
+ // >
245
+ timing.setAlternate(false);
246
+ timing.advance(50);
247
+ expect(timing.position).toBe(0.75);
248
+
249
+ // >
250
+ timing.advance(50);
251
+ expect(timing.position).toBe(0.25);
252
+
253
+ // <
254
+ timing.reverse();
255
+ expect(timing.position).toBe(0.25);
256
+
257
+ // <
258
+ timing.advance(50);
259
+ expect(timing.position).toBe(0.75);
260
+
261
+ // <
262
+ timing.setAlternate(true);
263
+ timing.advance(50);
264
+ expect(timing.position).toBe(0.25);
265
+
266
+ // <>
267
+ timing.advance(50);
268
+ expect(timing.position).toBe(0.25);
269
+ });
270
+ });