motion 10.5.2 → 10.6.0-rc.5
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/CHANGELOG.md +6 -0
- package/dist/animate.cjs.js +23 -0
- package/dist/animate.es.js +18 -0
- package/dist/main.cjs.js +21 -5
- package/dist/main.es.js +2 -1
- package/dist/motion.min.js +1 -1
- package/dist/motion.umd.js +258 -629
- package/dist/size-index.js +1 -1
- package/lib/animate.js +16 -0
- package/lib/animate.js.map +1 -0
- package/lib/index.js +2 -1
- package/lib/index.js.map +1 -1
- package/package.json +9 -7
- package/types/animate.d.ts +6 -0
- package/types/animate.d.ts.map +1 -0
- package/types/index.d.ts +2 -1
- package/types/index.d.ts.map +1 -1
package/dist/motion.umd.js
CHANGED
|
@@ -25,9 +25,62 @@
|
|
|
25
25
|
index > -1 && arr.splice(index, 1);
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
+
const clamp = (min, max, v) => Math.min(Math.max(v, min), max);
|
|
29
|
+
|
|
30
|
+
const defaults$1 = {
|
|
31
|
+
duration: 0.3,
|
|
32
|
+
delay: 0,
|
|
33
|
+
endDelay: 0,
|
|
34
|
+
repeat: 0,
|
|
35
|
+
easing: "ease",
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const isNumber = (value) => typeof value === "number";
|
|
39
|
+
const isEasingGenerator = (easing) => typeof easing === "object" &&
|
|
40
|
+
Boolean(easing.createAnimation);
|
|
41
|
+
const isCubicBezier = (easing) => Array.isArray(easing) && isNumber(easing[0]);
|
|
42
|
+
const isEasingList = (easing) => Array.isArray(easing) && !isNumber(easing[0]);
|
|
43
|
+
|
|
44
|
+
const mix = (min, max, progress) => -progress * min + progress * max + min;
|
|
45
|
+
|
|
28
46
|
const noop = () => { };
|
|
29
47
|
const noopReturn = (v) => v;
|
|
30
48
|
|
|
49
|
+
const progress = (min, max, value) => max - min === 0 ? 1 : (value - min) / (max - min);
|
|
50
|
+
|
|
51
|
+
function fillOffset(offset, remaining) {
|
|
52
|
+
const min = offset[offset.length - 1];
|
|
53
|
+
for (let i = 1; i <= remaining; i++) {
|
|
54
|
+
const offsetProgress = progress(0, remaining, i);
|
|
55
|
+
offset.push(mix(min, 1, offsetProgress));
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function defaultOffset(length) {
|
|
59
|
+
const offset = [0];
|
|
60
|
+
fillOffset(offset, length - 1);
|
|
61
|
+
return offset;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const time = {
|
|
65
|
+
ms: (seconds) => seconds * 1000,
|
|
66
|
+
s: (milliseconds) => milliseconds / 1000,
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
/*
|
|
70
|
+
Convert velocity into velocity per second
|
|
71
|
+
|
|
72
|
+
@param [number]: Unit per frame
|
|
73
|
+
@param [number]: Frame duration in ms
|
|
74
|
+
*/
|
|
75
|
+
function velocityPerSecond(velocity, frameDuration) {
|
|
76
|
+
return frameDuration ? velocity * (1000 / frameDuration) : 0;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const wrap = (min, max, v) => {
|
|
80
|
+
const rangeSize = max - min;
|
|
81
|
+
return ((((v - min) % rangeSize) + rangeSize) % rangeSize) + min;
|
|
82
|
+
};
|
|
83
|
+
|
|
31
84
|
/**
|
|
32
85
|
* A list of all transformable axes. We'll use this list to generated a version
|
|
33
86
|
* of each axes for each transform.
|
|
@@ -117,51 +170,6 @@
|
|
|
117
170
|
catch (e) { }
|
|
118
171
|
}
|
|
119
172
|
|
|
120
|
-
const ms = (seconds) => seconds * 1000;
|
|
121
|
-
|
|
122
|
-
const isNumber = (value) => typeof value === "number";
|
|
123
|
-
|
|
124
|
-
const isCubicBezier = (easing) => Array.isArray(easing) && isNumber(easing[0]);
|
|
125
|
-
const isEasingList = (easing) => Array.isArray(easing) && !isNumber(easing[0]);
|
|
126
|
-
const isCustomEasing = (easing) => typeof easing === "object" &&
|
|
127
|
-
Boolean(easing.createAnimation);
|
|
128
|
-
const convertEasing = (easing) => isCubicBezier(easing) ? cubicBezierAsString(easing) : easing;
|
|
129
|
-
const cubicBezierAsString = ([a, b, c, d]) => `cubic-bezier(${a}, ${b}, ${c}, ${d})`;
|
|
130
|
-
|
|
131
|
-
const testAnimation = (keyframes) => document.createElement("div").animate(keyframes, { duration: 0.001 });
|
|
132
|
-
const featureTests = {
|
|
133
|
-
cssRegisterProperty: () => typeof CSS !== "undefined" &&
|
|
134
|
-
Object.hasOwnProperty.call(CSS, "registerProperty"),
|
|
135
|
-
waapi: () => Object.hasOwnProperty.call(Element.prototype, "animate"),
|
|
136
|
-
partialKeyframes: () => {
|
|
137
|
-
try {
|
|
138
|
-
testAnimation({ opacity: [1] });
|
|
139
|
-
}
|
|
140
|
-
catch (e) {
|
|
141
|
-
return false;
|
|
142
|
-
}
|
|
143
|
-
return true;
|
|
144
|
-
},
|
|
145
|
-
finished: () => Boolean(testAnimation({ opacity: [0, 1] }).finished),
|
|
146
|
-
};
|
|
147
|
-
const results = {};
|
|
148
|
-
const supports = {};
|
|
149
|
-
for (const key in featureTests) {
|
|
150
|
-
supports[key] = () => {
|
|
151
|
-
if (results[key] === undefined)
|
|
152
|
-
results[key] = featureTests[key]();
|
|
153
|
-
return results[key];
|
|
154
|
-
};
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
const defaults = {
|
|
158
|
-
duration: 0.3,
|
|
159
|
-
delay: 0,
|
|
160
|
-
endDelay: 0,
|
|
161
|
-
repeat: 0,
|
|
162
|
-
easing: "ease",
|
|
163
|
-
};
|
|
164
|
-
|
|
165
173
|
/*
|
|
166
174
|
Bezier function generator
|
|
167
175
|
|
|
@@ -212,11 +220,11 @@
|
|
|
212
220
|
return (t) => t === 0 || t === 1 ? t : calcBezier(getTForX(t), mY1, mY2);
|
|
213
221
|
}
|
|
214
222
|
|
|
215
|
-
const clamp = (min, max, v) => Math.min(Math.max(v, min), max);
|
|
216
|
-
|
|
217
223
|
const steps = (steps, direction = "end") => (progress) => {
|
|
218
224
|
progress =
|
|
219
|
-
direction === "end"
|
|
225
|
+
direction === "end"
|
|
226
|
+
? Math.min(progress, 0.999)
|
|
227
|
+
: Math.max(progress, 0.001);
|
|
220
228
|
const expanded = progress * steps;
|
|
221
229
|
const rounded = direction === "end" ? Math.floor(expanded) : Math.ceil(expanded);
|
|
222
230
|
return clamp(0, 1, rounded / steps);
|
|
@@ -249,71 +257,14 @@
|
|
|
249
257
|
}
|
|
250
258
|
return noopReturn;
|
|
251
259
|
}
|
|
252
|
-
|
|
253
|
-
/*
|
|
254
|
-
Value in range from progress
|
|
255
|
-
|
|
256
|
-
Given a lower limit and an upper limit, we return the value within
|
|
257
|
-
that range as expressed by progress (usually a number from 0 to 1)
|
|
258
|
-
|
|
259
|
-
So progress = 0.5 would change
|
|
260
|
-
|
|
261
|
-
from -------- to
|
|
262
|
-
|
|
263
|
-
to
|
|
264
|
-
|
|
265
|
-
from ---- to
|
|
266
|
-
|
|
267
|
-
E.g. from = 10, to = 20, progress = 0.5 => 15
|
|
268
|
-
|
|
269
|
-
@param [number]: Lower limit of range
|
|
270
|
-
@param [number]: Upper limit of range
|
|
271
|
-
@param [number]: The progress between lower and upper limits expressed 0-1
|
|
272
|
-
@return [number]: Value as calculated from progress within range (not limited within range)
|
|
273
|
-
*/
|
|
274
|
-
const mix = (from, to, progress) => -progress * from + progress * to + from;
|
|
275
|
-
|
|
276
|
-
/*
|
|
277
|
-
Progress within given range
|
|
278
|
-
|
|
279
|
-
Given a lower limit and an upper limit, we return the progress
|
|
280
|
-
(expressed as a number 0-1) represented by the given value.
|
|
281
|
-
|
|
282
|
-
@param [number]: Lower limit
|
|
283
|
-
@param [number]: Upper limit
|
|
284
|
-
@param [number]: Value to find progress within given range
|
|
285
|
-
@return [number]: Progress of value within range as expressed 0-1
|
|
286
|
-
*/
|
|
287
|
-
const progress = (from, to, value) => {
|
|
288
|
-
return to - from === 0 ? 1 : (value - from) / (to - from);
|
|
289
|
-
};
|
|
290
|
-
|
|
291
|
-
const wrap = (min, max, v) => {
|
|
292
|
-
const rangeSize = max - min;
|
|
293
|
-
return ((((v - min) % rangeSize) + rangeSize) % rangeSize) + min;
|
|
294
|
-
};
|
|
295
|
-
|
|
296
260
|
function getEasingForSegment(easing, i) {
|
|
297
261
|
return isEasingList(easing)
|
|
298
262
|
? easing[wrap(0, easing.length, i)]
|
|
299
263
|
: easing;
|
|
300
264
|
}
|
|
301
265
|
|
|
302
|
-
function fillOffset(offset, remaining) {
|
|
303
|
-
const min = offset[offset.length - 1];
|
|
304
|
-
for (let i = 1; i <= remaining; i++) {
|
|
305
|
-
const offsetProgress = progress(0, remaining, i);
|
|
306
|
-
offset.push(mix(min, 1, offsetProgress));
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
function defaultOffset(length) {
|
|
310
|
-
const offset = [0];
|
|
311
|
-
fillOffset(offset, length - 1);
|
|
312
|
-
return offset;
|
|
313
|
-
}
|
|
314
|
-
|
|
315
266
|
const clampProgress = (p) => Math.min(1, Math.max(p, 0));
|
|
316
|
-
function
|
|
267
|
+
function interpolate(output, input = defaultOffset(output.length), easing = noopReturn) {
|
|
317
268
|
const length = output.length;
|
|
318
269
|
/**
|
|
319
270
|
* If the input length is lower than the output we
|
|
@@ -336,8 +287,8 @@
|
|
|
336
287
|
};
|
|
337
288
|
}
|
|
338
289
|
|
|
339
|
-
class
|
|
340
|
-
constructor(output, keyframes = [0, 1], { easing = defaults.easing, duration = defaults.duration, delay = defaults.delay, endDelay = defaults.endDelay, repeat = defaults.repeat, offset, direction = "normal", } = {}) {
|
|
290
|
+
class Animation {
|
|
291
|
+
constructor(output, keyframes = [0, 1], { easing = defaults$1.easing, duration = defaults$1.duration, delay = defaults$1.delay, endDelay = defaults$1.endDelay, repeat = defaults$1.repeat, offset, direction = "normal", } = {}) {
|
|
341
292
|
this.startTime = 0;
|
|
342
293
|
this.rate = 1;
|
|
343
294
|
this.t = 0;
|
|
@@ -348,14 +299,15 @@
|
|
|
348
299
|
this.reject = reject;
|
|
349
300
|
});
|
|
350
301
|
const totalDuration = duration * (repeat + 1);
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
302
|
+
if (isEasingGenerator(easing)) {
|
|
303
|
+
const custom = easing.createAnimation(keyframes, () => "0", true);
|
|
304
|
+
easing = custom.easing;
|
|
305
|
+
if (custom.keyframes !== undefined)
|
|
306
|
+
keyframes = custom.keyframes;
|
|
307
|
+
if (custom.duration !== undefined)
|
|
308
|
+
duration = custom.duration;
|
|
309
|
+
}
|
|
310
|
+
const interpolate$1 = interpolate(keyframes, offset, isEasingList(easing)
|
|
359
311
|
? easing.map(getEasingFunction)
|
|
360
312
|
: getEasingFunction(easing));
|
|
361
313
|
this.tick = (timestamp) => {
|
|
@@ -408,7 +360,7 @@
|
|
|
408
360
|
(direction === "alternate-reverse" && !iterationIsOdd)) {
|
|
409
361
|
iterationProgress = 1 - iterationProgress;
|
|
410
362
|
}
|
|
411
|
-
const latest = interpolate(t >= totalDuration ? 1 : Math.min(iterationProgress, 1));
|
|
363
|
+
const latest = interpolate$1(t >= totalDuration ? 1 : Math.min(iterationProgress, 1));
|
|
412
364
|
output(latest);
|
|
413
365
|
const isAnimationFinished = this.playState === "finished" || t >= totalDuration + endDelay;
|
|
414
366
|
if (isAnimationFinished) {
|
|
@@ -416,7 +368,7 @@
|
|
|
416
368
|
(_a = this.resolve) === null || _a === void 0 ? void 0 : _a.call(this, latest);
|
|
417
369
|
}
|
|
418
370
|
else if (this.playState !== "idle") {
|
|
419
|
-
requestAnimationFrame(this.tick);
|
|
371
|
+
this.frameRequestId = requestAnimationFrame(this.tick);
|
|
420
372
|
}
|
|
421
373
|
};
|
|
422
374
|
this.play();
|
|
@@ -446,11 +398,16 @@
|
|
|
446
398
|
this.playState = "idle";
|
|
447
399
|
this.tick(this.cancelTimestamp);
|
|
448
400
|
(_a = this.reject) === null || _a === void 0 ? void 0 : _a.call(this, false);
|
|
401
|
+
if (this.frameRequestId !== undefined) {
|
|
402
|
+
cancelAnimationFrame(this.frameRequestId);
|
|
403
|
+
}
|
|
449
404
|
}
|
|
450
405
|
reverse() {
|
|
451
406
|
this.rate *= -1;
|
|
452
407
|
}
|
|
453
408
|
commitStyles() {
|
|
409
|
+
// TODO: The bug now is that this is not called if the animation is finished
|
|
410
|
+
// this should be called regardless
|
|
454
411
|
this.cancelTimestamp = performance.now();
|
|
455
412
|
}
|
|
456
413
|
get currentTime() {
|
|
@@ -472,6 +429,35 @@
|
|
|
472
429
|
}
|
|
473
430
|
}
|
|
474
431
|
|
|
432
|
+
const convertEasing = (easing) => isCubicBezier(easing) ? cubicBezierAsString(easing) : easing;
|
|
433
|
+
const cubicBezierAsString = ([a, b, c, d]) => `cubic-bezier(${a}, ${b}, ${c}, ${d})`;
|
|
434
|
+
|
|
435
|
+
const testAnimation = (keyframes) => document.createElement("div").animate(keyframes, { duration: 0.001 });
|
|
436
|
+
const featureTests = {
|
|
437
|
+
cssRegisterProperty: () => typeof CSS !== "undefined" &&
|
|
438
|
+
Object.hasOwnProperty.call(CSS, "registerProperty"),
|
|
439
|
+
waapi: () => Object.hasOwnProperty.call(Element.prototype, "animate"),
|
|
440
|
+
partialKeyframes: () => {
|
|
441
|
+
try {
|
|
442
|
+
testAnimation({ opacity: [1] });
|
|
443
|
+
}
|
|
444
|
+
catch (e) {
|
|
445
|
+
return false;
|
|
446
|
+
}
|
|
447
|
+
return true;
|
|
448
|
+
},
|
|
449
|
+
finished: () => Boolean(testAnimation({ opacity: [0, 1] }).finished),
|
|
450
|
+
};
|
|
451
|
+
const results = {};
|
|
452
|
+
const supports = {};
|
|
453
|
+
for (const key in featureTests) {
|
|
454
|
+
supports[key] = () => {
|
|
455
|
+
if (results[key] === undefined)
|
|
456
|
+
results[key] = featureTests[key]();
|
|
457
|
+
return results[key];
|
|
458
|
+
};
|
|
459
|
+
}
|
|
460
|
+
|
|
475
461
|
function hydrateKeyframes(keyframes, readInitialValue) {
|
|
476
462
|
for (let i = 0; i < keyframes.length; i++) {
|
|
477
463
|
if (keyframes[i] === null) {
|
|
@@ -513,14 +499,14 @@
|
|
|
513
499
|
};
|
|
514
500
|
|
|
515
501
|
function stopAnimation(animation) {
|
|
516
|
-
if (!animation)
|
|
502
|
+
if (!animation || animation.playState === "finished")
|
|
517
503
|
return;
|
|
518
504
|
// Suppress error thrown by WAAPI
|
|
519
505
|
try {
|
|
520
506
|
/**
|
|
521
507
|
* commitStyles has overhead so we only want to commit and cancel
|
|
522
508
|
*/
|
|
523
|
-
animation.
|
|
509
|
+
animation.commitStyles();
|
|
524
510
|
animation.cancel();
|
|
525
511
|
}
|
|
526
512
|
catch (e) { }
|
|
@@ -528,7 +514,7 @@
|
|
|
528
514
|
|
|
529
515
|
function animateStyle(element, key, keyframesDefinition, options = {}) {
|
|
530
516
|
let animation;
|
|
531
|
-
let { duration = defaults.duration, delay = defaults.delay, endDelay = defaults.endDelay, repeat = defaults.repeat, easing = defaults.easing, direction, offset, allowWebkitAcceleration = false, } = options;
|
|
517
|
+
let { duration = defaults$1.duration, delay = defaults$1.delay, endDelay = defaults$1.endDelay, repeat = defaults$1.repeat, easing = defaults$1.easing, direction, offset, allowWebkitAcceleration = false, } = options;
|
|
532
518
|
const data = getAnimationData(element);
|
|
533
519
|
let canAnimateNatively = supports.waapi();
|
|
534
520
|
const valueIsTransform = isTransform(key);
|
|
@@ -560,7 +546,7 @@
|
|
|
560
546
|
* it from the DOM if it's the first keyframe.
|
|
561
547
|
*/
|
|
562
548
|
let keyframes = hydrateKeyframes(keyframesList(keyframesDefinition), readInitialValue);
|
|
563
|
-
if (
|
|
549
|
+
if (isEasingGenerator(easing)) {
|
|
564
550
|
const custom = easing.createAnimation(keyframes, readInitialValue, valueIsTransform, name, data);
|
|
565
551
|
easing = custom.easing;
|
|
566
552
|
if (custom.keyframes !== undefined)
|
|
@@ -601,9 +587,9 @@
|
|
|
601
587
|
keyframes.unshift(readInitialValue());
|
|
602
588
|
}
|
|
603
589
|
const animationOptions = {
|
|
604
|
-
delay: ms(delay),
|
|
605
|
-
duration: ms(duration),
|
|
606
|
-
endDelay: ms(endDelay),
|
|
590
|
+
delay: time.ms(delay),
|
|
591
|
+
duration: time.ms(duration),
|
|
592
|
+
endDelay: time.ms(endDelay),
|
|
607
593
|
easing: !isEasingList(easing) ? convertEasing(easing) : undefined,
|
|
608
594
|
direction,
|
|
609
595
|
iterations: repeat + 1,
|
|
@@ -661,7 +647,7 @@
|
|
|
661
647
|
latest = definition.toDefaultUnit(latest);
|
|
662
648
|
style.set(element, name, latest);
|
|
663
649
|
};
|
|
664
|
-
animation = new
|
|
650
|
+
animation = new Animation(render, keyframes, Object.assign(Object.assign({}, options), { duration,
|
|
665
651
|
easing }));
|
|
666
652
|
}
|
|
667
653
|
else {
|
|
@@ -709,7 +695,7 @@
|
|
|
709
695
|
}
|
|
710
696
|
|
|
711
697
|
const createAnimation = (factory) => factory();
|
|
712
|
-
const
|
|
698
|
+
const wrapAnimationWithControls = (animationFactory, duration = defaults$1.duration) => new Proxy({
|
|
713
699
|
animations: animationFactory.map(createAnimation).filter(Boolean),
|
|
714
700
|
duration,
|
|
715
701
|
}, controls);
|
|
@@ -744,7 +730,7 @@
|
|
|
744
730
|
set: (target, key, value) => {
|
|
745
731
|
switch (key) {
|
|
746
732
|
case "currentTime":
|
|
747
|
-
value = ms(value);
|
|
733
|
+
value = time.ms(value);
|
|
748
734
|
case "currentTime":
|
|
749
735
|
case "playbackRate":
|
|
750
736
|
for (let i = 0; i < target.animations.length; i++) {
|
|
@@ -785,8 +771,7 @@
|
|
|
785
771
|
: option;
|
|
786
772
|
}
|
|
787
773
|
|
|
788
|
-
function animate(elements, keyframes, options = {}) {
|
|
789
|
-
var _a;
|
|
774
|
+
function animate$1(elements, keyframes, options = {}) {
|
|
790
775
|
elements = resolveElements(elements);
|
|
791
776
|
const numElements = elements.length;
|
|
792
777
|
/**
|
|
@@ -802,7 +787,7 @@
|
|
|
802
787
|
animationFactories.push(animation);
|
|
803
788
|
}
|
|
804
789
|
}
|
|
805
|
-
return
|
|
790
|
+
return wrapAnimationWithControls(animationFactories,
|
|
806
791
|
/**
|
|
807
792
|
* TODO:
|
|
808
793
|
* If easing is set to spring or glide, duration will be dynamically
|
|
@@ -812,7 +797,7 @@
|
|
|
812
797
|
* to Proxy animations returned from animateStyle that has duration
|
|
813
798
|
* as a getter.
|
|
814
799
|
*/
|
|
815
|
-
|
|
800
|
+
options.duration);
|
|
816
801
|
}
|
|
817
802
|
|
|
818
803
|
/*! *****************************************************************************
|
|
@@ -903,7 +888,7 @@
|
|
|
903
888
|
}
|
|
904
889
|
|
|
905
890
|
function timeline(definition, options = {}) {
|
|
906
|
-
var _a
|
|
891
|
+
var _a;
|
|
907
892
|
const animationDefinitions = createAnimationsFromTimeline(definition, options);
|
|
908
893
|
/**
|
|
909
894
|
* Create and start animations
|
|
@@ -911,9 +896,9 @@
|
|
|
911
896
|
const animationFactories = animationDefinitions
|
|
912
897
|
.map((definition) => animateStyle(...definition))
|
|
913
898
|
.filter(Boolean);
|
|
914
|
-
return
|
|
899
|
+
return wrapAnimationWithControls(animationFactories,
|
|
915
900
|
// Get the duration from the first animation definition
|
|
916
|
-
(
|
|
901
|
+
(_a = animationDefinitions[0]) === null || _a === void 0 ? void 0 : _a[3].duration);
|
|
917
902
|
}
|
|
918
903
|
function createAnimationsFromTimeline(definition, _a = {}) {
|
|
919
904
|
var { defaultOptions = {} } = _a, timelineOptions = __rest(_a, ["defaultOptions"]);
|
|
@@ -956,8 +941,8 @@
|
|
|
956
941
|
const valueSequence = getValueSequence(key, elementSequence);
|
|
957
942
|
let valueKeyframes = keyframesList(keyframes[key]);
|
|
958
943
|
const valueOptions = getOptions(options, key);
|
|
959
|
-
let { duration = defaultOptions.duration || defaults.duration, easing = defaultOptions.easing || defaults.easing, } = valueOptions;
|
|
960
|
-
if (
|
|
944
|
+
let { duration = defaultOptions.duration || defaults$1.duration, easing = defaultOptions.easing || defaults$1.easing, } = valueOptions;
|
|
945
|
+
if (isEasingGenerator(easing)) {
|
|
961
946
|
const valueIsTransform = isTransform(key);
|
|
962
947
|
invariant(valueKeyframes.length === 2 || !valueIsTransform, "spring must be provided 2 keyframes within timeline");
|
|
963
948
|
const custom = easing.createAnimation(valueKeyframes,
|
|
@@ -1028,7 +1013,7 @@
|
|
|
1028
1013
|
const { at, value, easing } = valueSequence[i];
|
|
1029
1014
|
keyframes.push(value);
|
|
1030
1015
|
valueOffset.push(progress(0, totalDuration, at));
|
|
1031
|
-
valueEasing.push(easing || defaults.easing);
|
|
1016
|
+
valueEasing.push(easing || defaults$1.easing);
|
|
1032
1017
|
}
|
|
1033
1018
|
/**
|
|
1034
1019
|
* If the first keyframe doesn't land on offset: 0
|
|
@@ -1069,34 +1054,34 @@
|
|
|
1069
1054
|
return sequences[name];
|
|
1070
1055
|
}
|
|
1071
1056
|
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
@param [number]: Frame duration in ms
|
|
1077
|
-
*/
|
|
1078
|
-
function velocityPerSecond(velocity, frameDuration) {
|
|
1079
|
-
return frameDuration ? velocity * (1000 / frameDuration) : 0;
|
|
1057
|
+
const sampleT = 5; // ms
|
|
1058
|
+
function calcGeneratorVelocity(resolveValue, t, current) {
|
|
1059
|
+
const prevT = Math.max(t - sampleT, 0);
|
|
1060
|
+
return velocityPerSecond(current - resolveValue(prevT), 5);
|
|
1080
1061
|
}
|
|
1081
1062
|
|
|
1063
|
+
const defaults = {
|
|
1064
|
+
stiffness: 100.0,
|
|
1065
|
+
damping: 10.0,
|
|
1066
|
+
mass: 1.0,
|
|
1067
|
+
};
|
|
1068
|
+
|
|
1069
|
+
const calcDampingRatio = (stiffness = defaults.stiffness, damping = defaults.damping, mass = defaults.mass) => damping / (2 * Math.sqrt(stiffness * mass));
|
|
1070
|
+
const calcAngularFreq = (undampedFreq, dampingRatio) => undampedFreq * Math.sqrt(1 - dampingRatio * dampingRatio);
|
|
1071
|
+
|
|
1082
1072
|
function hasReachedTarget(origin, target, current) {
|
|
1083
1073
|
return ((origin < target && current >= target) ||
|
|
1084
1074
|
(origin > target && current <= target));
|
|
1085
1075
|
}
|
|
1086
1076
|
|
|
1087
|
-
const
|
|
1088
|
-
|
|
1089
|
-
const defaultMass = 1.0;
|
|
1090
|
-
const calcDampingRatio = (stiffness = defaultStiffness, damping = defaultDamping, mass = defaultMass) => damping / (2 * Math.sqrt(stiffness * mass));
|
|
1091
|
-
const calcAngularFreq = (undampedFreq, dampingRatio) => undampedFreq * Math.sqrt(1 - dampingRatio * dampingRatio);
|
|
1092
|
-
const createSpringGenerator = ({ stiffness = defaultStiffness, damping = defaultDamping, mass = defaultMass, from = 0, to = 1, velocity = 0.0, restSpeed = 2, restDistance = 0.5, } = {}) => {
|
|
1093
|
-
velocity = velocity ? velocity / 1000 : 0.0;
|
|
1077
|
+
const spring$1 = ({ stiffness = defaults.stiffness, damping = defaults.damping, mass = defaults.mass, from = 0, to = 1, velocity = 0.0, restSpeed = 2, restDistance = 0.5, } = {}) => {
|
|
1078
|
+
velocity = velocity ? time.s(velocity) : 0.0;
|
|
1094
1079
|
const state = {
|
|
1095
1080
|
done: false,
|
|
1096
|
-
|
|
1081
|
+
hasReachedTarget: false,
|
|
1082
|
+
current: from,
|
|
1097
1083
|
target: to,
|
|
1098
1084
|
velocity,
|
|
1099
|
-
hasReachedTarget: false,
|
|
1100
1085
|
};
|
|
1101
1086
|
const dampingRatio = calcDampingRatio(stiffness, damping, mass);
|
|
1102
1087
|
const initialDelta = to - from;
|
|
@@ -1118,35 +1103,119 @@
|
|
|
1118
1103
|
Math.exp(-undampedAngularFreq * t) *
|
|
1119
1104
|
(initialDelta + (velocity + undampedAngularFreq * initialDelta) * t);
|
|
1120
1105
|
}
|
|
1121
|
-
return {
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1106
|
+
return (t) => {
|
|
1107
|
+
state.current = resolveSpring(t);
|
|
1108
|
+
state.velocity =
|
|
1109
|
+
t === 0
|
|
1110
|
+
? velocity
|
|
1111
|
+
: calcGeneratorVelocity(resolveSpring, t, state.current);
|
|
1112
|
+
const isBelowVelocityThreshold = Math.abs(state.velocity) <= restSpeed;
|
|
1113
|
+
const isBelowDisplacementThreshold = Math.abs(to - state.current) <= restDistance;
|
|
1114
|
+
state.done = isBelowVelocityThreshold && isBelowDisplacementThreshold;
|
|
1115
|
+
state.hasReachedTarget = hasReachedTarget(from, to, state.current);
|
|
1116
|
+
return state;
|
|
1117
|
+
};
|
|
1118
|
+
};
|
|
1119
|
+
|
|
1120
|
+
const glide$1 = ({ from = 0, velocity = 0.0, power = 0.8, decay = 0.325, bounceDamping, bounceStiffness, changeTarget, min, max, restDistance = 0.5, restSpeed, }) => {
|
|
1121
|
+
decay = time.ms(decay);
|
|
1122
|
+
const state = {
|
|
1123
|
+
hasReachedTarget: false,
|
|
1124
|
+
done: false,
|
|
1125
|
+
current: from,
|
|
1126
|
+
target: from,
|
|
1127
|
+
velocity,
|
|
1128
|
+
};
|
|
1129
|
+
const isOutOfBounds = (v) => (min !== undefined && v < min) || (max !== undefined && v > max);
|
|
1130
|
+
const nearestBoundary = (v) => {
|
|
1131
|
+
if (min === undefined)
|
|
1132
|
+
return max;
|
|
1133
|
+
if (max === undefined)
|
|
1134
|
+
return min;
|
|
1135
|
+
return Math.abs(min - v) < Math.abs(max - v) ? min : max;
|
|
1136
|
+
};
|
|
1137
|
+
let amplitude = power * velocity;
|
|
1138
|
+
const ideal = from + amplitude;
|
|
1139
|
+
const target = changeTarget === undefined ? ideal : changeTarget(ideal);
|
|
1140
|
+
state.target = target;
|
|
1141
|
+
/**
|
|
1142
|
+
* If the target has changed we need to re-calculate the amplitude, otherwise
|
|
1143
|
+
* the animation will start from the wrong position.
|
|
1144
|
+
*/
|
|
1145
|
+
if (target !== ideal)
|
|
1146
|
+
amplitude = target - from;
|
|
1147
|
+
const calcDelta = (t) => -amplitude * Math.exp(-t / decay);
|
|
1148
|
+
const calcLatest = (t) => target + calcDelta(t);
|
|
1149
|
+
const applyFriction = (t) => {
|
|
1150
|
+
const delta = calcDelta(t);
|
|
1151
|
+
const latest = calcLatest(t);
|
|
1152
|
+
state.done = Math.abs(delta) <= restDistance;
|
|
1153
|
+
state.current = state.done ? target : latest;
|
|
1154
|
+
state.velocity =
|
|
1155
|
+
t === 0 ? velocity : calcGeneratorVelocity(calcLatest, t, state.current);
|
|
1156
|
+
};
|
|
1157
|
+
/**
|
|
1158
|
+
* Ideally this would resolve for t in a stateless way, we could
|
|
1159
|
+
* do that by always precalculating the animation but as we know
|
|
1160
|
+
* this will be done anyway we can assume that spring will
|
|
1161
|
+
* be discovered during that.
|
|
1162
|
+
*/
|
|
1163
|
+
let timeReachedBoundary;
|
|
1164
|
+
let spring$1$1;
|
|
1165
|
+
const checkCatchBoundary = (t) => {
|
|
1166
|
+
if (!isOutOfBounds(state.current))
|
|
1167
|
+
return;
|
|
1168
|
+
timeReachedBoundary = t;
|
|
1169
|
+
spring$1$1 = spring$1({
|
|
1170
|
+
from: state.current,
|
|
1171
|
+
to: nearestBoundary(state.current),
|
|
1172
|
+
velocity: state.velocity,
|
|
1173
|
+
damping: bounceDamping,
|
|
1174
|
+
stiffness: bounceStiffness,
|
|
1175
|
+
restDistance,
|
|
1176
|
+
restSpeed,
|
|
1177
|
+
});
|
|
1178
|
+
};
|
|
1179
|
+
checkCatchBoundary(0);
|
|
1180
|
+
return (t) => {
|
|
1181
|
+
/**
|
|
1182
|
+
* We need to resolve the friction to figure out if we need a
|
|
1183
|
+
* spring but we don't want to do this twice per frame. So here
|
|
1184
|
+
* we flag if we updated for this frame and later if we did
|
|
1185
|
+
* we can skip doing it again.
|
|
1186
|
+
*/
|
|
1187
|
+
let hasUpdatedFrame = false;
|
|
1188
|
+
if (!spring$1$1 && timeReachedBoundary === undefined) {
|
|
1189
|
+
hasUpdatedFrame = true;
|
|
1190
|
+
applyFriction(t);
|
|
1191
|
+
checkCatchBoundary(t);
|
|
1192
|
+
}
|
|
1193
|
+
/**
|
|
1194
|
+
* If we have a spring and the provided t is beyond the moment the friction
|
|
1195
|
+
* animation crossed the min/max boundary, use the spring.
|
|
1196
|
+
*/
|
|
1197
|
+
if (timeReachedBoundary !== undefined && t > timeReachedBoundary) {
|
|
1198
|
+
state.hasReachedTarget = true;
|
|
1199
|
+
return spring$1$1(t - timeReachedBoundary);
|
|
1200
|
+
}
|
|
1201
|
+
else {
|
|
1202
|
+
state.hasReachedTarget = false;
|
|
1203
|
+
!hasUpdatedFrame && applyFriction(t);
|
|
1130
1204
|
return state;
|
|
1131
|
-
}
|
|
1205
|
+
}
|
|
1132
1206
|
};
|
|
1133
1207
|
};
|
|
1134
|
-
const sampleT = 5; // ms
|
|
1135
|
-
function calcVelocity(resolveValue, t, current) {
|
|
1136
|
-
const prevT = Math.max(t - sampleT, 0);
|
|
1137
|
-
return velocityPerSecond(current - resolveValue(prevT), 5);
|
|
1138
|
-
}
|
|
1139
1208
|
|
|
1140
1209
|
const timeStep = 10;
|
|
1141
1210
|
const maxDuration = 10000;
|
|
1142
1211
|
function pregenerateKeyframes(generator) {
|
|
1143
1212
|
let overshootDuration = undefined;
|
|
1144
1213
|
let timestamp = timeStep;
|
|
1145
|
-
let state = generator
|
|
1146
|
-
const keyframes = [state.
|
|
1214
|
+
let state = generator(0);
|
|
1215
|
+
const keyframes = [state.current];
|
|
1147
1216
|
while (!state.done && timestamp < maxDuration) {
|
|
1148
|
-
state = generator
|
|
1149
|
-
keyframes.push(state.done ? state.target : state.
|
|
1217
|
+
state = generator(timestamp);
|
|
1218
|
+
keyframes.push(state.done ? state.target : state.current);
|
|
1150
1219
|
if (overshootDuration === undefined && state.hasReachedTarget) {
|
|
1151
1220
|
overshootDuration = timestamp;
|
|
1152
1221
|
}
|
|
@@ -1158,7 +1227,7 @@
|
|
|
1158
1227
|
* generate a second keyframe so we have an origin and target.
|
|
1159
1228
|
*/
|
|
1160
1229
|
if (keyframes.length === 1)
|
|
1161
|
-
keyframes.push(state.
|
|
1230
|
+
keyframes.push(state.current);
|
|
1162
1231
|
return {
|
|
1163
1232
|
keyframes,
|
|
1164
1233
|
duration: duration / 1000,
|
|
@@ -1204,7 +1273,7 @@
|
|
|
1204
1273
|
const unresolvedOrigin = numKeyframes === 1 ? null : keyframes[0];
|
|
1205
1274
|
const origin = unresolvedOrigin === null
|
|
1206
1275
|
? prevMotionState
|
|
1207
|
-
? prevMotionState.
|
|
1276
|
+
? prevMotionState.current
|
|
1208
1277
|
: parseFloat(getOrigin())
|
|
1209
1278
|
: unresolvedOrigin;
|
|
1210
1279
|
generator = getGenerator(origin, target, velocity, name === null || name === void 0 ? void 0 : name.includes("scale"));
|
|
@@ -1220,7 +1289,7 @@
|
|
|
1220
1289
|
};
|
|
1221
1290
|
}
|
|
1222
1291
|
// TODO Add test for this
|
|
1223
|
-
if (
|
|
1292
|
+
if (data && name) {
|
|
1224
1293
|
data.generators[name] = generator;
|
|
1225
1294
|
}
|
|
1226
1295
|
return settings;
|
|
@@ -1230,466 +1299,26 @@
|
|
|
1230
1299
|
}
|
|
1231
1300
|
const isNumberOrNull = (value) => typeof value !== "string";
|
|
1232
1301
|
|
|
1233
|
-
const spring = createGeneratorEasing(
|
|
1302
|
+
const spring = createGeneratorEasing(spring$1);
|
|
1234
1303
|
|
|
1235
|
-
const
|
|
1236
|
-
decay = ms(decay);
|
|
1237
|
-
const state = {
|
|
1238
|
-
value: from,
|
|
1239
|
-
target: from,
|
|
1240
|
-
velocity,
|
|
1241
|
-
hasReachedTarget: false,
|
|
1242
|
-
done: false,
|
|
1243
|
-
};
|
|
1244
|
-
const isOutOfBounds = (v) => (min !== undefined && v < min) || (max !== undefined && v > max);
|
|
1245
|
-
const nearestBoundary = (v) => {
|
|
1246
|
-
if (min === undefined)
|
|
1247
|
-
return max;
|
|
1248
|
-
if (max === undefined)
|
|
1249
|
-
return min;
|
|
1250
|
-
return Math.abs(min - v) < Math.abs(max - v) ? min : max;
|
|
1251
|
-
};
|
|
1252
|
-
let amplitude = power * velocity;
|
|
1253
|
-
const ideal = from + amplitude;
|
|
1254
|
-
const target = changeTarget === undefined ? ideal : changeTarget(ideal);
|
|
1255
|
-
state.target = target;
|
|
1256
|
-
/**
|
|
1257
|
-
* If the target has changed we need to re-calculate the amplitude, otherwise
|
|
1258
|
-
* the animation will start from the wrong position.
|
|
1259
|
-
*/
|
|
1260
|
-
if (target !== ideal)
|
|
1261
|
-
amplitude = target - from;
|
|
1262
|
-
const calcDelta = (t) => -amplitude * Math.exp(-t / decay);
|
|
1263
|
-
const calcLatest = (t) => target + calcDelta(t);
|
|
1264
|
-
const applyFriction = (t) => {
|
|
1265
|
-
const delta = calcDelta(t);
|
|
1266
|
-
const latest = calcLatest(t);
|
|
1267
|
-
state.done = Math.abs(delta) <= restDistance;
|
|
1268
|
-
state.value = state.done ? target : latest;
|
|
1269
|
-
state.velocity =
|
|
1270
|
-
t === 0 ? velocity : calcVelocity(calcLatest, t, state.value);
|
|
1271
|
-
};
|
|
1272
|
-
/**
|
|
1273
|
-
* Ideally this would resolve for t in a stateless way, we could
|
|
1274
|
-
* do that by always precalculating the animation but as we know
|
|
1275
|
-
* this will be done anyway we can assume that spring will
|
|
1276
|
-
* be discovered during that.
|
|
1277
|
-
*/
|
|
1278
|
-
let timeReachedBoundary;
|
|
1279
|
-
let spring;
|
|
1280
|
-
const checkCatchBoundary = (t) => {
|
|
1281
|
-
if (!isOutOfBounds(state.value))
|
|
1282
|
-
return;
|
|
1283
|
-
timeReachedBoundary = t;
|
|
1284
|
-
spring = createSpringGenerator({
|
|
1285
|
-
from: state.value,
|
|
1286
|
-
to: nearestBoundary(state.value),
|
|
1287
|
-
velocity: state.velocity,
|
|
1288
|
-
damping: bounceDamping,
|
|
1289
|
-
stiffness: bounceStiffness,
|
|
1290
|
-
restDistance,
|
|
1291
|
-
restSpeed,
|
|
1292
|
-
});
|
|
1293
|
-
};
|
|
1294
|
-
checkCatchBoundary(0);
|
|
1295
|
-
return {
|
|
1296
|
-
next: (t) => {
|
|
1297
|
-
/**
|
|
1298
|
-
* We need to resolve the friction to figure out if we need a
|
|
1299
|
-
* spring but we don't want to do this twice per frame. So here
|
|
1300
|
-
* we flag if we updated for this frame and later if we did
|
|
1301
|
-
* we can skip doing it again.
|
|
1302
|
-
*/
|
|
1303
|
-
let hasUpdatedFrame = false;
|
|
1304
|
-
if (!spring && timeReachedBoundary === undefined) {
|
|
1305
|
-
hasUpdatedFrame = true;
|
|
1306
|
-
applyFriction(t);
|
|
1307
|
-
checkCatchBoundary(t);
|
|
1308
|
-
}
|
|
1309
|
-
/**
|
|
1310
|
-
* If we have a spring and the provided t is beyond the moment the friction
|
|
1311
|
-
* animation crossed the min/max boundary, use the spring.
|
|
1312
|
-
*/
|
|
1313
|
-
if (timeReachedBoundary !== undefined && t > timeReachedBoundary) {
|
|
1314
|
-
state.hasReachedTarget = true;
|
|
1315
|
-
return spring.next(t - timeReachedBoundary);
|
|
1316
|
-
}
|
|
1317
|
-
else {
|
|
1318
|
-
state.hasReachedTarget = false;
|
|
1319
|
-
!hasUpdatedFrame && applyFriction(t);
|
|
1320
|
-
return state;
|
|
1321
|
-
}
|
|
1322
|
-
},
|
|
1323
|
-
};
|
|
1324
|
-
};
|
|
1304
|
+
const glide = createGeneratorEasing(glide$1);
|
|
1325
1305
|
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
return !shallowCompare(a, b);
|
|
1333
|
-
return a !== b;
|
|
1334
|
-
}
|
|
1335
|
-
function shallowCompare(next, prev) {
|
|
1336
|
-
const prevLength = prev.length;
|
|
1337
|
-
if (prevLength !== next.length)
|
|
1338
|
-
return false;
|
|
1339
|
-
for (let i = 0; i < prevLength; i++) {
|
|
1340
|
-
if (prev[i] !== next[i])
|
|
1341
|
-
return false;
|
|
1342
|
-
}
|
|
1343
|
-
return true;
|
|
1344
|
-
}
|
|
1345
|
-
|
|
1346
|
-
function isVariant(definition) {
|
|
1347
|
-
return typeof definition === "object";
|
|
1348
|
-
}
|
|
1349
|
-
|
|
1350
|
-
function resolveVariant(definition, variants) {
|
|
1351
|
-
if (isVariant(definition)) {
|
|
1352
|
-
return definition;
|
|
1353
|
-
}
|
|
1354
|
-
else if (definition && variants) {
|
|
1355
|
-
return variants[definition];
|
|
1356
|
-
}
|
|
1357
|
-
}
|
|
1358
|
-
|
|
1359
|
-
let scheduled = undefined;
|
|
1360
|
-
function processScheduledAnimations() {
|
|
1361
|
-
if (!scheduled)
|
|
1362
|
-
return;
|
|
1363
|
-
const generators = scheduled.sort(compareByDepth).map(fireAnimateUpdates);
|
|
1364
|
-
generators.forEach(fireNext);
|
|
1365
|
-
generators.forEach(fireNext);
|
|
1366
|
-
scheduled = undefined;
|
|
1367
|
-
}
|
|
1368
|
-
function scheduleAnimation(state) {
|
|
1369
|
-
if (!scheduled) {
|
|
1370
|
-
scheduled = [state];
|
|
1371
|
-
requestAnimationFrame(processScheduledAnimations);
|
|
1372
|
-
}
|
|
1373
|
-
else {
|
|
1374
|
-
addUniqueItem(scheduled, state);
|
|
1375
|
-
}
|
|
1376
|
-
}
|
|
1377
|
-
function unscheduleAnimation(state) {
|
|
1378
|
-
scheduled && removeItem(scheduled, state);
|
|
1379
|
-
}
|
|
1380
|
-
const compareByDepth = (a, b) => a.getDepth() - b.getDepth();
|
|
1381
|
-
const fireAnimateUpdates = (state) => state.animateUpdates();
|
|
1382
|
-
const fireNext = (iterator) => iterator.next();
|
|
1383
|
-
|
|
1384
|
-
const motionEvent = (name, target) => new CustomEvent(name, { detail: { target } });
|
|
1385
|
-
function dispatchPointerEvent(element, name, event) {
|
|
1386
|
-
element.dispatchEvent(new CustomEvent(name, { detail: { originalEvent: event } }));
|
|
1387
|
-
}
|
|
1388
|
-
function dispatchViewEvent(element, name, entry) {
|
|
1389
|
-
element.dispatchEvent(new CustomEvent(name, { detail: { originalEntry: entry } }));
|
|
1390
|
-
}
|
|
1391
|
-
|
|
1392
|
-
/**
|
|
1393
|
-
* TODO: Support viewport options
|
|
1394
|
-
*/
|
|
1395
|
-
const inView = {
|
|
1396
|
-
isActive: (options) => Boolean(options.inView),
|
|
1397
|
-
subscribe: (element, { enable, disable }) => {
|
|
1398
|
-
let isVisible = false;
|
|
1399
|
-
if (typeof IntersectionObserver !== "undefined") {
|
|
1400
|
-
const observer = new IntersectionObserver(([entry]) => {
|
|
1401
|
-
if (!isVisible && entry.isIntersecting) {
|
|
1402
|
-
enable();
|
|
1403
|
-
dispatchViewEvent(element, "viewenter", entry);
|
|
1404
|
-
}
|
|
1405
|
-
else if (isVisible && !entry.isIntersecting) {
|
|
1406
|
-
disable();
|
|
1407
|
-
dispatchViewEvent(element, "viewleave", entry);
|
|
1408
|
-
}
|
|
1409
|
-
isVisible = entry.isIntersecting;
|
|
1410
|
-
});
|
|
1411
|
-
observer.observe(element);
|
|
1412
|
-
return () => {
|
|
1413
|
-
observer.unobserve(element);
|
|
1414
|
-
observer.disconnect();
|
|
1415
|
-
};
|
|
1416
|
-
}
|
|
1417
|
-
else {
|
|
1418
|
-
enable();
|
|
1419
|
-
return () => { };
|
|
1420
|
-
}
|
|
1421
|
-
},
|
|
1422
|
-
};
|
|
1423
|
-
|
|
1424
|
-
const mouseEvent = (element, name, action) => (event) => {
|
|
1425
|
-
if (event.pointerType && event.pointerType !== "mouse")
|
|
1426
|
-
return;
|
|
1427
|
-
action();
|
|
1428
|
-
dispatchPointerEvent(element, name, event);
|
|
1429
|
-
};
|
|
1430
|
-
const hover = {
|
|
1431
|
-
isActive: (options) => Boolean(options.hover),
|
|
1432
|
-
subscribe: (element, { enable, disable }) => {
|
|
1433
|
-
const onEnter = mouseEvent(element, "hoverstart", enable);
|
|
1434
|
-
const onLeave = mouseEvent(element, "hoverend", disable);
|
|
1435
|
-
element.addEventListener("pointerenter", onEnter);
|
|
1436
|
-
element.addEventListener("pointerleave", onLeave);
|
|
1437
|
-
return () => {
|
|
1438
|
-
element.removeEventListener("pointerenter", onEnter);
|
|
1439
|
-
element.removeEventListener("pointerleave", onLeave);
|
|
1440
|
-
};
|
|
1441
|
-
},
|
|
1442
|
-
};
|
|
1443
|
-
|
|
1444
|
-
const press = {
|
|
1445
|
-
isActive: (options) => Boolean(options.press),
|
|
1446
|
-
subscribe: (element, { enable, disable }) => {
|
|
1447
|
-
const onPointerUp = (event) => {
|
|
1448
|
-
disable();
|
|
1449
|
-
dispatchPointerEvent(element, "pressend", event);
|
|
1450
|
-
window.removeEventListener("pointerup", onPointerUp);
|
|
1451
|
-
};
|
|
1452
|
-
const onPointerDown = (event) => {
|
|
1453
|
-
enable();
|
|
1454
|
-
dispatchPointerEvent(element, "pressstart", event);
|
|
1455
|
-
window.addEventListener("pointerup", onPointerUp);
|
|
1456
|
-
};
|
|
1457
|
-
element.addEventListener("pointerdown", onPointerDown);
|
|
1458
|
-
return () => {
|
|
1459
|
-
element.removeEventListener("pointerdown", onPointerDown);
|
|
1460
|
-
window.removeEventListener("pointerup", onPointerUp);
|
|
1461
|
-
};
|
|
1462
|
-
},
|
|
1463
|
-
};
|
|
1464
|
-
|
|
1465
|
-
const gestures = { inView, hover, press };
|
|
1466
|
-
/**
|
|
1467
|
-
* A list of state types, in priority order. If a value is defined in
|
|
1468
|
-
* a righter-most type, it will override any definition in a lefter-most.
|
|
1469
|
-
*/
|
|
1470
|
-
const stateTypes = ["initial", "animate", ...Object.keys(gestures), "exit"];
|
|
1471
|
-
/**
|
|
1472
|
-
* A global store of all generated motion states. This can be used to lookup
|
|
1473
|
-
* a motion state for a given Element.
|
|
1474
|
-
*/
|
|
1475
|
-
const mountedStates = new WeakMap();
|
|
1476
|
-
function createMotionState(options = {}, parent) {
|
|
1477
|
-
/**
|
|
1478
|
-
* The element represented by the motion state. This is an empty reference
|
|
1479
|
-
* when we create the state to support SSR and allow for later mounting
|
|
1480
|
-
* in view libraries.
|
|
1481
|
-
*
|
|
1482
|
-
* @ts-ignore
|
|
1483
|
-
*/
|
|
1484
|
-
let element;
|
|
1485
|
-
/**
|
|
1486
|
-
* Calculate a depth that we can use to order motion states by tree depth.
|
|
1487
|
-
*/
|
|
1488
|
-
let depth = parent ? parent.getDepth() + 1 : 0;
|
|
1489
|
-
/**
|
|
1490
|
-
* Track which states are currently active.
|
|
1491
|
-
*/
|
|
1492
|
-
const activeStates = { initial: true, animate: true };
|
|
1493
|
-
/**
|
|
1494
|
-
* A map of functions that, when called, will remove event listeners for
|
|
1495
|
-
* a given gesture.
|
|
1496
|
-
*/
|
|
1497
|
-
const gestureSubscriptions = {};
|
|
1498
|
-
/**
|
|
1499
|
-
* Initialise a context to share through motion states. This
|
|
1500
|
-
* will be populated by variant names (if any).
|
|
1501
|
-
*/
|
|
1502
|
-
const context = {};
|
|
1503
|
-
for (const name of stateTypes) {
|
|
1504
|
-
context[name] =
|
|
1505
|
-
typeof options[name] === "string"
|
|
1506
|
-
? options[name]
|
|
1507
|
-
: parent === null || parent === void 0 ? void 0 : parent.getContext()[name];
|
|
1508
|
-
}
|
|
1509
|
-
/**
|
|
1510
|
-
* If initial is set to false we use the animate prop as the initial
|
|
1511
|
-
* animation state.
|
|
1512
|
-
*/
|
|
1513
|
-
const initialVariantSource = options.initial === false ? "animate" : "initial";
|
|
1514
|
-
/**
|
|
1515
|
-
* Destructure an initial target out from the resolved initial variant.
|
|
1516
|
-
*/
|
|
1517
|
-
let _a = resolveVariant(options[initialVariantSource] || context[initialVariantSource], options.variants) || {}, target = __rest(_a, ["transition"]);
|
|
1518
|
-
/**
|
|
1519
|
-
* The base target is a cached map of values that we'll use to animate
|
|
1520
|
-
* back to if a value is removed from all active state types. This
|
|
1521
|
-
* is usually the initial value as read from the DOM, for instance if
|
|
1522
|
-
* it hasn't been defined in initial.
|
|
1523
|
-
*/
|
|
1524
|
-
const baseTarget = Object.assign({}, target);
|
|
1525
|
-
/**
|
|
1526
|
-
* A generator that will be processed by the global animation scheduler.
|
|
1527
|
-
* This yeilds when it switches from reading the DOM to writing to it
|
|
1528
|
-
* to prevent layout thrashing.
|
|
1529
|
-
*/
|
|
1530
|
-
function* animateUpdates() {
|
|
1531
|
-
var _a, _b;
|
|
1532
|
-
const prevTarget = target;
|
|
1533
|
-
target = {};
|
|
1534
|
-
const resolvedVariants = {};
|
|
1535
|
-
const enteringInto = {};
|
|
1536
|
-
const animationOptions = {};
|
|
1537
|
-
for (const name of stateTypes) {
|
|
1538
|
-
if (!activeStates[name])
|
|
1539
|
-
continue;
|
|
1540
|
-
const variant = resolveVariant(options[name]);
|
|
1541
|
-
if (!variant)
|
|
1542
|
-
continue;
|
|
1543
|
-
resolvedVariants[name] = variant;
|
|
1544
|
-
for (const key in variant) {
|
|
1545
|
-
if (key === "transition")
|
|
1546
|
-
continue;
|
|
1547
|
-
target[key] = variant[key];
|
|
1548
|
-
animationOptions[key] = getOptions((_b = (_a = variant.transition) !== null && _a !== void 0 ? _a : options.transition) !== null && _b !== void 0 ? _b : {}, key);
|
|
1549
|
-
/**
|
|
1550
|
-
* Mark which state type this value is animating into.
|
|
1551
|
-
*/
|
|
1552
|
-
enteringInto[key] = name;
|
|
1553
|
-
}
|
|
1554
|
-
}
|
|
1555
|
-
const allTargetKeys = new Set([
|
|
1556
|
-
...Object.keys(target),
|
|
1557
|
-
...Object.keys(prevTarget),
|
|
1558
|
-
]);
|
|
1559
|
-
const animationFactories = [];
|
|
1560
|
-
allTargetKeys.forEach((key) => {
|
|
1561
|
-
var _a;
|
|
1562
|
-
if (target[key] === undefined) {
|
|
1563
|
-
target[key] = baseTarget[key];
|
|
1564
|
-
}
|
|
1565
|
-
if (hasChanged(prevTarget[key], target[key])) {
|
|
1566
|
-
(_a = baseTarget[key]) !== null && _a !== void 0 ? _a : (baseTarget[key] = style.get(element, key));
|
|
1567
|
-
animationFactories.push(animateStyle(element, key, target[key], animationOptions[key]));
|
|
1568
|
-
}
|
|
1569
|
-
});
|
|
1570
|
-
// Wait for all animation states to read from the DOM
|
|
1571
|
-
yield;
|
|
1572
|
-
const animations = animationFactories
|
|
1573
|
-
.map((factory) => factory())
|
|
1574
|
-
.filter(Boolean);
|
|
1575
|
-
if (!animations.length)
|
|
1576
|
-
return;
|
|
1577
|
-
const animationTarget = target;
|
|
1578
|
-
element.dispatchEvent(motionEvent("motionstart", animationTarget));
|
|
1579
|
-
Promise.all(animations.map((animation) => animation.finished))
|
|
1580
|
-
.then(() => {
|
|
1581
|
-
element.dispatchEvent(motionEvent("motioncomplete", animationTarget));
|
|
1582
|
-
})
|
|
1583
|
-
.catch(noop);
|
|
1584
|
-
}
|
|
1585
|
-
const setGesture = (name, isActive) => () => {
|
|
1586
|
-
activeStates[name] = isActive;
|
|
1587
|
-
scheduleAnimation(state);
|
|
1588
|
-
};
|
|
1589
|
-
const updateGestureSubscriptions = () => {
|
|
1590
|
-
for (const name in gestures) {
|
|
1591
|
-
const isGestureActive = gestures[name].isActive(options);
|
|
1592
|
-
const remove = gestureSubscriptions[name];
|
|
1593
|
-
if (isGestureActive && !remove) {
|
|
1594
|
-
gestureSubscriptions[name] = gestures[name].subscribe(element, {
|
|
1595
|
-
enable: setGesture(name, true),
|
|
1596
|
-
disable: setGesture(name, false),
|
|
1597
|
-
});
|
|
1598
|
-
}
|
|
1599
|
-
else if (!isGestureActive && remove) {
|
|
1600
|
-
remove();
|
|
1601
|
-
delete gestureSubscriptions[name];
|
|
1602
|
-
}
|
|
1603
|
-
}
|
|
1604
|
-
};
|
|
1605
|
-
const state = {
|
|
1606
|
-
update: (newOptions) => {
|
|
1607
|
-
if (!element)
|
|
1608
|
-
return;
|
|
1609
|
-
options = newOptions;
|
|
1610
|
-
updateGestureSubscriptions();
|
|
1611
|
-
scheduleAnimation(state);
|
|
1612
|
-
},
|
|
1613
|
-
setActive: (name, isActive) => {
|
|
1614
|
-
if (!element)
|
|
1615
|
-
return;
|
|
1616
|
-
activeStates[name] = isActive;
|
|
1617
|
-
scheduleAnimation(state);
|
|
1618
|
-
},
|
|
1619
|
-
animateUpdates,
|
|
1620
|
-
getDepth: () => depth,
|
|
1621
|
-
getTarget: () => target,
|
|
1622
|
-
getOptions: () => options,
|
|
1623
|
-
getContext: () => context,
|
|
1624
|
-
mount: (newElement) => {
|
|
1625
|
-
invariant(Boolean(newElement), "Animation state must be mounted with valid Element");
|
|
1626
|
-
element = newElement;
|
|
1627
|
-
mountedStates.set(element, state);
|
|
1628
|
-
updateGestureSubscriptions();
|
|
1629
|
-
return () => {
|
|
1630
|
-
mountedStates.delete(element);
|
|
1631
|
-
unscheduleAnimation(state);
|
|
1632
|
-
for (const key in gestureSubscriptions) {
|
|
1633
|
-
gestureSubscriptions[key]();
|
|
1634
|
-
}
|
|
1635
|
-
};
|
|
1306
|
+
function animateProgress(target, options) {
|
|
1307
|
+
return wrapAnimationWithControls([
|
|
1308
|
+
() => {
|
|
1309
|
+
const animation = new Animation(target, [0, 1], options);
|
|
1310
|
+
animation.finished.catch(() => { });
|
|
1311
|
+
return animation;
|
|
1636
1312
|
},
|
|
1637
|
-
|
|
1638
|
-
};
|
|
1639
|
-
return state;
|
|
1313
|
+
], options === null || options === void 0 ? void 0 : options.duration);
|
|
1640
1314
|
}
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
const transformKeys = [];
|
|
1645
|
-
for (let key in keyframes) {
|
|
1646
|
-
const value = keyframes[key];
|
|
1647
|
-
if (isTransform(key)) {
|
|
1648
|
-
if (transformAlias[key])
|
|
1649
|
-
key = transformAlias[key];
|
|
1650
|
-
transformKeys.push(key);
|
|
1651
|
-
key = asTransformCssVar(key);
|
|
1652
|
-
}
|
|
1653
|
-
let initialKeyframe = Array.isArray(value) ? value[0] : value;
|
|
1654
|
-
/**
|
|
1655
|
-
* If this is a number and we have a default value type, convert the number
|
|
1656
|
-
* to this type.
|
|
1657
|
-
*/
|
|
1658
|
-
const definition = transformDefinitions.get(key);
|
|
1659
|
-
if (definition) {
|
|
1660
|
-
initialKeyframe = isNumber(value)
|
|
1661
|
-
? definition.toDefaultUnit(value)
|
|
1662
|
-
: value;
|
|
1663
|
-
}
|
|
1664
|
-
initialKeyframes[key] = initialKeyframe;
|
|
1665
|
-
}
|
|
1666
|
-
if (transformKeys.length) {
|
|
1667
|
-
initialKeyframes.transform = buildTransformTemplate(transformKeys);
|
|
1668
|
-
}
|
|
1669
|
-
return initialKeyframes;
|
|
1670
|
-
}
|
|
1671
|
-
|
|
1672
|
-
const camelLetterToPipeLetter = (letter) => `-${letter.toLowerCase()}`;
|
|
1673
|
-
const camelToPipeCase = (str) => str.replace(/[A-Z]/g, camelLetterToPipeLetter);
|
|
1674
|
-
function createStyleString(target = {}) {
|
|
1675
|
-
const styles = createStyles(target);
|
|
1676
|
-
let style = "";
|
|
1677
|
-
for (const key in styles) {
|
|
1678
|
-
style += key.startsWith("--") ? key : camelToPipeCase(key);
|
|
1679
|
-
style += `: ${styles[key]}; `;
|
|
1680
|
-
}
|
|
1681
|
-
return style;
|
|
1315
|
+
function animate(target, keyframesOrOptions, options) {
|
|
1316
|
+
const animationFunction = typeof target === "function" ? animateProgress : animate$1;
|
|
1317
|
+
return animationFunction(target, keyframesOrOptions, options);
|
|
1682
1318
|
}
|
|
1683
1319
|
|
|
1684
1320
|
exports.animate = animate;
|
|
1685
|
-
exports.animateStyle = animateStyle;
|
|
1686
|
-
exports.createMotionState = createMotionState;
|
|
1687
|
-
exports.createStyleString = createStyleString;
|
|
1688
|
-
exports.createStyles = createStyles;
|
|
1689
|
-
exports.getAnimationData = getAnimationData;
|
|
1690
|
-
exports.getStyleName = getStyleName;
|
|
1691
1321
|
exports.glide = glide;
|
|
1692
|
-
exports.mountedStates = mountedStates;
|
|
1693
1322
|
exports.spring = spring;
|
|
1694
1323
|
exports.stagger = stagger;
|
|
1695
1324
|
exports.style = style;
|