chnobli 0.1.10 → 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 +2 -1
- package/dist/animation/Animation.d.ts.map +1 -1
- package/dist/animation/Animation.js +5 -3
- package/dist/animation/Animation.js.map +1 -1
- 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 +3 -3
- package/dist/chnobli.d.ts.map +1 -1
- package/dist/chnobli.js.map +1 -1
- package/dist/property/ClassProperty.js +1 -1
- package/dist/property/ClassProperty.js.map +1 -1
- package/dist/property/TransformXYProperty.d.ts.map +1 -1
- package/dist/scroll/Scroll.d.ts +24 -3
- package/dist/scroll/Scroll.d.ts.map +1 -1
- package/dist/scroll/Scroll.js +155 -43
- package/dist/scroll/Scroll.js.map +1 -1
- package/dist/scroll/ScrollEvent.d.ts.map +1 -1
- package/dist/scroll/ScrollEvent.js +1 -0
- package/dist/scroll/ScrollEvent.js.map +1 -1
- package/dist/scroll/index.d.ts +2 -0
- package/dist/scroll/index.d.ts.map +1 -1
- package/dist/scroll/index.js +1 -0
- package/dist/scroll/index.js.map +1 -1
- package/dist/scroll/public.d.ts +19 -1
- package/dist/scroll/public.d.ts.map +1 -1
- package/dist/scroll/public.js +26 -1
- package/dist/scroll/public.js.map +1 -1
- package/dist/target/DomTarget.js +1 -1
- package/dist/target/DomTarget.js.map +1 -1
- package/dist/target/ObjectTarget.d.ts +11 -10
- package/dist/target/ObjectTarget.d.ts.map +1 -1
- package/dist/target/ObjectTarget.js +20 -13
- package/dist/target/ObjectTarget.js.map +1 -1
- package/dist/timeline/Timeline.d.ts +2 -1
- package/dist/timeline/Timeline.d.ts.map +1 -1
- package/dist/timeline/Timeline.js +4 -4
- package/dist/timeline/Timeline.js.map +1 -1
- package/dist/timeline/public.d.ts +11 -4
- package/dist/timeline/public.d.ts.map +1 -1
- package/dist/timeline/public.js +19 -11
- package/dist/timeline/public.js.map +1 -1
- package/dist/timing/AnimationFrameTicker.d.ts.map +1 -1
- package/dist/timing/AnimationFrameTicker.js +5 -1
- package/dist/timing/AnimationFrameTicker.js.map +1 -1
- package/dist/timing/TestTicker.d.ts.map +1 -1
- package/dist/timing/TestTicker.js +5 -1
- package/dist/timing/TestTicker.js.map +1 -1
- package/dist/timing/Ticker.d.ts +4 -2
- package/dist/timing/Ticker.d.ts.map +1 -1
- package/dist/timing/Timing.d.ts +47 -2
- package/dist/timing/Timing.d.ts.map +1 -1
- package/dist/timing/Timing.js +118 -84
- package/dist/timing/Timing.js.map +1 -1
- package/dist/utils/Events.js +1 -1
- package/dist/utils/Events.js.map +1 -1
- package/dist/utils/motionpath.js +5 -5
- package/dist/utils/motionpath.js.map +1 -1
- package/dist/utils/utils.d.ts.map +1 -1
- package/dist/utils/utils.js +0 -8
- package/dist/utils/utils.js.map +1 -1
- package/dist/values/ColorValue.js +1 -0
- package/dist/values/ColorValue.js.map +1 -1
- package/dist/values/Value.js +1 -1
- package/dist/values/Value.js.map +1 -1
- 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
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
|
}
|
package/src/utils/Events.ts
CHANGED
package/src/utils/motionpath.ts
CHANGED
|
@@ -7,10 +7,10 @@ function catmullRom(
|
|
|
7
7
|
p1Tension: number,
|
|
8
8
|
p2Tension: number,
|
|
9
9
|
) {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
const v0 = (p2 - p0) * p1Tension;
|
|
11
|
+
const v1 = (p3 - p1) * p2Tension;
|
|
12
|
+
const t2 = t * t;
|
|
13
|
+
const t3 = t2 * t;
|
|
14
14
|
|
|
15
15
|
return (
|
|
16
16
|
(2 * p1 - 2 * p2 + v0 + v1) * t3 +
|
|
@@ -40,7 +40,7 @@ export function curve(
|
|
|
40
40
|
): (t: number) => { x: number; y: number } {
|
|
41
41
|
if (points.length <= 1) throw new Error('curve expects at least 2 points');
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
const startEndStraight = opts.startEndStraight ?? true;
|
|
44
44
|
if (startEndStraight) {
|
|
45
45
|
points[0].straight = true;
|
|
46
46
|
points[points.length - 1].straight = true;
|
package/src/utils/utils.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { Callback } from '../responsive/ResponsiveEvent.js';
|
|
2
1
|
import { curve } from './motionpath.js';
|
|
3
2
|
|
|
4
3
|
export { curve };
|
|
@@ -100,15 +99,6 @@ export function words(
|
|
|
100
99
|
* get the offset to the current page page
|
|
101
100
|
*/
|
|
102
101
|
export function pageOffset(el: HTMLElement) {
|
|
103
|
-
if ('offsetTop' in el) {
|
|
104
|
-
return {
|
|
105
|
-
top: el.offsetTop,
|
|
106
|
-
left: el.offsetLeft,
|
|
107
|
-
width: el.offsetWidth,
|
|
108
|
-
height: el.offsetHeight,
|
|
109
|
-
};
|
|
110
|
-
}
|
|
111
|
-
|
|
112
102
|
const rect = (el as HTMLElement).getBoundingClientRect();
|
|
113
103
|
return {
|
|
114
104
|
top: window.scrollY + rect.top,
|
package/src/values/ColorValue.ts
CHANGED
package/src/values/Value.ts
CHANGED
package/.eslintrc.cjs
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
module.exports = {
|
|
2
|
-
"env": {
|
|
3
|
-
"browser": true,
|
|
4
|
-
"es2021": true
|
|
5
|
-
},
|
|
6
|
-
"extends": "eslint:recommended",
|
|
7
|
-
"overrides": [
|
|
8
|
-
{
|
|
9
|
-
"env": {
|
|
10
|
-
"node": true
|
|
11
|
-
},
|
|
12
|
-
"files": [
|
|
13
|
-
".eslintrc.{js,cjs}"
|
|
14
|
-
],
|
|
15
|
-
"parserOptions": {
|
|
16
|
-
"sourceType": "script"
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
],
|
|
20
|
-
"parserOptions": {
|
|
21
|
-
"ecmaVersion": "latest",
|
|
22
|
-
"sourceType": "module"
|
|
23
|
-
},
|
|
24
|
-
"rules": {
|
|
25
|
-
"no-unused-vars": [
|
|
26
|
-
"error",
|
|
27
|
-
{
|
|
28
|
-
"varsIgnorePattern": "^_",
|
|
29
|
-
"argsIgnorePattern": "^_"
|
|
30
|
-
}
|
|
31
|
-
],
|
|
32
|
-
"no-constant-condition": [
|
|
33
|
-
"error",
|
|
34
|
-
{
|
|
35
|
-
"checkLoops": false
|
|
36
|
-
}
|
|
37
|
-
]
|
|
38
|
-
}
|
|
39
|
-
}
|
package/src/animator.js
DELETED
|
@@ -1,187 +0,0 @@
|
|
|
1
|
-
/* eslint no-unused-vars: 0 */
|
|
2
|
-
|
|
3
|
-
import { quadInOut, quadOut } from './easing/index.js';
|
|
4
|
-
import { range } from 'fire/util.js';
|
|
5
|
-
|
|
6
|
-
const START = 0;
|
|
7
|
-
const RUNNING = 1;
|
|
8
|
-
const ENDING = 2;
|
|
9
|
-
const ENDED = 3;
|
|
10
|
-
|
|
11
|
-
export default class Animator {
|
|
12
|
-
constructor(el, props) {
|
|
13
|
-
this.el = el;
|
|
14
|
-
|
|
15
|
-
this.running = false;
|
|
16
|
-
|
|
17
|
-
this.props = [];
|
|
18
|
-
|
|
19
|
-
this.prevTime = null;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
for (const propName in props) {
|
|
23
|
-
const prop = new PropertyAnimator(propName, props[propName], el);
|
|
24
|
-
this.props.push(prop);
|
|
25
|
-
this[propName] = prop;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// if the animation loop has not started starts it
|
|
30
|
-
run() {
|
|
31
|
-
// if running
|
|
32
|
-
if (this.prevTime !== null)
|
|
33
|
-
return;
|
|
34
|
-
|
|
35
|
-
requestAnimationFrame(a => this._tick(a));
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
_tick(elapsed) {
|
|
39
|
-
if (this.prevTime === null)
|
|
40
|
-
this.prevTime = elapsed;
|
|
41
|
-
|
|
42
|
-
const change = elapsed - this.prevTime;
|
|
43
|
-
this.prevTime = elapsed;
|
|
44
|
-
|
|
45
|
-
const transforms = [];
|
|
46
|
-
const cssVars = [];
|
|
47
|
-
|
|
48
|
-
let stillRunning = false;
|
|
49
|
-
|
|
50
|
-
for (const prop of this.props) {
|
|
51
|
-
prop._tick(change);
|
|
52
|
-
|
|
53
|
-
if (prop.state < ENDED)
|
|
54
|
-
stillRunning = true;
|
|
55
|
-
|
|
56
|
-
if (prop.name === 'translateY' || prop.name === 'scale')
|
|
57
|
-
transforms.push(prop);
|
|
58
|
-
else if (prop.name.startsWith('--'))
|
|
59
|
-
cssVars.push(prop);
|
|
60
|
-
else
|
|
61
|
-
throw new Error('unknown prop ' + prop.name);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
if (!stillRunning) {
|
|
65
|
-
this.prevTime = null;
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
if (transforms.some(t => t.state < ENDED)) {
|
|
70
|
-
this.el.style.transform = transforms.map(t => {
|
|
71
|
-
const v = t._toTransformValue();
|
|
72
|
-
return v;
|
|
73
|
-
}).join(' ');
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
for (const prop of cssVars) {
|
|
77
|
-
if (prop.state < ENDED)
|
|
78
|
-
this.el.style.setProperty(prop.name, prop._toCssValue());
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
requestAnimationFrame(a => this._tick(a));
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
class PropertyAnimator {
|
|
87
|
-
constructor(name, type, el) {
|
|
88
|
-
this.name = name;
|
|
89
|
-
this.type = type;
|
|
90
|
-
|
|
91
|
-
this.fromV = null;
|
|
92
|
-
this.currentV = null;
|
|
93
|
-
this.toV = null;
|
|
94
|
-
|
|
95
|
-
this.easing = quadInOut;
|
|
96
|
-
|
|
97
|
-
this.elapsed = 0;
|
|
98
|
-
this.duration = 0;
|
|
99
|
-
this.state = ENDED;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
set(val) {
|
|
103
|
-
this.fromV = val;
|
|
104
|
-
this.currentV = val;
|
|
105
|
-
this.toV = val;
|
|
106
|
-
|
|
107
|
-
this.elapsed = 0;
|
|
108
|
-
this.duration = 0;
|
|
109
|
-
this.state = START;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
to(val, dur = null) {
|
|
113
|
-
this.fromV = this.currentV;
|
|
114
|
-
this.toV = val;
|
|
115
|
-
|
|
116
|
-
if (this.state === RUNNING)
|
|
117
|
-
this.easing = quadOut;
|
|
118
|
-
else
|
|
119
|
-
this.easing = quadInOut;
|
|
120
|
-
|
|
121
|
-
this.elapsed = 0;
|
|
122
|
-
this.duration = dur ?? 500;
|
|
123
|
-
this.state = START;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
_tick(change) {
|
|
127
|
-
if (this.state >= ENDING)
|
|
128
|
-
return this.state = ENDED;
|
|
129
|
-
|
|
130
|
-
this.elapsed += change;
|
|
131
|
-
|
|
132
|
-
const dur = Math.max(this.duration, 1);
|
|
133
|
-
const t = Math.min(this.elapsed / dur, 1);
|
|
134
|
-
if (t >= 1)
|
|
135
|
-
this.state = ENDED;
|
|
136
|
-
else
|
|
137
|
-
this.state = RUNNING;
|
|
138
|
-
|
|
139
|
-
const et = this.easing(t);
|
|
140
|
-
|
|
141
|
-
if (this.type === 'num') {
|
|
142
|
-
const dif = this.toV - this.fromV;
|
|
143
|
-
this.currentV = this.fromV + dif * et;
|
|
144
|
-
} else if (this.type === 'hex') {
|
|
145
|
-
if (!Array.isArray(this.fromV))
|
|
146
|
-
this.fromV = hexToRgb(this.fromV);
|
|
147
|
-
if (!Array.isArray(this.toV))
|
|
148
|
-
this.toV = hexToRgb(this.toV);
|
|
149
|
-
|
|
150
|
-
// now animate
|
|
151
|
-
this.currentV = this.fromV.map((from, i) => {
|
|
152
|
-
return from + (this.toV[i] - from) * et;
|
|
153
|
-
});
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
_toTransformValue() {
|
|
158
|
-
let v = this.currentV;
|
|
159
|
-
if (this.name === 'translateY')
|
|
160
|
-
v += 'px';
|
|
161
|
-
|
|
162
|
-
return `${this.name}(${v})`;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
_toCssValue() {
|
|
166
|
-
if (this.type === 'hex')
|
|
167
|
-
return `rgba(${this.currentV.map(v => Math.round(v)).join()}, 1)`;
|
|
168
|
-
throw new Error('to css value');
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
function hexToRgb(val) {
|
|
174
|
-
if (!val.startsWith('#') || val.length !== 7)
|
|
175
|
-
throw new Error('expected a hex value with 6 characters');
|
|
176
|
-
|
|
177
|
-
const hex = val.substring(1);
|
|
178
|
-
|
|
179
|
-
const values = range(0, 3)
|
|
180
|
-
.map(i => parseInt(hex.substring(i * 2, i * 2 + 2), 16));
|
|
181
|
-
|
|
182
|
-
return values;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
// function rgbToHex(rgb) {
|
|
186
|
-
// return
|
|
187
|
-
// }
|