motion 10.11.1 → 10.13.0
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 +26 -0
- package/dist/animate.cjs.js +6 -5
- package/dist/animate.es.js +7 -6
- package/dist/main.cjs.js +7 -25
- package/dist/main.es.js +2 -2
- package/dist/motion.min.js +1 -1
- package/dist/motion.umd.js +948 -108
- package/dist/size-index.js +1 -1
- package/dist/vue.cjs.js +0 -0
- package/dist/vue.es.js +0 -0
- package/lib/animate.js +7 -6
- package/lib/animate.js.map +1 -1
- package/lib/index.js +2 -2
- package/lib/index.js.map +1 -1
- package/lib/react.js +0 -0
- package/lib/react.js.map +0 -0
- package/lib/vue.js +0 -0
- package/lib/vue.js.map +0 -0
- package/package.json +8 -8
- package/types/animate.d.ts +2 -2
- package/types/animate.d.ts.map +1 -1
- package/types/index.d.ts +2 -3
- package/types/index.d.ts.map +1 -1
- package/types/react.d.ts +0 -0
- package/types/react.d.ts.map +0 -0
- package/types/vue.d.ts +0 -0
- package/types/vue.d.ts.map +0 -0
- package/dist/react.cjs.js +0 -14
- package/dist/react.es.js +0 -1
- package/react/package.json +0 -6
package/dist/motion.umd.js
CHANGED
|
@@ -56,12 +56,20 @@
|
|
|
56
56
|
};
|
|
57
57
|
|
|
58
58
|
const isNumber = (value) => typeof value === "number";
|
|
59
|
-
|
|
60
|
-
const isEasingGenerator = (easing) => typeof easing === "object" &&
|
|
61
|
-
Boolean(easing.createAnimation);
|
|
62
|
-
const isCubicBezier = (easing) => Array.isArray(easing) && isNumber(easing[0]);
|
|
59
|
+
|
|
63
60
|
const isEasingList = (easing) => Array.isArray(easing) && !isNumber(easing[0]);
|
|
64
61
|
|
|
62
|
+
const wrap = (min, max, v) => {
|
|
63
|
+
const rangeSize = max - min;
|
|
64
|
+
return ((((v - min) % rangeSize) + rangeSize) % rangeSize) + min;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
function getEasingForSegment(easing, i) {
|
|
68
|
+
return isEasingList(easing)
|
|
69
|
+
? easing[wrap(0, easing.length, i)]
|
|
70
|
+
: easing;
|
|
71
|
+
}
|
|
72
|
+
|
|
65
73
|
const mix = (min, max, progress) => -progress * min + progress * max + min;
|
|
66
74
|
|
|
67
75
|
const noop = () => { };
|
|
@@ -76,12 +84,44 @@
|
|
|
76
84
|
offset.push(mix(min, 1, offsetProgress));
|
|
77
85
|
}
|
|
78
86
|
}
|
|
79
|
-
function defaultOffset(length) {
|
|
87
|
+
function defaultOffset$1(length) {
|
|
80
88
|
const offset = [0];
|
|
81
89
|
fillOffset(offset, length - 1);
|
|
82
90
|
return offset;
|
|
83
91
|
}
|
|
84
92
|
|
|
93
|
+
function interpolate(output, input = defaultOffset$1(output.length), easing = noopReturn) {
|
|
94
|
+
const length = output.length;
|
|
95
|
+
/**
|
|
96
|
+
* If the input length is lower than the output we
|
|
97
|
+
* fill the input to match. This currently assumes the input
|
|
98
|
+
* is an animation progress value so is a good candidate for
|
|
99
|
+
* moving outside the function.
|
|
100
|
+
*/
|
|
101
|
+
const remainder = length - input.length;
|
|
102
|
+
remainder > 0 && fillOffset(input, remainder);
|
|
103
|
+
return (t) => {
|
|
104
|
+
let i = 0;
|
|
105
|
+
for (; i < length - 2; i++) {
|
|
106
|
+
if (t < input[i + 1])
|
|
107
|
+
break;
|
|
108
|
+
}
|
|
109
|
+
let progressInRange = clamp(0, 1, progress(input[i], input[i + 1], t));
|
|
110
|
+
const segmentEasing = getEasingForSegment(easing, i);
|
|
111
|
+
progressInRange = segmentEasing(progressInRange);
|
|
112
|
+
return mix(output[i], output[i + 1], progressInRange);
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const isCubicBezier = (easing) => Array.isArray(easing) && isNumber(easing[0]);
|
|
117
|
+
|
|
118
|
+
const isEasingGenerator = (easing) => typeof easing === "object" &&
|
|
119
|
+
Boolean(easing.createAnimation);
|
|
120
|
+
|
|
121
|
+
const isFunction = (value) => typeof value === "function";
|
|
122
|
+
|
|
123
|
+
const isString = (value) => typeof value === "string";
|
|
124
|
+
|
|
85
125
|
const time = {
|
|
86
126
|
ms: (seconds) => seconds * 1000,
|
|
87
127
|
s: (milliseconds) => milliseconds / 1000,
|
|
@@ -97,11 +137,6 @@
|
|
|
97
137
|
return frameDuration ? velocity * (1000 / frameDuration) : 0;
|
|
98
138
|
}
|
|
99
139
|
|
|
100
|
-
const wrap = (min, max, v) => {
|
|
101
|
-
const rangeSize = max - min;
|
|
102
|
-
return ((((v - min) % rangeSize) + rangeSize) % rangeSize) + min;
|
|
103
|
-
};
|
|
104
|
-
|
|
105
140
|
/**
|
|
106
141
|
* A list of all transformable axes. We'll use this list to generated a version
|
|
107
142
|
* of each axes for each transform.
|
|
@@ -264,7 +299,7 @@
|
|
|
264
299
|
const functionArgsRegex = /\((.*?)\)/;
|
|
265
300
|
function getEasingFunction(definition) {
|
|
266
301
|
// If already an easing function, return
|
|
267
|
-
if (
|
|
302
|
+
if (isFunction(definition))
|
|
268
303
|
return definition;
|
|
269
304
|
// If an easing curve definition, return bezier function
|
|
270
305
|
if (Array.isArray(definition))
|
|
@@ -282,67 +317,46 @@
|
|
|
282
317
|
}
|
|
283
318
|
return noopReturn;
|
|
284
319
|
}
|
|
285
|
-
function getEasingForSegment(easing, i) {
|
|
286
|
-
return isEasingList(easing)
|
|
287
|
-
? easing[wrap(0, easing.length, i)]
|
|
288
|
-
: easing;
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
const clampProgress = (p) => Math.min(1, Math.max(p, 0));
|
|
292
|
-
function interpolate(output, input = defaultOffset(output.length), easing = noopReturn) {
|
|
293
|
-
const length = output.length;
|
|
294
|
-
/**
|
|
295
|
-
* If the input length is lower than the output we
|
|
296
|
-
* fill the input to match. This currently assumes the input
|
|
297
|
-
* is an animation progress value so is a good candidate for
|
|
298
|
-
* moving outside the function.
|
|
299
|
-
*/
|
|
300
|
-
const remainder = length - input.length;
|
|
301
|
-
remainder > 0 && fillOffset(input, remainder);
|
|
302
|
-
return (t) => {
|
|
303
|
-
let i = 0;
|
|
304
|
-
for (; i < length - 2; i++) {
|
|
305
|
-
if (t < input[i + 1])
|
|
306
|
-
break;
|
|
307
|
-
}
|
|
308
|
-
let progressInRange = clampProgress(progress(input[i], input[i + 1], t));
|
|
309
|
-
const segmentEasing = getEasingForSegment(easing, i);
|
|
310
|
-
progressInRange = segmentEasing(progressInRange);
|
|
311
|
-
return mix(output[i], output[i + 1], progressInRange);
|
|
312
|
-
};
|
|
313
|
-
}
|
|
314
320
|
|
|
315
321
|
class Animation {
|
|
316
|
-
constructor(output, keyframes = [0, 1], { easing
|
|
322
|
+
constructor(output, keyframes = [0, 1], { easing, duration: initialDuration = defaults$1.duration, delay = defaults$1.delay, endDelay = defaults$1.endDelay, repeat = defaults$1.repeat, offset, direction = "normal", } = {}) {
|
|
317
323
|
this.startTime = null;
|
|
318
324
|
this.rate = 1;
|
|
319
325
|
this.t = 0;
|
|
320
326
|
this.cancelTimestamp = null;
|
|
327
|
+
this.easing = noopReturn;
|
|
328
|
+
this.duration = 0;
|
|
329
|
+
this.totalDuration = 0;
|
|
330
|
+
this.repeat = 0;
|
|
321
331
|
this.playState = "idle";
|
|
322
332
|
this.finished = new Promise((resolve, reject) => {
|
|
323
333
|
this.resolve = resolve;
|
|
324
334
|
this.reject = reject;
|
|
325
335
|
});
|
|
336
|
+
easing = easing || defaults$1.easing;
|
|
326
337
|
if (isEasingGenerator(easing)) {
|
|
327
338
|
const custom = easing.createAnimation(keyframes, () => "0", true);
|
|
328
339
|
easing = custom.easing;
|
|
329
340
|
if (custom.keyframes !== undefined)
|
|
330
341
|
keyframes = custom.keyframes;
|
|
331
342
|
if (custom.duration !== undefined)
|
|
332
|
-
|
|
343
|
+
initialDuration = custom.duration;
|
|
333
344
|
}
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
const totalDuration = duration * (repeat + 1);
|
|
345
|
+
this.repeat = repeat;
|
|
346
|
+
this.easing = isEasingList(easing) ? noopReturn : getEasingFunction(easing);
|
|
347
|
+
this.updateDuration(initialDuration);
|
|
338
348
|
const interpolate$1 = interpolate(keyframes, offset, isEasingList(easing) ? easing.map(getEasingFunction) : noopReturn);
|
|
339
349
|
this.tick = (timestamp) => {
|
|
340
350
|
var _a;
|
|
341
351
|
// TODO: Temporary fix for OptionsResolver typing
|
|
342
352
|
delay = delay;
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
353
|
+
let t = 0;
|
|
354
|
+
if (this.pauseTime !== undefined) {
|
|
355
|
+
t = this.pauseTime;
|
|
356
|
+
}
|
|
357
|
+
else {
|
|
358
|
+
t = (timestamp - this.startTime) * this.rate;
|
|
359
|
+
}
|
|
346
360
|
this.t = t;
|
|
347
361
|
// Convert to seconds
|
|
348
362
|
t /= 1000;
|
|
@@ -352,14 +366,15 @@
|
|
|
352
366
|
* If this animation has finished, set the current time
|
|
353
367
|
* to the total duration.
|
|
354
368
|
*/
|
|
355
|
-
if (this.playState === "finished")
|
|
356
|
-
t = totalDuration;
|
|
369
|
+
if (this.playState === "finished" && this.pauseTime === undefined) {
|
|
370
|
+
t = this.totalDuration;
|
|
371
|
+
}
|
|
357
372
|
/**
|
|
358
373
|
* Get the current progress (0-1) of the animation. If t is >
|
|
359
374
|
* than duration we'll get values like 2.5 (midway through the
|
|
360
375
|
* third iteration)
|
|
361
376
|
*/
|
|
362
|
-
const progress = t / duration;
|
|
377
|
+
const progress = t / this.duration;
|
|
363
378
|
// TODO progress += iterationStart
|
|
364
379
|
/**
|
|
365
380
|
* Get the current iteration (0 indexed). For instance the floor of
|
|
@@ -388,10 +403,11 @@
|
|
|
388
403
|
(direction === "alternate-reverse" && !iterationIsOdd)) {
|
|
389
404
|
iterationProgress = 1 - iterationProgress;
|
|
390
405
|
}
|
|
391
|
-
const p = t >= totalDuration ? 1 : Math.min(iterationProgress, 1);
|
|
392
|
-
const latest = interpolate$1(
|
|
406
|
+
const p = t >= this.totalDuration ? 1 : Math.min(iterationProgress, 1);
|
|
407
|
+
const latest = interpolate$1(this.easing(p));
|
|
393
408
|
output(latest);
|
|
394
|
-
const isAnimationFinished = this.
|
|
409
|
+
const isAnimationFinished = this.pauseTime === undefined &&
|
|
410
|
+
(this.playState === "finished" || t >= this.totalDuration + endDelay);
|
|
395
411
|
if (isAnimationFinished) {
|
|
396
412
|
this.playState = "finished";
|
|
397
413
|
(_a = this.resolve) === null || _a === void 0 ? void 0 : _a.call(this, latest);
|
|
@@ -403,22 +419,21 @@
|
|
|
403
419
|
this.play();
|
|
404
420
|
}
|
|
405
421
|
play() {
|
|
406
|
-
var _a;
|
|
407
422
|
const now = performance.now();
|
|
408
423
|
this.playState = "running";
|
|
409
|
-
if (this.pauseTime) {
|
|
410
|
-
this.startTime = now -
|
|
424
|
+
if (this.pauseTime !== undefined) {
|
|
425
|
+
this.startTime = now - this.pauseTime;
|
|
411
426
|
}
|
|
412
427
|
else if (!this.startTime) {
|
|
413
428
|
this.startTime = now;
|
|
414
429
|
}
|
|
415
430
|
this.cancelTimestamp = this.startTime;
|
|
416
431
|
this.pauseTime = undefined;
|
|
417
|
-
requestAnimationFrame(this.tick);
|
|
432
|
+
this.frameRequestId = requestAnimationFrame(this.tick);
|
|
418
433
|
}
|
|
419
434
|
pause() {
|
|
420
435
|
this.playState = "paused";
|
|
421
|
-
this.pauseTime =
|
|
436
|
+
this.pauseTime = this.t;
|
|
422
437
|
}
|
|
423
438
|
finish() {
|
|
424
439
|
this.playState = "finished";
|
|
@@ -440,11 +455,15 @@
|
|
|
440
455
|
this.rate *= -1;
|
|
441
456
|
}
|
|
442
457
|
commitStyles() { }
|
|
458
|
+
updateDuration(duration) {
|
|
459
|
+
this.duration = duration;
|
|
460
|
+
this.totalDuration = duration * (this.repeat + 1);
|
|
461
|
+
}
|
|
443
462
|
get currentTime() {
|
|
444
463
|
return this.t;
|
|
445
464
|
}
|
|
446
465
|
set currentTime(t) {
|
|
447
|
-
if (this.pauseTime || this.rate === 0) {
|
|
466
|
+
if (this.pauseTime !== undefined || this.rate === 0) {
|
|
448
467
|
this.pauseTime = t;
|
|
449
468
|
}
|
|
450
469
|
else {
|
|
@@ -459,10 +478,7 @@
|
|
|
459
478
|
}
|
|
460
479
|
}
|
|
461
480
|
|
|
462
|
-
const
|
|
463
|
-
const cubicBezierAsString = ([a, b, c, d]) => `cubic-bezier(${a}, ${b}, ${c}, ${d})`;
|
|
464
|
-
|
|
465
|
-
const testAnimation = (keyframes) => document.createElement("div").animate(keyframes, { duration: 0.001 });
|
|
481
|
+
const testAnimation = (keyframes, options) => document.createElement("div").animate(keyframes, options);
|
|
466
482
|
const featureTests = {
|
|
467
483
|
cssRegisterProperty: () => typeof CSS !== "undefined" &&
|
|
468
484
|
Object.hasOwnProperty.call(CSS, "registerProperty"),
|
|
@@ -476,7 +492,16 @@
|
|
|
476
492
|
}
|
|
477
493
|
return true;
|
|
478
494
|
},
|
|
479
|
-
finished: () => Boolean(testAnimation({ opacity: [0, 1] }).finished),
|
|
495
|
+
finished: () => Boolean(testAnimation({ opacity: [0, 1] }, { duration: 0.001 }).finished),
|
|
496
|
+
linearEasing: () => {
|
|
497
|
+
try {
|
|
498
|
+
testAnimation({ opacity: 0 }, { easing: "linear(0, 1)" });
|
|
499
|
+
}
|
|
500
|
+
catch (e) {
|
|
501
|
+
return false;
|
|
502
|
+
}
|
|
503
|
+
return true;
|
|
504
|
+
},
|
|
480
505
|
};
|
|
481
506
|
const results = {};
|
|
482
507
|
const supports = {};
|
|
@@ -488,6 +513,28 @@
|
|
|
488
513
|
};
|
|
489
514
|
}
|
|
490
515
|
|
|
516
|
+
// Create a linear easing point for every x second
|
|
517
|
+
const resolution = 0.015;
|
|
518
|
+
const generateLinearEasingPoints = (easing, duration) => {
|
|
519
|
+
let points = "";
|
|
520
|
+
const numPoints = Math.round(duration / resolution);
|
|
521
|
+
for (let i = 0; i < numPoints; i++) {
|
|
522
|
+
points += easing(progress(0, numPoints - 1, i)) + ", ";
|
|
523
|
+
}
|
|
524
|
+
return points.substring(0, points.length - 2);
|
|
525
|
+
};
|
|
526
|
+
const convertEasing = (easing, duration) => {
|
|
527
|
+
if (isFunction(easing)) {
|
|
528
|
+
return supports.linearEasing()
|
|
529
|
+
? `linear(${generateLinearEasingPoints(easing, duration)})`
|
|
530
|
+
: defaults$1.easing;
|
|
531
|
+
}
|
|
532
|
+
else {
|
|
533
|
+
return isCubicBezier(easing) ? cubicBezierAsString(easing) : easing;
|
|
534
|
+
}
|
|
535
|
+
};
|
|
536
|
+
const cubicBezierAsString = ([a, b, c, d]) => `cubic-bezier(${a}, ${b}, ${c}, ${d})`;
|
|
537
|
+
|
|
491
538
|
function hydrateKeyframes(keyframes, readInitialValue) {
|
|
492
539
|
for (let i = 0; i < keyframes.length; i++) {
|
|
493
540
|
if (keyframes[i] === null) {
|
|
@@ -553,8 +600,8 @@
|
|
|
553
600
|
let animation;
|
|
554
601
|
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;
|
|
555
602
|
const data = getAnimationData(element);
|
|
556
|
-
let canAnimateNatively = supports.waapi();
|
|
557
603
|
const valueIsTransform = isTransform(key);
|
|
604
|
+
let canAnimateNatively = supports.waapi();
|
|
558
605
|
/**
|
|
559
606
|
* If this is an individual transform, we need to map its
|
|
560
607
|
* key to a CSS variable and update the element's transform style
|
|
@@ -607,8 +654,16 @@
|
|
|
607
654
|
}
|
|
608
655
|
}
|
|
609
656
|
/**
|
|
610
|
-
* If we
|
|
611
|
-
*
|
|
657
|
+
* If we've been passed a custom easing function, and this browser
|
|
658
|
+
* does **not** support linear() easing, and the value is a transform
|
|
659
|
+
* (and thus a pure number) we can still support the custom easing
|
|
660
|
+
* by falling back to the animation polyfill.
|
|
661
|
+
*/
|
|
662
|
+
if (isFunction(easing) && !supports.linearEasing() && valueIsTransform) {
|
|
663
|
+
canAnimateNatively = false;
|
|
664
|
+
}
|
|
665
|
+
/**
|
|
666
|
+
* If we can animate this value with WAAPI, do so.
|
|
612
667
|
*/
|
|
613
668
|
if (canAnimateNatively) {
|
|
614
669
|
/**
|
|
@@ -630,7 +685,9 @@
|
|
|
630
685
|
delay: time.ms(delay),
|
|
631
686
|
duration: time.ms(duration),
|
|
632
687
|
endDelay: time.ms(endDelay),
|
|
633
|
-
easing: !isEasingList(easing)
|
|
688
|
+
easing: !isEasingList(easing)
|
|
689
|
+
? convertEasing(easing, duration)
|
|
690
|
+
: undefined,
|
|
634
691
|
direction,
|
|
635
692
|
iterations: repeat + 1,
|
|
636
693
|
fill: "both",
|
|
@@ -638,7 +695,9 @@
|
|
|
638
695
|
animation = element.animate({
|
|
639
696
|
[name]: keyframes,
|
|
640
697
|
offset,
|
|
641
|
-
easing: isEasingList(easing)
|
|
698
|
+
easing: isEasingList(easing)
|
|
699
|
+
? easing.map((thisEasing) => convertEasing(thisEasing, duration))
|
|
700
|
+
: undefined,
|
|
642
701
|
}, animationOptions);
|
|
643
702
|
/**
|
|
644
703
|
* Polyfill finished Promise in browsers that don't support it
|
|
@@ -744,10 +803,13 @@
|
|
|
744
803
|
}
|
|
745
804
|
|
|
746
805
|
const createAnimation = (factory) => factory();
|
|
747
|
-
const
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
806
|
+
const withControls = (animationFactory, options, duration = defaults$1.duration) => {
|
|
807
|
+
return new Proxy({
|
|
808
|
+
animations: animationFactory.map(createAnimation).filter(Boolean),
|
|
809
|
+
duration,
|
|
810
|
+
options,
|
|
811
|
+
}, controls);
|
|
812
|
+
};
|
|
751
813
|
/**
|
|
752
814
|
* TODO:
|
|
753
815
|
* Currently this returns the first animation, ideally it would return
|
|
@@ -761,8 +823,7 @@
|
|
|
761
823
|
case "duration":
|
|
762
824
|
return target.duration;
|
|
763
825
|
case "currentTime":
|
|
764
|
-
|
|
765
|
-
return time ? time / 1000 : 0;
|
|
826
|
+
return time.s((activeAnimation === null || activeAnimation === void 0 ? void 0 : activeAnimation[key]) || 0);
|
|
766
827
|
case "playbackRate":
|
|
767
828
|
case "playState":
|
|
768
829
|
return activeAnimation === null || activeAnimation === void 0 ? void 0 : activeAnimation[key];
|
|
@@ -772,7 +833,17 @@
|
|
|
772
833
|
}
|
|
773
834
|
return target.finished;
|
|
774
835
|
case "stop":
|
|
775
|
-
return () =>
|
|
836
|
+
return () => {
|
|
837
|
+
target.animations.forEach((animation) => stopAnimation(animation));
|
|
838
|
+
};
|
|
839
|
+
case "forEachNative":
|
|
840
|
+
/**
|
|
841
|
+
* This is for internal use only, fire a callback for each
|
|
842
|
+
* underlying animation.
|
|
843
|
+
*/
|
|
844
|
+
return (callback) => {
|
|
845
|
+
target.animations.forEach((animation) => callback(animation, target));
|
|
846
|
+
};
|
|
776
847
|
default:
|
|
777
848
|
return typeof (activeAnimation === null || activeAnimation === void 0 ? void 0 : activeAnimation[key]) === "undefined"
|
|
778
849
|
? undefined
|
|
@@ -818,9 +889,7 @@
|
|
|
818
889
|
}
|
|
819
890
|
}
|
|
820
891
|
function resolveOption(option, i, total) {
|
|
821
|
-
return
|
|
822
|
-
? option(i, total)
|
|
823
|
-
: option;
|
|
892
|
+
return isFunction(option) ? option(i, total) : option;
|
|
824
893
|
}
|
|
825
894
|
|
|
826
895
|
function animate$1(elements, keyframes, options = {}) {
|
|
@@ -839,7 +908,7 @@
|
|
|
839
908
|
animationFactories.push(animation);
|
|
840
909
|
}
|
|
841
910
|
}
|
|
842
|
-
return
|
|
911
|
+
return withControls(animationFactories, options,
|
|
843
912
|
/**
|
|
844
913
|
* TODO:
|
|
845
914
|
* If easing is set to spring or glide, duration will be dynamically
|
|
@@ -948,7 +1017,7 @@
|
|
|
948
1017
|
const animationFactories = animationDefinitions
|
|
949
1018
|
.map((definition) => animateStyle(...definition))
|
|
950
1019
|
.filter(Boolean);
|
|
951
|
-
return
|
|
1020
|
+
return withControls(animationFactories, options,
|
|
952
1021
|
// Get the duration from the first animation definition
|
|
953
1022
|
(_a = animationDefinitions[0]) === null || _a === void 0 ? void 0 : _a[3].duration);
|
|
954
1023
|
}
|
|
@@ -1025,7 +1094,7 @@
|
|
|
1025
1094
|
/**
|
|
1026
1095
|
*
|
|
1027
1096
|
*/
|
|
1028
|
-
let { offset = defaultOffset(valueKeyframes.length) } = valueOptions;
|
|
1097
|
+
let { offset = defaultOffset$1(valueKeyframes.length) } = valueOptions;
|
|
1029
1098
|
/**
|
|
1030
1099
|
* If there's only one offset of 0, fill in a second with length 1
|
|
1031
1100
|
*
|
|
@@ -1373,24 +1442,11 @@
|
|
|
1373
1442
|
|
|
1374
1443
|
const glide = createGeneratorEasing(glide$1);
|
|
1375
1444
|
|
|
1376
|
-
let supportsDocumentRoot;
|
|
1377
|
-
function getDefaultRoot() {
|
|
1378
|
-
if (supportsDocumentRoot === undefined) {
|
|
1379
|
-
try {
|
|
1380
|
-
new IntersectionObserver(noop, { root: document });
|
|
1381
|
-
supportsDocumentRoot = true;
|
|
1382
|
-
}
|
|
1383
|
-
catch (e) {
|
|
1384
|
-
supportsDocumentRoot = false;
|
|
1385
|
-
}
|
|
1386
|
-
}
|
|
1387
|
-
return supportsDocumentRoot ? document : undefined;
|
|
1388
|
-
}
|
|
1389
1445
|
const thresholds = {
|
|
1390
1446
|
any: 0,
|
|
1391
1447
|
all: 1,
|
|
1392
1448
|
};
|
|
1393
|
-
function inView(
|
|
1449
|
+
function inView$1(elementOrSelector, onStart, { root, margin: rootMargin, amount = "any" } = {}) {
|
|
1394
1450
|
/**
|
|
1395
1451
|
* If this browser doesn't support IntersectionObserver, return a dummy stop function.
|
|
1396
1452
|
* Default triggering of onStart is tricky - it could be used for starting/stopping
|
|
@@ -1400,7 +1456,7 @@
|
|
|
1400
1456
|
if (typeof IntersectionObserver === "undefined") {
|
|
1401
1457
|
return () => { };
|
|
1402
1458
|
}
|
|
1403
|
-
const
|
|
1459
|
+
const elements = resolveElements(elementOrSelector);
|
|
1404
1460
|
const activeIntersections = new WeakMap();
|
|
1405
1461
|
const onIntersectionChange = (entries) => {
|
|
1406
1462
|
entries.forEach((entry) => {
|
|
@@ -1413,7 +1469,7 @@
|
|
|
1413
1469
|
return;
|
|
1414
1470
|
if (entry.isIntersecting) {
|
|
1415
1471
|
const newOnEnd = onStart(entry);
|
|
1416
|
-
if (
|
|
1472
|
+
if (isFunction(newOnEnd)) {
|
|
1417
1473
|
activeIntersections.set(entry.target, newOnEnd);
|
|
1418
1474
|
}
|
|
1419
1475
|
else {
|
|
@@ -1427,36 +1483,820 @@
|
|
|
1427
1483
|
});
|
|
1428
1484
|
};
|
|
1429
1485
|
const observer = new IntersectionObserver(onIntersectionChange, {
|
|
1430
|
-
root
|
|
1486
|
+
root,
|
|
1431
1487
|
rootMargin,
|
|
1432
1488
|
threshold: typeof amount === "number" ? amount : thresholds[amount],
|
|
1433
1489
|
});
|
|
1434
|
-
|
|
1490
|
+
elements.forEach((element) => observer.observe(element));
|
|
1435
1491
|
return () => observer.disconnect();
|
|
1436
1492
|
}
|
|
1437
1493
|
|
|
1438
|
-
|
|
1439
|
-
|
|
1494
|
+
const resizeHandlers = new WeakMap();
|
|
1495
|
+
let observer;
|
|
1496
|
+
function getElementSize(target, borderBoxSize) {
|
|
1497
|
+
if (borderBoxSize) {
|
|
1498
|
+
const { inlineSize, blockSize } = borderBoxSize[0];
|
|
1499
|
+
return { width: inlineSize, height: blockSize };
|
|
1500
|
+
}
|
|
1501
|
+
else if (target instanceof SVGElement && "getBBox" in target) {
|
|
1502
|
+
return target.getBBox();
|
|
1503
|
+
}
|
|
1504
|
+
else {
|
|
1505
|
+
return {
|
|
1506
|
+
width: target.offsetWidth,
|
|
1507
|
+
height: target.offsetHeight,
|
|
1508
|
+
};
|
|
1509
|
+
}
|
|
1510
|
+
}
|
|
1511
|
+
function notifyTarget({ target, contentRect, borderBoxSize, }) {
|
|
1512
|
+
var _a;
|
|
1513
|
+
(_a = resizeHandlers.get(target)) === null || _a === void 0 ? void 0 : _a.forEach((handler) => {
|
|
1514
|
+
handler({
|
|
1515
|
+
target,
|
|
1516
|
+
contentSize: contentRect,
|
|
1517
|
+
get size() {
|
|
1518
|
+
return getElementSize(target, borderBoxSize);
|
|
1519
|
+
},
|
|
1520
|
+
});
|
|
1521
|
+
});
|
|
1522
|
+
}
|
|
1523
|
+
function notifyAll(entries) {
|
|
1524
|
+
entries.forEach(notifyTarget);
|
|
1525
|
+
}
|
|
1526
|
+
function createResizeObserver() {
|
|
1527
|
+
if (typeof ResizeObserver === "undefined")
|
|
1528
|
+
return;
|
|
1529
|
+
observer = new ResizeObserver(notifyAll);
|
|
1530
|
+
}
|
|
1531
|
+
function resizeElement(target, handler) {
|
|
1532
|
+
if (!observer)
|
|
1533
|
+
createResizeObserver();
|
|
1534
|
+
const elements = resolveElements(target);
|
|
1535
|
+
elements.forEach((element) => {
|
|
1536
|
+
let elementHandlers = resizeHandlers.get(element);
|
|
1537
|
+
if (!elementHandlers) {
|
|
1538
|
+
elementHandlers = new Set();
|
|
1539
|
+
resizeHandlers.set(element, elementHandlers);
|
|
1540
|
+
}
|
|
1541
|
+
elementHandlers.add(handler);
|
|
1542
|
+
observer === null || observer === void 0 ? void 0 : observer.observe(element);
|
|
1543
|
+
});
|
|
1544
|
+
return () => {
|
|
1545
|
+
elements.forEach((element) => {
|
|
1546
|
+
const elementHandlers = resizeHandlers.get(element);
|
|
1547
|
+
elementHandlers === null || elementHandlers === void 0 ? void 0 : elementHandlers.delete(handler);
|
|
1548
|
+
if (!(elementHandlers === null || elementHandlers === void 0 ? void 0 : elementHandlers.size)) {
|
|
1549
|
+
observer === null || observer === void 0 ? void 0 : observer.unobserve(element);
|
|
1550
|
+
}
|
|
1551
|
+
});
|
|
1552
|
+
};
|
|
1553
|
+
}
|
|
1554
|
+
|
|
1555
|
+
const windowCallbacks = new Set();
|
|
1556
|
+
let windowResizeHandler;
|
|
1557
|
+
function createWindowResizeHandler() {
|
|
1558
|
+
windowResizeHandler = () => {
|
|
1559
|
+
const size = {
|
|
1560
|
+
width: window.innerWidth,
|
|
1561
|
+
height: window.innerHeight,
|
|
1562
|
+
};
|
|
1563
|
+
const info = {
|
|
1564
|
+
target: window,
|
|
1565
|
+
size,
|
|
1566
|
+
contentSize: size,
|
|
1567
|
+
};
|
|
1568
|
+
windowCallbacks.forEach((callback) => callback(info));
|
|
1569
|
+
};
|
|
1570
|
+
window.addEventListener("resize", windowResizeHandler);
|
|
1571
|
+
}
|
|
1572
|
+
function resizeWindow(callback) {
|
|
1573
|
+
windowCallbacks.add(callback);
|
|
1574
|
+
if (!windowResizeHandler)
|
|
1575
|
+
createWindowResizeHandler();
|
|
1576
|
+
return () => {
|
|
1577
|
+
windowCallbacks.delete(callback);
|
|
1578
|
+
if (!windowCallbacks.size && windowResizeHandler) {
|
|
1579
|
+
windowResizeHandler = undefined;
|
|
1580
|
+
}
|
|
1581
|
+
};
|
|
1582
|
+
}
|
|
1583
|
+
|
|
1584
|
+
function resize(a, b) {
|
|
1585
|
+
return isFunction(a) ? resizeWindow(a) : resizeElement(a, b);
|
|
1586
|
+
}
|
|
1587
|
+
|
|
1588
|
+
/**
|
|
1589
|
+
* A time in milliseconds, beyond which we consider the scroll velocity to be 0.
|
|
1590
|
+
*/
|
|
1591
|
+
const maxElapsed = 50;
|
|
1592
|
+
const createAxisInfo = () => ({
|
|
1593
|
+
current: 0,
|
|
1594
|
+
offset: [],
|
|
1595
|
+
progress: 0,
|
|
1596
|
+
scrollLength: 0,
|
|
1597
|
+
targetOffset: 0,
|
|
1598
|
+
targetLength: 0,
|
|
1599
|
+
containerLength: 0,
|
|
1600
|
+
velocity: 0,
|
|
1601
|
+
});
|
|
1602
|
+
const createScrollInfo = () => ({
|
|
1603
|
+
time: 0,
|
|
1604
|
+
x: createAxisInfo(),
|
|
1605
|
+
y: createAxisInfo(),
|
|
1606
|
+
});
|
|
1607
|
+
const keys = {
|
|
1608
|
+
x: {
|
|
1609
|
+
length: "Width",
|
|
1610
|
+
position: "Left",
|
|
1611
|
+
},
|
|
1612
|
+
y: {
|
|
1613
|
+
length: "Height",
|
|
1614
|
+
position: "Top",
|
|
1615
|
+
},
|
|
1616
|
+
};
|
|
1617
|
+
function updateAxisInfo(element, axisName, info, time) {
|
|
1618
|
+
const axis = info[axisName];
|
|
1619
|
+
const { length, position } = keys[axisName];
|
|
1620
|
+
const prev = axis.current;
|
|
1621
|
+
const prevTime = info.time;
|
|
1622
|
+
axis.current = element["scroll" + position];
|
|
1623
|
+
axis.scrollLength = element["scroll" + length] - element["client" + length];
|
|
1624
|
+
axis.offset.length = 0;
|
|
1625
|
+
axis.offset[0] = 0;
|
|
1626
|
+
axis.offset[1] = axis.scrollLength;
|
|
1627
|
+
axis.progress = progress(0, axis.scrollLength, axis.current);
|
|
1628
|
+
const elapsed = time - prevTime;
|
|
1629
|
+
axis.velocity =
|
|
1630
|
+
elapsed > maxElapsed ? 0 : velocityPerSecond(axis.current - prev, elapsed);
|
|
1631
|
+
}
|
|
1632
|
+
function updateScrollInfo(element, info, time) {
|
|
1633
|
+
updateAxisInfo(element, "x", info, time);
|
|
1634
|
+
updateAxisInfo(element, "y", info, time);
|
|
1635
|
+
info.time = time;
|
|
1636
|
+
}
|
|
1637
|
+
|
|
1638
|
+
function calcInset(element, container) {
|
|
1639
|
+
let inset = { x: 0, y: 0 };
|
|
1640
|
+
let current = element;
|
|
1641
|
+
while (current && current !== container) {
|
|
1642
|
+
if (current instanceof HTMLElement) {
|
|
1643
|
+
inset.x += current.offsetLeft;
|
|
1644
|
+
inset.y += current.offsetTop;
|
|
1645
|
+
current = current.offsetParent;
|
|
1646
|
+
}
|
|
1647
|
+
else if (current instanceof SVGGraphicsElement && "getBBox" in current) {
|
|
1648
|
+
const { top, left } = current.getBBox();
|
|
1649
|
+
inset.x += left;
|
|
1650
|
+
inset.y += top;
|
|
1651
|
+
/**
|
|
1652
|
+
* Assign the next parent element as the <svg /> tag.
|
|
1653
|
+
*/
|
|
1654
|
+
while (current && current.tagName !== "svg") {
|
|
1655
|
+
current = current.parentNode;
|
|
1656
|
+
}
|
|
1657
|
+
}
|
|
1658
|
+
}
|
|
1659
|
+
return inset;
|
|
1660
|
+
}
|
|
1661
|
+
|
|
1662
|
+
const ScrollOffset = {
|
|
1663
|
+
Enter: [
|
|
1664
|
+
[0, 1],
|
|
1665
|
+
[1, 1],
|
|
1666
|
+
],
|
|
1667
|
+
Exit: [
|
|
1668
|
+
[0, 0],
|
|
1669
|
+
[1, 0],
|
|
1670
|
+
],
|
|
1671
|
+
Any: [
|
|
1672
|
+
[1, 0],
|
|
1673
|
+
[0, 1],
|
|
1674
|
+
],
|
|
1675
|
+
All: [
|
|
1676
|
+
[0, 0],
|
|
1677
|
+
[1, 1],
|
|
1678
|
+
],
|
|
1679
|
+
};
|
|
1680
|
+
|
|
1681
|
+
const namedEdges = {
|
|
1682
|
+
start: 0,
|
|
1683
|
+
center: 0.5,
|
|
1684
|
+
end: 1,
|
|
1685
|
+
};
|
|
1686
|
+
function resolveEdge(edge, length, inset = 0) {
|
|
1687
|
+
let delta = 0;
|
|
1688
|
+
/**
|
|
1689
|
+
* If we have this edge defined as a preset, replace the definition
|
|
1690
|
+
* with the numerical value.
|
|
1691
|
+
*/
|
|
1692
|
+
if (namedEdges[edge] !== undefined) {
|
|
1693
|
+
edge = namedEdges[edge];
|
|
1694
|
+
}
|
|
1695
|
+
/**
|
|
1696
|
+
* Handle unit values
|
|
1697
|
+
*/
|
|
1698
|
+
if (isString(edge)) {
|
|
1699
|
+
const asNumber = parseFloat(edge);
|
|
1700
|
+
if (edge.endsWith("px")) {
|
|
1701
|
+
delta = asNumber;
|
|
1702
|
+
}
|
|
1703
|
+
else if (edge.endsWith("%")) {
|
|
1704
|
+
edge = asNumber / 100;
|
|
1705
|
+
}
|
|
1706
|
+
else if (edge.endsWith("vw")) {
|
|
1707
|
+
delta = (asNumber / 100) * document.documentElement.clientWidth;
|
|
1708
|
+
}
|
|
1709
|
+
else if (edge.endsWith("vh")) {
|
|
1710
|
+
delta = (asNumber / 100) * document.documentElement.clientHeight;
|
|
1711
|
+
}
|
|
1712
|
+
else {
|
|
1713
|
+
edge = asNumber;
|
|
1714
|
+
}
|
|
1715
|
+
}
|
|
1716
|
+
/**
|
|
1717
|
+
* If the edge is defined as a number, handle as a progress value.
|
|
1718
|
+
*/
|
|
1719
|
+
if (isNumber(edge)) {
|
|
1720
|
+
delta = length * edge;
|
|
1721
|
+
}
|
|
1722
|
+
return inset + delta;
|
|
1723
|
+
}
|
|
1724
|
+
|
|
1725
|
+
const defaultOffset = [0, 0];
|
|
1726
|
+
function resolveOffset(offset, containerLength, targetLength, targetInset) {
|
|
1727
|
+
let offsetDefinition = Array.isArray(offset) ? offset : defaultOffset;
|
|
1728
|
+
let targetPoint = 0;
|
|
1729
|
+
let containerPoint = 0;
|
|
1730
|
+
if (isNumber(offset)) {
|
|
1731
|
+
/**
|
|
1732
|
+
* If we're provided offset: [0, 0.5, 1] then each number x should become
|
|
1733
|
+
* [x, x], so we default to the behaviour of mapping 0 => 0 of both target
|
|
1734
|
+
* and container etc.
|
|
1735
|
+
*/
|
|
1736
|
+
offsetDefinition = [offset, offset];
|
|
1737
|
+
}
|
|
1738
|
+
else if (isString(offset)) {
|
|
1739
|
+
offset = offset.trim();
|
|
1740
|
+
if (offset.includes(" ")) {
|
|
1741
|
+
offsetDefinition = offset.split(" ");
|
|
1742
|
+
}
|
|
1743
|
+
else {
|
|
1744
|
+
/**
|
|
1745
|
+
* If we're provided a definition like "100px" then we want to apply
|
|
1746
|
+
* that only to the top of the target point, leaving the container at 0.
|
|
1747
|
+
* Whereas a named offset like "end" should be applied to both.
|
|
1748
|
+
*/
|
|
1749
|
+
offsetDefinition = [offset, namedEdges[offset] ? offset : `0`];
|
|
1750
|
+
}
|
|
1751
|
+
}
|
|
1752
|
+
targetPoint = resolveEdge(offsetDefinition[0], targetLength, targetInset);
|
|
1753
|
+
containerPoint = resolveEdge(offsetDefinition[1], containerLength);
|
|
1754
|
+
return targetPoint - containerPoint;
|
|
1755
|
+
}
|
|
1756
|
+
|
|
1757
|
+
const point = { x: 0, y: 0 };
|
|
1758
|
+
function resolveOffsets(container, info, options) {
|
|
1759
|
+
let { offset: offsetDefinition = ScrollOffset.All } = options;
|
|
1760
|
+
const { target = container, axis = "y" } = options;
|
|
1761
|
+
const lengthLabel = axis === "y" ? "height" : "width";
|
|
1762
|
+
const inset = target !== container ? calcInset(target, container) : point;
|
|
1763
|
+
/**
|
|
1764
|
+
* Measure the target and container. If they're the same thing then we
|
|
1765
|
+
* use the container's scrollWidth/Height as the target, from there
|
|
1766
|
+
* all other calculations can remain the same.
|
|
1767
|
+
*/
|
|
1768
|
+
const targetSize = target === container
|
|
1769
|
+
? { width: container.scrollWidth, height: container.scrollHeight }
|
|
1770
|
+
: { width: target.clientWidth, height: target.clientHeight };
|
|
1771
|
+
const containerSize = {
|
|
1772
|
+
width: container.clientWidth,
|
|
1773
|
+
height: container.clientHeight,
|
|
1774
|
+
};
|
|
1775
|
+
/**
|
|
1776
|
+
* Reset the length of the resolved offset array rather than creating a new one.
|
|
1777
|
+
* TODO: More reusable data structures for targetSize/containerSize would also be good.
|
|
1778
|
+
*/
|
|
1779
|
+
info[axis].offset.length = 0;
|
|
1780
|
+
/**
|
|
1781
|
+
* Populate the offset array by resolving the user's offset definition into
|
|
1782
|
+
* a list of pixel scroll offets.
|
|
1783
|
+
*/
|
|
1784
|
+
let hasChanged = !info[axis].interpolate;
|
|
1785
|
+
const numOffsets = offsetDefinition.length;
|
|
1786
|
+
for (let i = 0; i < numOffsets; i++) {
|
|
1787
|
+
const offset = resolveOffset(offsetDefinition[i], containerSize[lengthLabel], targetSize[lengthLabel], inset[axis]);
|
|
1788
|
+
if (!hasChanged && offset !== info[axis].interpolatorOffsets[i]) {
|
|
1789
|
+
hasChanged = true;
|
|
1790
|
+
}
|
|
1791
|
+
info[axis].offset[i] = offset;
|
|
1792
|
+
}
|
|
1793
|
+
/**
|
|
1794
|
+
* If the pixel scroll offsets have changed, create a new interpolator function
|
|
1795
|
+
* to map scroll value into a progress.
|
|
1796
|
+
*/
|
|
1797
|
+
if (hasChanged) {
|
|
1798
|
+
info[axis].interpolate = interpolate(defaultOffset$1(numOffsets), info[axis].offset);
|
|
1799
|
+
info[axis].interpolatorOffsets = [...info[axis].offset];
|
|
1800
|
+
}
|
|
1801
|
+
info[axis].progress = info[axis].interpolate(info[axis].current);
|
|
1802
|
+
}
|
|
1803
|
+
|
|
1804
|
+
function measure(container, target = container, info) {
|
|
1805
|
+
/**
|
|
1806
|
+
* Find inset of target within scrollable container
|
|
1807
|
+
*/
|
|
1808
|
+
info.x.targetOffset = 0;
|
|
1809
|
+
info.y.targetOffset = 0;
|
|
1810
|
+
if (target !== container) {
|
|
1811
|
+
let node = target;
|
|
1812
|
+
while (node && node != container) {
|
|
1813
|
+
info.x.targetOffset += node.offsetLeft;
|
|
1814
|
+
info.y.targetOffset += node.offsetTop;
|
|
1815
|
+
node = node.offsetParent;
|
|
1816
|
+
}
|
|
1817
|
+
}
|
|
1818
|
+
info.x.targetLength =
|
|
1819
|
+
target === container ? target.scrollWidth : target.clientWidth;
|
|
1820
|
+
info.y.targetLength =
|
|
1821
|
+
target === container ? target.scrollHeight : target.clientHeight;
|
|
1822
|
+
info.x.containerLength = container.clientWidth;
|
|
1823
|
+
info.y.containerLength = container.clientHeight;
|
|
1824
|
+
}
|
|
1825
|
+
function createOnScrollHandler(element, onScroll, info, options = {}) {
|
|
1826
|
+
const axis = options.axis || "y";
|
|
1827
|
+
return {
|
|
1828
|
+
measure: () => measure(element, options.target, info),
|
|
1829
|
+
update: (time) => {
|
|
1830
|
+
updateScrollInfo(element, info, time);
|
|
1831
|
+
if (options.offset || options.target) {
|
|
1832
|
+
resolveOffsets(element, info, options);
|
|
1833
|
+
}
|
|
1834
|
+
},
|
|
1835
|
+
notify: isFunction(onScroll)
|
|
1836
|
+
? () => onScroll(info)
|
|
1837
|
+
: scrubAnimation(onScroll, info[axis]),
|
|
1838
|
+
};
|
|
1839
|
+
}
|
|
1840
|
+
function scrubAnimation(controls, axisInfo) {
|
|
1841
|
+
controls.pause();
|
|
1842
|
+
controls.forEachNative((animation, { easing }) => {
|
|
1843
|
+
var _a, _b;
|
|
1844
|
+
if (animation.updateDuration) {
|
|
1845
|
+
if (!easing)
|
|
1846
|
+
animation.easing = noopReturn;
|
|
1847
|
+
animation.updateDuration(1);
|
|
1848
|
+
}
|
|
1849
|
+
else {
|
|
1850
|
+
const timingOptions = { duration: 1000 };
|
|
1851
|
+
if (!easing)
|
|
1852
|
+
timingOptions.easing = "linear";
|
|
1853
|
+
(_b = (_a = animation.effect) === null || _a === void 0 ? void 0 : _a.updateTiming) === null || _b === void 0 ? void 0 : _b.call(_a, timingOptions);
|
|
1854
|
+
}
|
|
1855
|
+
});
|
|
1856
|
+
return () => {
|
|
1857
|
+
controls.currentTime = axisInfo.progress;
|
|
1858
|
+
};
|
|
1859
|
+
}
|
|
1860
|
+
|
|
1861
|
+
const scrollListeners = new WeakMap();
|
|
1862
|
+
const resizeListeners = new WeakMap();
|
|
1863
|
+
const onScrollHandlers = new WeakMap();
|
|
1864
|
+
const getEventTarget = (element) => element === document.documentElement ? window : element;
|
|
1865
|
+
function scroll(onScroll, _a = {}) {
|
|
1866
|
+
var { container = document.documentElement } = _a, options = __rest(_a, ["container"]);
|
|
1867
|
+
let containerHandlers = onScrollHandlers.get(container);
|
|
1868
|
+
/**
|
|
1869
|
+
* Get the onScroll handlers for this container.
|
|
1870
|
+
* If one isn't found, create a new one.
|
|
1871
|
+
*/
|
|
1872
|
+
if (!containerHandlers) {
|
|
1873
|
+
containerHandlers = new Set();
|
|
1874
|
+
onScrollHandlers.set(container, containerHandlers);
|
|
1875
|
+
}
|
|
1876
|
+
/**
|
|
1877
|
+
* Create a new onScroll handler for the provided callback.
|
|
1878
|
+
*/
|
|
1879
|
+
const info = createScrollInfo();
|
|
1880
|
+
const containerHandler = createOnScrollHandler(container, onScroll, info, options);
|
|
1881
|
+
containerHandlers.add(containerHandler);
|
|
1882
|
+
/**
|
|
1883
|
+
* Check if there's a scroll event listener for this container.
|
|
1884
|
+
* If not, create one.
|
|
1885
|
+
*/
|
|
1886
|
+
if (!scrollListeners.has(container)) {
|
|
1887
|
+
const listener = () => {
|
|
1888
|
+
const time = performance.now();
|
|
1889
|
+
for (const handler of containerHandlers)
|
|
1890
|
+
handler.measure();
|
|
1891
|
+
for (const handler of containerHandlers)
|
|
1892
|
+
handler.update(time);
|
|
1893
|
+
for (const handler of containerHandlers)
|
|
1894
|
+
handler.notify();
|
|
1895
|
+
};
|
|
1896
|
+
scrollListeners.set(container, listener);
|
|
1897
|
+
const target = getEventTarget(container);
|
|
1898
|
+
window.addEventListener("resize", listener, { passive: true });
|
|
1899
|
+
if (container !== document.documentElement) {
|
|
1900
|
+
resizeListeners.set(container, resize(container, listener));
|
|
1901
|
+
}
|
|
1902
|
+
target.addEventListener("scroll", listener, { passive: true });
|
|
1903
|
+
}
|
|
1904
|
+
const listener = scrollListeners.get(container);
|
|
1905
|
+
const onLoadProcesss = requestAnimationFrame(listener);
|
|
1906
|
+
return () => {
|
|
1907
|
+
var _a;
|
|
1908
|
+
if (typeof onScroll !== "function")
|
|
1909
|
+
onScroll.stop();
|
|
1910
|
+
cancelAnimationFrame(onLoadProcesss);
|
|
1911
|
+
/**
|
|
1912
|
+
* Check if we even have any handlers for this container.
|
|
1913
|
+
*/
|
|
1914
|
+
const containerHandlers = onScrollHandlers.get(container);
|
|
1915
|
+
if (!containerHandlers)
|
|
1916
|
+
return;
|
|
1917
|
+
containerHandlers.delete(containerHandler);
|
|
1918
|
+
if (containerHandlers.size)
|
|
1919
|
+
return;
|
|
1920
|
+
/**
|
|
1921
|
+
* If no more handlers, remove the scroll listener too.
|
|
1922
|
+
*/
|
|
1923
|
+
const listener = scrollListeners.get(container);
|
|
1924
|
+
scrollListeners.delete(container);
|
|
1925
|
+
if (listener) {
|
|
1926
|
+
getEventTarget(container).removeEventListener("scroll", listener);
|
|
1927
|
+
(_a = resizeListeners.get(container)) === null || _a === void 0 ? void 0 : _a();
|
|
1928
|
+
window.removeEventListener("resize", listener);
|
|
1929
|
+
}
|
|
1930
|
+
};
|
|
1931
|
+
}
|
|
1932
|
+
|
|
1933
|
+
function hasChanged(a, b) {
|
|
1934
|
+
if (typeof a !== typeof b)
|
|
1935
|
+
return true;
|
|
1936
|
+
if (Array.isArray(a) && Array.isArray(b))
|
|
1937
|
+
return !shallowCompare(a, b);
|
|
1938
|
+
return a !== b;
|
|
1939
|
+
}
|
|
1940
|
+
function shallowCompare(next, prev) {
|
|
1941
|
+
const prevLength = prev.length;
|
|
1942
|
+
if (prevLength !== next.length)
|
|
1943
|
+
return false;
|
|
1944
|
+
for (let i = 0; i < prevLength; i++) {
|
|
1945
|
+
if (prev[i] !== next[i])
|
|
1946
|
+
return false;
|
|
1947
|
+
}
|
|
1948
|
+
return true;
|
|
1949
|
+
}
|
|
1950
|
+
|
|
1951
|
+
function isVariant(definition) {
|
|
1952
|
+
return typeof definition === "object";
|
|
1953
|
+
}
|
|
1954
|
+
|
|
1955
|
+
function resolveVariant(definition, variants) {
|
|
1956
|
+
if (isVariant(definition)) {
|
|
1957
|
+
return definition;
|
|
1958
|
+
}
|
|
1959
|
+
else if (definition && variants) {
|
|
1960
|
+
return variants[definition];
|
|
1961
|
+
}
|
|
1962
|
+
}
|
|
1963
|
+
|
|
1964
|
+
let scheduled = undefined;
|
|
1965
|
+
function processScheduledAnimations() {
|
|
1966
|
+
if (!scheduled)
|
|
1967
|
+
return;
|
|
1968
|
+
const generators = scheduled.sort(compareByDepth).map(fireAnimateUpdates);
|
|
1969
|
+
generators.forEach(fireNext);
|
|
1970
|
+
generators.forEach(fireNext);
|
|
1971
|
+
scheduled = undefined;
|
|
1972
|
+
}
|
|
1973
|
+
function scheduleAnimation(state) {
|
|
1974
|
+
if (!scheduled) {
|
|
1975
|
+
scheduled = [state];
|
|
1976
|
+
requestAnimationFrame(processScheduledAnimations);
|
|
1977
|
+
}
|
|
1978
|
+
else {
|
|
1979
|
+
addUniqueItem(scheduled, state);
|
|
1980
|
+
}
|
|
1981
|
+
}
|
|
1982
|
+
function unscheduleAnimation(state) {
|
|
1983
|
+
scheduled && removeItem(scheduled, state);
|
|
1984
|
+
}
|
|
1985
|
+
const compareByDepth = (a, b) => a.getDepth() - b.getDepth();
|
|
1986
|
+
const fireAnimateUpdates = (state) => state.animateUpdates();
|
|
1987
|
+
const fireNext = (iterator) => iterator.next();
|
|
1988
|
+
|
|
1989
|
+
const motionEvent = (name, target) => new CustomEvent(name, { detail: { target } });
|
|
1990
|
+
function dispatchPointerEvent(element, name, event) {
|
|
1991
|
+
element.dispatchEvent(new CustomEvent(name, { detail: { originalEvent: event } }));
|
|
1992
|
+
}
|
|
1993
|
+
function dispatchViewEvent(element, name, entry) {
|
|
1994
|
+
element.dispatchEvent(new CustomEvent(name, { detail: { originalEntry: entry } }));
|
|
1995
|
+
}
|
|
1996
|
+
|
|
1997
|
+
const inView = {
|
|
1998
|
+
isActive: (options) => Boolean(options.inView),
|
|
1999
|
+
subscribe: (element, { enable, disable }, { inViewOptions = {} }) => {
|
|
2000
|
+
const { once } = inViewOptions, viewOptions = __rest(inViewOptions, ["once"]);
|
|
2001
|
+
return inView$1(element, (enterEntry) => {
|
|
2002
|
+
enable();
|
|
2003
|
+
dispatchViewEvent(element, "viewenter", enterEntry);
|
|
2004
|
+
if (!once) {
|
|
2005
|
+
return (leaveEntry) => {
|
|
2006
|
+
disable();
|
|
2007
|
+
dispatchViewEvent(element, "viewleave", leaveEntry);
|
|
2008
|
+
};
|
|
2009
|
+
}
|
|
2010
|
+
}, viewOptions);
|
|
2011
|
+
},
|
|
2012
|
+
};
|
|
2013
|
+
|
|
2014
|
+
const mouseEvent = (element, name, action) => (event) => {
|
|
2015
|
+
if (event.pointerType && event.pointerType !== "mouse")
|
|
2016
|
+
return;
|
|
2017
|
+
action();
|
|
2018
|
+
dispatchPointerEvent(element, name, event);
|
|
2019
|
+
};
|
|
2020
|
+
const hover = {
|
|
2021
|
+
isActive: (options) => Boolean(options.hover),
|
|
2022
|
+
subscribe: (element, { enable, disable }) => {
|
|
2023
|
+
const onEnter = mouseEvent(element, "hoverstart", enable);
|
|
2024
|
+
const onLeave = mouseEvent(element, "hoverend", disable);
|
|
2025
|
+
element.addEventListener("pointerenter", onEnter);
|
|
2026
|
+
element.addEventListener("pointerleave", onLeave);
|
|
2027
|
+
return () => {
|
|
2028
|
+
element.removeEventListener("pointerenter", onEnter);
|
|
2029
|
+
element.removeEventListener("pointerleave", onLeave);
|
|
2030
|
+
};
|
|
2031
|
+
},
|
|
2032
|
+
};
|
|
2033
|
+
|
|
2034
|
+
const press = {
|
|
2035
|
+
isActive: (options) => Boolean(options.press),
|
|
2036
|
+
subscribe: (element, { enable, disable }) => {
|
|
2037
|
+
const onPointerUp = (event) => {
|
|
2038
|
+
disable();
|
|
2039
|
+
dispatchPointerEvent(element, "pressend", event);
|
|
2040
|
+
window.removeEventListener("pointerup", onPointerUp);
|
|
2041
|
+
};
|
|
2042
|
+
const onPointerDown = (event) => {
|
|
2043
|
+
enable();
|
|
2044
|
+
dispatchPointerEvent(element, "pressstart", event);
|
|
2045
|
+
window.addEventListener("pointerup", onPointerUp);
|
|
2046
|
+
};
|
|
2047
|
+
element.addEventListener("pointerdown", onPointerDown);
|
|
2048
|
+
return () => {
|
|
2049
|
+
element.removeEventListener("pointerdown", onPointerDown);
|
|
2050
|
+
window.removeEventListener("pointerup", onPointerUp);
|
|
2051
|
+
};
|
|
2052
|
+
},
|
|
2053
|
+
};
|
|
2054
|
+
|
|
2055
|
+
const gestures = { inView, hover, press };
|
|
2056
|
+
/**
|
|
2057
|
+
* A list of state types, in priority order. If a value is defined in
|
|
2058
|
+
* a righter-most type, it will override any definition in a lefter-most.
|
|
2059
|
+
*/
|
|
2060
|
+
const stateTypes = ["initial", "animate", ...Object.keys(gestures), "exit"];
|
|
2061
|
+
/**
|
|
2062
|
+
* A global store of all generated motion states. This can be used to lookup
|
|
2063
|
+
* a motion state for a given Element.
|
|
2064
|
+
*/
|
|
2065
|
+
const mountedStates = new WeakMap();
|
|
2066
|
+
function createMotionState(options = {}, parent) {
|
|
2067
|
+
/**
|
|
2068
|
+
* The element represented by the motion state. This is an empty reference
|
|
2069
|
+
* when we create the state to support SSR and allow for later mounting
|
|
2070
|
+
* in view libraries.
|
|
2071
|
+
*
|
|
2072
|
+
* @ts-ignore
|
|
2073
|
+
*/
|
|
2074
|
+
let element;
|
|
2075
|
+
/**
|
|
2076
|
+
* Calculate a depth that we can use to order motion states by tree depth.
|
|
2077
|
+
*/
|
|
2078
|
+
let depth = parent ? parent.getDepth() + 1 : 0;
|
|
2079
|
+
/**
|
|
2080
|
+
* Track which states are currently active.
|
|
2081
|
+
*/
|
|
2082
|
+
const activeStates = { initial: true, animate: true };
|
|
2083
|
+
/**
|
|
2084
|
+
* A map of functions that, when called, will remove event listeners for
|
|
2085
|
+
* a given gesture.
|
|
2086
|
+
*/
|
|
2087
|
+
const gestureSubscriptions = {};
|
|
2088
|
+
/**
|
|
2089
|
+
* Initialise a context to share through motion states. This
|
|
2090
|
+
* will be populated by variant names (if any).
|
|
2091
|
+
*/
|
|
2092
|
+
const context = {};
|
|
2093
|
+
for (const name of stateTypes) {
|
|
2094
|
+
context[name] =
|
|
2095
|
+
typeof options[name] === "string"
|
|
2096
|
+
? options[name]
|
|
2097
|
+
: parent === null || parent === void 0 ? void 0 : parent.getContext()[name];
|
|
2098
|
+
}
|
|
2099
|
+
/**
|
|
2100
|
+
* If initial is set to false we use the animate prop as the initial
|
|
2101
|
+
* animation state.
|
|
2102
|
+
*/
|
|
2103
|
+
const initialVariantSource = options.initial === false ? "animate" : "initial";
|
|
2104
|
+
/**
|
|
2105
|
+
* Destructure an initial target out from the resolved initial variant.
|
|
2106
|
+
*/
|
|
2107
|
+
let _a = resolveVariant(options[initialVariantSource] || context[initialVariantSource], options.variants) || {}, target = __rest(_a, ["transition"]);
|
|
2108
|
+
/**
|
|
2109
|
+
* The base target is a cached map of values that we'll use to animate
|
|
2110
|
+
* back to if a value is removed from all active state types. This
|
|
2111
|
+
* is usually the initial value as read from the DOM, for instance if
|
|
2112
|
+
* it hasn't been defined in initial.
|
|
2113
|
+
*/
|
|
2114
|
+
const baseTarget = Object.assign({}, target);
|
|
2115
|
+
/**
|
|
2116
|
+
* A generator that will be processed by the global animation scheduler.
|
|
2117
|
+
* This yeilds when it switches from reading the DOM to writing to it
|
|
2118
|
+
* to prevent layout thrashing.
|
|
2119
|
+
*/
|
|
2120
|
+
function* animateUpdates() {
|
|
2121
|
+
var _a, _b;
|
|
2122
|
+
const prevTarget = target;
|
|
2123
|
+
target = {};
|
|
2124
|
+
const animationOptions = {};
|
|
2125
|
+
for (const name of stateTypes) {
|
|
2126
|
+
if (!activeStates[name])
|
|
2127
|
+
continue;
|
|
2128
|
+
const variant = resolveVariant(options[name]);
|
|
2129
|
+
if (!variant)
|
|
2130
|
+
continue;
|
|
2131
|
+
for (const key in variant) {
|
|
2132
|
+
if (key === "transition")
|
|
2133
|
+
continue;
|
|
2134
|
+
target[key] = variant[key];
|
|
2135
|
+
animationOptions[key] = getOptions((_b = (_a = variant.transition) !== null && _a !== void 0 ? _a : options.transition) !== null && _b !== void 0 ? _b : {}, key);
|
|
2136
|
+
}
|
|
2137
|
+
}
|
|
2138
|
+
const allTargetKeys = new Set([
|
|
2139
|
+
...Object.keys(target),
|
|
2140
|
+
...Object.keys(prevTarget),
|
|
2141
|
+
]);
|
|
2142
|
+
const animationFactories = [];
|
|
2143
|
+
allTargetKeys.forEach((key) => {
|
|
2144
|
+
var _a;
|
|
2145
|
+
if (target[key] === undefined) {
|
|
2146
|
+
target[key] = baseTarget[key];
|
|
2147
|
+
}
|
|
2148
|
+
if (hasChanged(prevTarget[key], target[key])) {
|
|
2149
|
+
(_a = baseTarget[key]) !== null && _a !== void 0 ? _a : (baseTarget[key] = style.get(element, key));
|
|
2150
|
+
animationFactories.push(animateStyle(element, key, target[key], animationOptions[key]));
|
|
2151
|
+
}
|
|
2152
|
+
});
|
|
2153
|
+
// Wait for all animation states to read from the DOM
|
|
2154
|
+
yield;
|
|
2155
|
+
const animations = animationFactories
|
|
2156
|
+
.map((factory) => factory())
|
|
2157
|
+
.filter(Boolean);
|
|
2158
|
+
if (!animations.length)
|
|
2159
|
+
return;
|
|
2160
|
+
const animationTarget = target;
|
|
2161
|
+
element.dispatchEvent(motionEvent("motionstart", animationTarget));
|
|
2162
|
+
Promise.all(animations.map((animation) => animation.finished))
|
|
2163
|
+
.then(() => {
|
|
2164
|
+
element.dispatchEvent(motionEvent("motioncomplete", animationTarget));
|
|
2165
|
+
})
|
|
2166
|
+
.catch(noop);
|
|
2167
|
+
}
|
|
2168
|
+
const setGesture = (name, isActive) => () => {
|
|
2169
|
+
activeStates[name] = isActive;
|
|
2170
|
+
scheduleAnimation(state);
|
|
2171
|
+
};
|
|
2172
|
+
const updateGestureSubscriptions = () => {
|
|
2173
|
+
for (const name in gestures) {
|
|
2174
|
+
const isGestureActive = gestures[name].isActive(options);
|
|
2175
|
+
const remove = gestureSubscriptions[name];
|
|
2176
|
+
if (isGestureActive && !remove) {
|
|
2177
|
+
gestureSubscriptions[name] = gestures[name].subscribe(element, {
|
|
2178
|
+
enable: setGesture(name, true),
|
|
2179
|
+
disable: setGesture(name, false),
|
|
2180
|
+
}, options);
|
|
2181
|
+
}
|
|
2182
|
+
else if (!isGestureActive && remove) {
|
|
2183
|
+
remove();
|
|
2184
|
+
delete gestureSubscriptions[name];
|
|
2185
|
+
}
|
|
2186
|
+
}
|
|
2187
|
+
};
|
|
2188
|
+
const state = {
|
|
2189
|
+
update: (newOptions) => {
|
|
2190
|
+
if (!element)
|
|
2191
|
+
return;
|
|
2192
|
+
options = newOptions;
|
|
2193
|
+
updateGestureSubscriptions();
|
|
2194
|
+
scheduleAnimation(state);
|
|
2195
|
+
},
|
|
2196
|
+
setActive: (name, isActive) => {
|
|
2197
|
+
if (!element)
|
|
2198
|
+
return;
|
|
2199
|
+
activeStates[name] = isActive;
|
|
2200
|
+
scheduleAnimation(state);
|
|
2201
|
+
},
|
|
2202
|
+
animateUpdates,
|
|
2203
|
+
getDepth: () => depth,
|
|
2204
|
+
getTarget: () => target,
|
|
2205
|
+
getOptions: () => options,
|
|
2206
|
+
getContext: () => context,
|
|
2207
|
+
mount: (newElement) => {
|
|
2208
|
+
invariant(Boolean(newElement), "Animation state must be mounted with valid Element");
|
|
2209
|
+
element = newElement;
|
|
2210
|
+
mountedStates.set(element, state);
|
|
2211
|
+
updateGestureSubscriptions();
|
|
2212
|
+
return () => {
|
|
2213
|
+
mountedStates.delete(element);
|
|
2214
|
+
unscheduleAnimation(state);
|
|
2215
|
+
for (const key in gestureSubscriptions) {
|
|
2216
|
+
gestureSubscriptions[key]();
|
|
2217
|
+
}
|
|
2218
|
+
};
|
|
2219
|
+
},
|
|
2220
|
+
isMounted: () => Boolean(element),
|
|
2221
|
+
};
|
|
2222
|
+
return state;
|
|
2223
|
+
}
|
|
2224
|
+
|
|
2225
|
+
function createStyles(keyframes) {
|
|
2226
|
+
const initialKeyframes = {};
|
|
2227
|
+
const transformKeys = [];
|
|
2228
|
+
for (let key in keyframes) {
|
|
2229
|
+
const value = keyframes[key];
|
|
2230
|
+
if (isTransform(key)) {
|
|
2231
|
+
if (transformAlias[key])
|
|
2232
|
+
key = transformAlias[key];
|
|
2233
|
+
transformKeys.push(key);
|
|
2234
|
+
key = asTransformCssVar(key);
|
|
2235
|
+
}
|
|
2236
|
+
let initialKeyframe = Array.isArray(value) ? value[0] : value;
|
|
2237
|
+
/**
|
|
2238
|
+
* If this is a number and we have a default value type, convert the number
|
|
2239
|
+
* to this type.
|
|
2240
|
+
*/
|
|
2241
|
+
const definition = transformDefinitions.get(key);
|
|
2242
|
+
if (definition) {
|
|
2243
|
+
initialKeyframe = isNumber(value)
|
|
2244
|
+
? definition.toDefaultUnit(value)
|
|
2245
|
+
: value;
|
|
2246
|
+
}
|
|
2247
|
+
initialKeyframes[key] = initialKeyframe;
|
|
2248
|
+
}
|
|
2249
|
+
if (transformKeys.length) {
|
|
2250
|
+
initialKeyframes.transform = buildTransformTemplate(transformKeys);
|
|
2251
|
+
}
|
|
2252
|
+
return initialKeyframes;
|
|
2253
|
+
}
|
|
2254
|
+
|
|
2255
|
+
const camelLetterToPipeLetter = (letter) => `-${letter.toLowerCase()}`;
|
|
2256
|
+
const camelToPipeCase = (str) => str.replace(/[A-Z]/g, camelLetterToPipeLetter);
|
|
2257
|
+
function createStyleString(target = {}) {
|
|
2258
|
+
const styles = createStyles(target);
|
|
2259
|
+
let style = "";
|
|
2260
|
+
for (const key in styles) {
|
|
2261
|
+
style += key.startsWith("--") ? key : camelToPipeCase(key);
|
|
2262
|
+
style += `: ${styles[key]}; `;
|
|
2263
|
+
}
|
|
2264
|
+
return style;
|
|
2265
|
+
}
|
|
2266
|
+
|
|
2267
|
+
function animateProgress(target, options = {}) {
|
|
2268
|
+
return withControls([
|
|
1440
2269
|
() => {
|
|
1441
2270
|
const animation = new Animation(target, [0, 1], options);
|
|
1442
2271
|
animation.finished.catch(() => { });
|
|
1443
2272
|
return animation;
|
|
1444
2273
|
},
|
|
1445
|
-
], options
|
|
2274
|
+
], options, options.duration);
|
|
1446
2275
|
}
|
|
1447
2276
|
function animate(target, keyframesOrOptions, options) {
|
|
1448
|
-
const
|
|
1449
|
-
return
|
|
2277
|
+
const factory = isFunction(target) ? animateProgress : animate$1;
|
|
2278
|
+
return factory(target, keyframesOrOptions, options);
|
|
1450
2279
|
}
|
|
1451
2280
|
|
|
1452
2281
|
exports.MotionValue = MotionValue;
|
|
2282
|
+
exports.ScrollOffset = ScrollOffset;
|
|
1453
2283
|
exports.animate = animate;
|
|
2284
|
+
exports.animateStyle = animateStyle;
|
|
2285
|
+
exports.createMotionState = createMotionState;
|
|
2286
|
+
exports.createStyleString = createStyleString;
|
|
2287
|
+
exports.createStyles = createStyles;
|
|
2288
|
+
exports.getAnimationData = getAnimationData;
|
|
2289
|
+
exports.getStyleName = getStyleName;
|
|
1454
2290
|
exports.glide = glide;
|
|
1455
|
-
exports.inView = inView;
|
|
2291
|
+
exports.inView = inView$1;
|
|
2292
|
+
exports.mountedStates = mountedStates;
|
|
2293
|
+
exports.resize = resize;
|
|
2294
|
+
exports.scroll = scroll;
|
|
1456
2295
|
exports.spring = spring;
|
|
1457
2296
|
exports.stagger = stagger;
|
|
1458
2297
|
exports.style = style;
|
|
1459
2298
|
exports.timeline = timeline;
|
|
2299
|
+
exports.withControls = withControls;
|
|
1460
2300
|
|
|
1461
2301
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
1462
2302
|
|