animejs 4.2.0-beta.0 → 4.2.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/README.md +6 -1
- package/dist/bundles/anime.esm.js +448 -260
- package/dist/bundles/anime.esm.min.js +1 -1
- package/dist/bundles/anime.umd.js +449 -261
- package/dist/bundles/anime.umd.min.js +1 -1
- package/dist/modules/animatable/animatable.cjs +2 -2
- package/dist/modules/animatable/animatable.js +1 -1
- package/dist/modules/animation/animation.cjs +21 -14
- package/dist/modules/animation/animation.d.ts +0 -2
- package/dist/modules/animation/animation.js +20 -13
- package/dist/modules/core/consts.cjs +6 -1
- package/dist/modules/core/consts.d.ts +2 -0
- package/dist/modules/core/consts.js +5 -2
- package/dist/modules/core/globals.cjs +1 -0
- package/dist/modules/core/globals.js +1 -0
- package/dist/modules/core/render.cjs +3 -1
- package/dist/modules/core/render.js +3 -1
- package/dist/modules/core/styles.cjs +7 -7
- package/dist/modules/core/styles.js +9 -9
- package/dist/modules/core/values.cjs +16 -5
- package/dist/modules/core/values.js +18 -7
- package/dist/modules/draggable/draggable.cjs +16 -16
- package/dist/modules/draggable/draggable.d.ts +1 -1
- package/dist/modules/draggable/draggable.js +11 -11
- package/dist/modules/easings/{cubic-bezier.cjs → cubic-bezier/index.cjs} +3 -3
- package/dist/modules/easings/{cubic-bezier.d.ts → cubic-bezier/index.d.ts} +1 -1
- package/dist/modules/easings/{cubic-bezier.js → cubic-bezier/index.js} +3 -3
- package/dist/modules/easings/eases/index.cjs +14 -0
- package/dist/modules/easings/eases/index.d.ts +1 -0
- package/dist/modules/{spring → easings/eases}/index.js +2 -2
- package/dist/modules/easings/{eases.cjs → eases/parser.cjs} +68 -26
- package/dist/modules/easings/{eases.d.ts → eases/parser.d.ts} +31 -17
- package/dist/modules/easings/{eases.js → eases/parser.js} +59 -20
- package/dist/modules/easings/index.cjs +14 -12
- package/dist/modules/easings/index.d.ts +6 -6
- package/dist/modules/easings/index.js +6 -6
- package/dist/modules/easings/{irregular.cjs → irregular/index.cjs} +4 -4
- package/dist/modules/easings/{irregular.d.ts → irregular/index.d.ts} +1 -1
- package/dist/modules/easings/{irregular.js → irregular/index.js} +3 -3
- package/dist/modules/easings/{linear.cjs → linear/index.cjs} +3 -3
- package/dist/modules/easings/{linear.d.ts → linear/index.d.ts} +1 -1
- package/dist/modules/easings/{linear.js → linear/index.js} +3 -3
- package/dist/modules/easings/spring/index.cjs +255 -0
- package/dist/modules/{spring/spring.d.ts → easings/spring/index.d.ts} +21 -5
- package/dist/modules/easings/spring/index.js +251 -0
- package/dist/modules/easings/{steps.cjs → steps/index.cjs} +2 -2
- package/dist/modules/easings/{steps.d.ts → steps/index.d.ts} +1 -1
- package/dist/modules/easings/{steps.js → steps/index.js} +2 -2
- package/dist/modules/events/scroll.cjs +10 -6
- package/dist/modules/events/scroll.d.ts +2 -0
- package/dist/modules/events/scroll.js +9 -5
- package/dist/modules/index.cjs +14 -15
- package/dist/modules/index.d.ts +0 -1
- package/dist/modules/index.js +6 -7
- package/dist/modules/timeline/timeline.cjs +2 -2
- package/dist/modules/timeline/timeline.js +1 -1
- package/dist/modules/types/index.d.ts +30 -13
- package/dist/modules/utils/stagger.cjs +3 -3
- package/dist/modules/utils/stagger.js +2 -2
- package/dist/modules/waapi/composition.cjs +10 -4
- package/dist/modules/waapi/composition.d.ts +1 -1
- package/dist/modules/waapi/composition.js +10 -4
- package/dist/modules/waapi/waapi.cjs +50 -31
- package/dist/modules/waapi/waapi.d.ts +4 -2
- package/dist/modules/waapi/waapi.js +51 -32
- package/package.json +46 -10
- package/dist/modules/easings/parser.cjs +0 -59
- package/dist/modules/easings/parser.d.ts +0 -21
- package/dist/modules/easings/parser.js +0 -55
- package/dist/modules/spring/index.cjs +0 -15
- package/dist/modules/spring/index.d.ts +0 -1
- package/dist/modules/spring/spring.cjs +0 -133
- package/dist/modules/spring/spring.js +0 -130
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
* @property {Number|Boolean} [loop]
|
|
18
18
|
* @property {Boolean} [reversed]
|
|
19
19
|
* @property {Boolean} [alternate]
|
|
20
|
+
* @property {Boolean} [persist]
|
|
20
21
|
* @property {Boolean|ScrollObserver} [autoplay]
|
|
21
22
|
* @property {Number|FunctionValue} [duration]
|
|
22
23
|
* @property {Number|FunctionValue} [delay]
|
|
@@ -24,13 +25,13 @@
|
|
|
24
25
|
* @property {EasingParam} [ease]
|
|
25
26
|
* @property {'none'|'replace'|'blend'|compositionTypes} [composition]
|
|
26
27
|
* @property {(v: any) => any} [modifier]
|
|
27
|
-
* @property {
|
|
28
|
-
* @property {
|
|
29
|
-
* @property {
|
|
30
|
-
* @property {
|
|
31
|
-
* @property {
|
|
32
|
-
* @property {
|
|
33
|
-
* @property {
|
|
28
|
+
* @property {Callback<Tickable>} [onBegin]
|
|
29
|
+
* @property {Callback<Tickable>} [onBeforeUpdate]
|
|
30
|
+
* @property {Callback<Tickable>} [onUpdate]
|
|
31
|
+
* @property {Callback<Tickable>} [onLoop]
|
|
32
|
+
* @property {Callback<Tickable>} [onPause]
|
|
33
|
+
* @property {Callback<Tickable>} [onComplete]
|
|
34
|
+
* @property {Callback<Renderable>} [onRender]
|
|
34
35
|
*/
|
|
35
36
|
|
|
36
37
|
/** @typedef {JSAnimation|Timeline} Renderable */
|
|
@@ -86,7 +87,11 @@
|
|
|
86
87
|
*/
|
|
87
88
|
|
|
88
89
|
/**
|
|
89
|
-
* @typedef {('linear'|'
|
|
90
|
+
* @typedef {('linear'|'none'|'in'|'out'|'inOut'|'inQuad'|'outQuad'|'inOutQuad'|'inCubic'|'outCubic'|'inOutCubic'|'inQuart'|'outQuart'|'inOutQuart'|'inQuint'|'outQuint'|'inOutQuint'|'inSine'|'outSine'|'inOutSine'|'inCirc'|'outCirc'|'inOutCirc'|'inExpo'|'outExpo'|'inOutExpo'|'inBounce'|'outBounce'|'inOutBounce'|'inBack'|'outBack'|'inOutBack'|'inElastic'|'outElastic'|'inOutElastic'|'out(p = 1.675)'|'inOut(p = 1.675)'|'inBack(overshoot = 1.7)'|'outBack(overshoot = 1.7)'|'inOutBack(overshoot = 1.7)'|'inElastic(amplitude = 1, period = .3)'|'outElastic(amplitude = 1, period = .3)'|'inOutElastic(amplitude = 1, period = .3)')} EaseStringParamNames
|
|
91
|
+
*/
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* @typedef {('ease'|'ease-in'|'ease-out'|'ease-in-out'|'linear(0, 0.25, 1)'|'steps'|'steps(6, start)'|'step-start'|'step-end'|'cubic-bezier(0.42, 0, 1, 1)') } WAAPIEaseStringParamNames
|
|
90
95
|
*/
|
|
91
96
|
|
|
92
97
|
/**
|
|
@@ -97,7 +102,7 @@
|
|
|
97
102
|
|
|
98
103
|
/**
|
|
99
104
|
* @callback BackEasing
|
|
100
|
-
* @param {Number|String} [overshoot=1.
|
|
105
|
+
* @param {Number|String} [overshoot=1.7]
|
|
101
106
|
* @return {EasingFunction}
|
|
102
107
|
*/
|
|
103
108
|
|
|
@@ -113,6 +118,7 @@
|
|
|
113
118
|
// A hack to get both ease names suggestions AND allow any strings
|
|
114
119
|
// https://github.com/microsoft/TypeScript/issues/29729#issuecomment-460346421
|
|
115
120
|
/** @typedef {(String & {})|EaseStringParamNames|EasingFunction|Spring} EasingParam */
|
|
121
|
+
/** @typedef {(String & {})|EaseStringParamNames|WAAPIEaseStringParamNames|EasingFunction|Spring} WAAPIEasingParam */
|
|
116
122
|
|
|
117
123
|
// Spring types
|
|
118
124
|
|
|
@@ -122,6 +128,9 @@
|
|
|
122
128
|
* @property {Number} [stiffness=100] - Stiffness, default 100
|
|
123
129
|
* @property {Number} [damping=10] - Damping, default 10
|
|
124
130
|
* @property {Number} [velocity=0] - Initial velocity, default 0
|
|
131
|
+
* @property {Number} [bounce=0] - Initial bounce, default 0
|
|
132
|
+
* @property {Number} [duration=0] - The perceived duration, default 0
|
|
133
|
+
* @property {Callback<JSAnimation>} [onComplete] - Callback function called when the spring currentTime hits the perceived duration
|
|
125
134
|
*/
|
|
126
135
|
|
|
127
136
|
// Callback types
|
|
@@ -219,6 +228,7 @@
|
|
|
219
228
|
* @property {Number} _isOverlapped
|
|
220
229
|
* @property {Number} _isOverridden
|
|
221
230
|
* @property {Number} _renderTransforms
|
|
231
|
+
* @property {String} _inlineValue
|
|
222
232
|
* @property {Tween} _prevRep
|
|
223
233
|
* @property {Tween} _nextRep
|
|
224
234
|
* @property {Tween} _prevAdd
|
|
@@ -376,7 +386,7 @@
|
|
|
376
386
|
*/
|
|
377
387
|
|
|
378
388
|
/**
|
|
379
|
-
* @typedef {
|
|
389
|
+
* @typedef {Callback<WAAPIAnimation>} WAAPICallback
|
|
380
390
|
*/
|
|
381
391
|
|
|
382
392
|
/**
|
|
@@ -385,7 +395,7 @@
|
|
|
385
395
|
* @property {WAAPIKeyframeValue} [from]
|
|
386
396
|
* @property {Number|WAAPIFunctionValue} [duration]
|
|
387
397
|
* @property {Number|WAAPIFunctionValue} [delay]
|
|
388
|
-
* @property {
|
|
398
|
+
* @property {WAAPIEasingParam} [ease]
|
|
389
399
|
* @property {CompositeOperation} [composition]
|
|
390
400
|
*/
|
|
391
401
|
|
|
@@ -398,13 +408,14 @@
|
|
|
398
408
|
* @property {Number} [playbackRate]
|
|
399
409
|
* @property {Number|WAAPIFunctionValue} [duration]
|
|
400
410
|
* @property {Number|WAAPIFunctionValue} [delay]
|
|
401
|
-
* @property {
|
|
411
|
+
* @property {WAAPIEasingParam} [ease]
|
|
402
412
|
* @property {CompositeOperation} [composition]
|
|
413
|
+
* @property {Boolean} [persist]
|
|
403
414
|
* @property {WAAPICallback} [onComplete]
|
|
404
415
|
*/
|
|
405
416
|
|
|
406
417
|
/**
|
|
407
|
-
* @typedef {Record<String, WAAPIKeyframeValue | WAAPIAnimationOptions | Boolean | ScrollObserver | WAAPICallback |
|
|
418
|
+
* @typedef {Record<String, WAAPIKeyframeValue | WAAPIAnimationOptions | Boolean | ScrollObserver | WAAPICallback | WAAPIEasingParam | WAAPITweenOptions> & WAAPIAnimationOptions} WAAPIAnimationParams
|
|
408
419
|
*/
|
|
409
420
|
|
|
410
421
|
// Animatable types
|
|
@@ -688,6 +699,8 @@
|
|
|
688
699
|
// Strings
|
|
689
700
|
|
|
690
701
|
const emptyString = '';
|
|
702
|
+
const cssVarPrefix = 'var(';
|
|
703
|
+
|
|
691
704
|
const shortTransforms = /*#__PURE__*/ (() => {
|
|
692
705
|
const map = new Map();
|
|
693
706
|
map.set('x', 'translateX');
|
|
@@ -711,9 +724,9 @@
|
|
|
711
724
|
'skew',
|
|
712
725
|
'skewX',
|
|
713
726
|
'skewY',
|
|
714
|
-
'perspective',
|
|
715
727
|
'matrix',
|
|
716
728
|
'matrix3d',
|
|
729
|
+
'perspective',
|
|
717
730
|
];
|
|
718
731
|
|
|
719
732
|
const transformsFragmentStrings = /*#__PURE__*/ validTransforms.reduce((a, v) => ({...a, [v]: v + '('}), {});
|
|
@@ -737,6 +750,7 @@
|
|
|
737
750
|
const lowerCaseRgx = /([a-z])([A-Z])/g;
|
|
738
751
|
const transformsExecRgx = /(\w+)(\([^)]+\)+)/g; // Match inline transforms with cacl() values, returns the value wrapped in ()
|
|
739
752
|
const relativeValuesExecRgx = /(\*=|\+=|-=)/;
|
|
753
|
+
const cssVariableMatchRgx = /var\(\s*(--[\w-]+)(?:\s*,\s*([^)]+))?\s*\)/;
|
|
740
754
|
|
|
741
755
|
|
|
742
756
|
|
|
@@ -751,6 +765,7 @@
|
|
|
751
765
|
reversed: false,
|
|
752
766
|
alternate: false,
|
|
753
767
|
autoplay: true,
|
|
768
|
+
persist: false,
|
|
754
769
|
duration: K,
|
|
755
770
|
delay: 0,
|
|
756
771
|
loopDelay: 0,
|
|
@@ -1174,19 +1189,30 @@
|
|
|
1174
1189
|
* @return {any}
|
|
1175
1190
|
*/
|
|
1176
1191
|
const getFunctionValue = (value, target, index, total, store) => {
|
|
1192
|
+
let func;
|
|
1177
1193
|
if (isFnc(value)) {
|
|
1178
|
-
|
|
1194
|
+
func = () => {
|
|
1179
1195
|
const computed = /** @type {Function} */(value)(target, index, total);
|
|
1180
1196
|
// Fallback to 0 if the function returns undefined / NaN / null / false / 0
|
|
1181
1197
|
return !isNaN(+computed) ? +computed : computed || 0;
|
|
1182
1198
|
};
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1199
|
+
} else if (isStr(value) && stringStartsWith(value, cssVarPrefix)) {
|
|
1200
|
+
func = () => {
|
|
1201
|
+
const match = value.match(cssVariableMatchRgx);
|
|
1202
|
+
const cssVarName = match[1];
|
|
1203
|
+
const fallbackValue = match[2];
|
|
1204
|
+
let computed = getComputedStyle(/** @type {HTMLElement} */(target))?.getPropertyValue(cssVarName);
|
|
1205
|
+
// Use fallback if CSS variable is not set or empty
|
|
1206
|
+
if ((!computed || computed.trim() === emptyString) && fallbackValue) {
|
|
1207
|
+
computed = fallbackValue.trim();
|
|
1208
|
+
}
|
|
1209
|
+
return computed || 0;
|
|
1210
|
+
};
|
|
1187
1211
|
} else {
|
|
1188
1212
|
return value;
|
|
1189
1213
|
}
|
|
1214
|
+
if (store) store.func = func;
|
|
1215
|
+
return func();
|
|
1190
1216
|
};
|
|
1191
1217
|
|
|
1192
1218
|
/**
|
|
@@ -1593,7 +1619,9 @@
|
|
|
1593
1619
|
// Handle setters on timeline differently and allow re-trigering the onComplete callback when seeking backwards
|
|
1594
1620
|
if (parent && isSetter) {
|
|
1595
1621
|
if (!muteCallbacks && (
|
|
1596
|
-
(
|
|
1622
|
+
// (tickableAbsoluteTime > 0 instead) of (tickableAbsoluteTime >= duration) to prevent floating point precision issues
|
|
1623
|
+
// see: https://github.com/juliangarnier/anime/issues/1088
|
|
1624
|
+
(parent.began && !isRunningBackwards && tickableAbsoluteTime > 0 && !completed) ||
|
|
1597
1625
|
(isRunningBackwards && tickableAbsoluteTime <= minValue && completed)
|
|
1598
1626
|
)) {
|
|
1599
1627
|
tickable.onComplete(/** @type {CallbackArgument} */(tickable));
|
|
@@ -1695,13 +1723,12 @@
|
|
|
1695
1723
|
}
|
|
1696
1724
|
};
|
|
1697
1725
|
|
|
1698
|
-
const propertyNamesCache = {};
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
1726
|
|
|
1702
1727
|
|
|
1703
1728
|
|
|
1704
1729
|
|
|
1730
|
+
const propertyNamesCache = {};
|
|
1731
|
+
|
|
1705
1732
|
/**
|
|
1706
1733
|
* @param {String} propertyName
|
|
1707
1734
|
* @param {Target} target
|
|
@@ -1748,10 +1775,11 @@
|
|
|
1748
1775
|
const tweenTarget = tween.target;
|
|
1749
1776
|
if (tweenTarget[isDomSymbol]) {
|
|
1750
1777
|
const targetStyle = /** @type {DOMTarget} */(tweenTarget).style;
|
|
1751
|
-
const originalInlinedValue =
|
|
1778
|
+
const originalInlinedValue = tween._inlineValue;
|
|
1779
|
+
const tweenHadNoInlineValue = isNil(originalInlinedValue) || originalInlinedValue === emptyString;
|
|
1752
1780
|
if (tween._tweenType === tweenTypes.TRANSFORM) {
|
|
1753
1781
|
const cachedTransforms = tweenTarget[transformsSymbol];
|
|
1754
|
-
if (
|
|
1782
|
+
if (tweenHadNoInlineValue) {
|
|
1755
1783
|
delete cachedTransforms[tweenProperty];
|
|
1756
1784
|
} else {
|
|
1757
1785
|
cachedTransforms[tweenProperty] = originalInlinedValue;
|
|
@@ -1768,8 +1796,8 @@
|
|
|
1768
1796
|
}
|
|
1769
1797
|
}
|
|
1770
1798
|
} else {
|
|
1771
|
-
if (
|
|
1772
|
-
targetStyle.removeProperty(tweenProperty);
|
|
1799
|
+
if (tweenHadNoInlineValue) {
|
|
1800
|
+
targetStyle.removeProperty(toLowerCase(tweenProperty));
|
|
1773
1801
|
} else {
|
|
1774
1802
|
targetStyle[tweenProperty] = originalInlinedValue;
|
|
1775
1803
|
}
|
|
@@ -3054,6 +3082,7 @@
|
|
|
3054
3082
|
|
|
3055
3083
|
|
|
3056
3084
|
|
|
3085
|
+
|
|
3057
3086
|
/** @type {PowerEasing} */
|
|
3058
3087
|
const easeInPower = (p = 1.68) => t => pow(t, +p);
|
|
3059
3088
|
|
|
@@ -3071,154 +3100,6 @@
|
|
|
3071
3100
|
outIn: easeIn => t => t < .5 ? (1 - easeIn(1 - t * 2)) / 2 : (easeIn(t * 2 - 1) + 1) / 2,
|
|
3072
3101
|
};
|
|
3073
3102
|
|
|
3074
|
-
/**
|
|
3075
|
-
* @param {String} string
|
|
3076
|
-
* @param {Record<String, EasingFunctionWithParams|EasingFunction>} easesFunctions
|
|
3077
|
-
* @param {Object} easesLookups
|
|
3078
|
-
* @return {EasingFunction}
|
|
3079
|
-
*/
|
|
3080
|
-
const parseEaseString = (string, easesFunctions, easesLookups) => {
|
|
3081
|
-
if (easesLookups[string]) return easesLookups[string];
|
|
3082
|
-
if (string.indexOf('(') <= -1) {
|
|
3083
|
-
const hasParams = easeTypes[string] || string.includes('Back') || string.includes('Elastic');
|
|
3084
|
-
const parsedFn = /** @type {EasingFunction} */(hasParams ? /** @type {EasingFunctionWithParams} */(easesFunctions[string])() : easesFunctions[string]);
|
|
3085
|
-
return parsedFn ? easesLookups[string] = parsedFn : none;
|
|
3086
|
-
} else {
|
|
3087
|
-
const split = string.slice(0, -1).split('(');
|
|
3088
|
-
const parsedFn = /** @type {EasingFunctionWithParams} */(easesFunctions[split[0]]);
|
|
3089
|
-
return parsedFn ? easesLookups[string] = parsedFn(...split[1].split(',')) : none;
|
|
3090
|
-
}
|
|
3091
|
-
};
|
|
3092
|
-
|
|
3093
|
-
|
|
3094
|
-
|
|
3095
|
-
/**
|
|
3096
|
-
* Cubic Bezier solver adapted from https://github.com/gre/bezier-easing
|
|
3097
|
-
* (c) 2014 Gaëtan Renaudeau
|
|
3098
|
-
*/
|
|
3099
|
-
|
|
3100
|
-
/**
|
|
3101
|
-
* @param {Number} aT
|
|
3102
|
-
* @param {Number} aA1
|
|
3103
|
-
* @param {Number} aA2
|
|
3104
|
-
* @return {Number}
|
|
3105
|
-
*/
|
|
3106
|
-
const calcBezier = (aT, aA1, aA2) => (((1 - 3 * aA2 + 3 * aA1) * aT + (3 * aA2 - 6 * aA1)) * aT + (3 * aA1)) * aT;
|
|
3107
|
-
|
|
3108
|
-
/**
|
|
3109
|
-
* @param {Number} aX
|
|
3110
|
-
* @param {Number} mX1
|
|
3111
|
-
* @param {Number} mX2
|
|
3112
|
-
* @return {Number}
|
|
3113
|
-
*/
|
|
3114
|
-
const binarySubdivide = (aX, mX1, mX2) => {
|
|
3115
|
-
let aA = 0, aB = 1, currentX, currentT, i = 0;
|
|
3116
|
-
do {
|
|
3117
|
-
currentT = aA + (aB - aA) / 2;
|
|
3118
|
-
currentX = calcBezier(currentT, mX1, mX2) - aX;
|
|
3119
|
-
if (currentX > 0) {
|
|
3120
|
-
aB = currentT;
|
|
3121
|
-
} else {
|
|
3122
|
-
aA = currentT;
|
|
3123
|
-
}
|
|
3124
|
-
} while (abs(currentX) > .0000001 && ++i < 100);
|
|
3125
|
-
return currentT;
|
|
3126
|
-
};
|
|
3127
|
-
|
|
3128
|
-
/**
|
|
3129
|
-
* @param {Number} [mX1] The x coordinate of the first point
|
|
3130
|
-
* @param {Number} [mY1] The y coordinate of the first point
|
|
3131
|
-
* @param {Number} [mX2] The x coordinate of the second point
|
|
3132
|
-
* @param {Number} [mY2] The y coordinate of the second point
|
|
3133
|
-
* @return {EasingFunction}
|
|
3134
|
-
*/
|
|
3135
|
-
|
|
3136
|
-
const cubicBezier = (mX1 = 0.5, mY1 = 0.0, mX2 = 0.5, mY2 = 1.0) => (mX1 === mY1 && mX2 === mY2) ? none :
|
|
3137
|
-
t => t === 0 || t === 1 ? t :
|
|
3138
|
-
calcBezier(binarySubdivide(t, mX1, mX2), mY1, mY2);
|
|
3139
|
-
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
/**
|
|
3143
|
-
* Steps ease implementation https://developer.mozilla.org/fr/docs/Web/CSS/transition-timing-function
|
|
3144
|
-
* Only covers 'end' and 'start' jumpterms
|
|
3145
|
-
* @param {Number} steps
|
|
3146
|
-
* @param {Boolean} [fromStart]
|
|
3147
|
-
* @return {EasingFunction}
|
|
3148
|
-
*/
|
|
3149
|
-
const steps = (steps = 10, fromStart) => {
|
|
3150
|
-
const roundMethod = fromStart ? ceil : floor;
|
|
3151
|
-
return t => roundMethod(clamp$1(t, 0, 1) * steps) * (1 / steps);
|
|
3152
|
-
};
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
/**
|
|
3157
|
-
* Without parameters, the linear function creates a non-eased transition.
|
|
3158
|
-
* Parameters, if used, creates a piecewise linear easing by interpolating linearly between the specified points.
|
|
3159
|
-
*
|
|
3160
|
-
* @param {...(String|Number)} args - Points
|
|
3161
|
-
* @return {EasingFunction}
|
|
3162
|
-
*/
|
|
3163
|
-
const linear = (...args) => {
|
|
3164
|
-
const argsLength = args.length;
|
|
3165
|
-
if (!argsLength) return none;
|
|
3166
|
-
const totalPoints = argsLength - 1;
|
|
3167
|
-
const firstArg = args[0];
|
|
3168
|
-
const lastArg = args[totalPoints];
|
|
3169
|
-
const xPoints = [0];
|
|
3170
|
-
const yPoints = [parseNumber(firstArg)];
|
|
3171
|
-
for (let i = 1; i < totalPoints; i++) {
|
|
3172
|
-
const arg = args[i];
|
|
3173
|
-
const splitValue = isStr(arg) ?
|
|
3174
|
-
/** @type {String} */(arg).trim().split(' ') :
|
|
3175
|
-
[arg];
|
|
3176
|
-
const value = splitValue[0];
|
|
3177
|
-
const percent = splitValue[1];
|
|
3178
|
-
xPoints.push(!isUnd(percent) ? parseNumber(percent) / 100 : i / totalPoints);
|
|
3179
|
-
yPoints.push(parseNumber(value));
|
|
3180
|
-
}
|
|
3181
|
-
yPoints.push(parseNumber(lastArg));
|
|
3182
|
-
xPoints.push(1);
|
|
3183
|
-
return function easeLinear(t) {
|
|
3184
|
-
for (let i = 1, l = xPoints.length; i < l; i++) {
|
|
3185
|
-
const currentX = xPoints[i];
|
|
3186
|
-
if (t <= currentX) {
|
|
3187
|
-
const prevX = xPoints[i - 1];
|
|
3188
|
-
const prevY = yPoints[i - 1];
|
|
3189
|
-
return prevY + (yPoints[i] - prevY) * (t - prevX) / (currentX - prevX);
|
|
3190
|
-
}
|
|
3191
|
-
}
|
|
3192
|
-
return yPoints[yPoints.length - 1];
|
|
3193
|
-
}
|
|
3194
|
-
};
|
|
3195
|
-
|
|
3196
|
-
|
|
3197
|
-
|
|
3198
|
-
/**
|
|
3199
|
-
* Generate random steps
|
|
3200
|
-
* @param {Number} [length] - The number of steps
|
|
3201
|
-
* @param {Number} [randomness] - How strong the randomness is
|
|
3202
|
-
* @return {EasingFunction}
|
|
3203
|
-
*/
|
|
3204
|
-
const irregular = (length = 10, randomness = 1) => {
|
|
3205
|
-
const values = [0];
|
|
3206
|
-
const total = length - 1;
|
|
3207
|
-
for (let i = 1; i < total; i++) {
|
|
3208
|
-
const previousValue = values[i - 1];
|
|
3209
|
-
const spacing = i / total;
|
|
3210
|
-
const segmentEnd = (i + 1) / total;
|
|
3211
|
-
const randomVariation = spacing + (segmentEnd - spacing) * Math.random();
|
|
3212
|
-
// Mix the even spacing and random variation based on the randomness parameter
|
|
3213
|
-
const randomValue = spacing * (1 - randomness) + randomVariation * randomness;
|
|
3214
|
-
values.push(clamp$1(randomValue, previousValue, 1));
|
|
3215
|
-
}
|
|
3216
|
-
values.push(1);
|
|
3217
|
-
return linear(...values);
|
|
3218
|
-
};
|
|
3219
|
-
|
|
3220
|
-
|
|
3221
|
-
|
|
3222
3103
|
/**
|
|
3223
3104
|
* Easing functions adapted and simplified from https://robertpenner.com/easing/
|
|
3224
3105
|
* (c) 2001 Robert Penner
|
|
@@ -3247,7 +3128,7 @@
|
|
|
3247
3128
|
return 1 / pow(4, 3 - b) - 7.5625 * pow((pow2 * 3 - 2) / 22 - t, 2);
|
|
3248
3129
|
},
|
|
3249
3130
|
/** @type {BackEasing} */
|
|
3250
|
-
Back: (overshoot = 1.
|
|
3131
|
+
Back: (overshoot = 1.7) => t => (+overshoot + 1) * t * t * t - +overshoot * t * t,
|
|
3251
3132
|
/** @type {ElasticEasing} */
|
|
3252
3133
|
Elastic: (amplitude = 1, period = .3) => {
|
|
3253
3134
|
const a = clamp$1(+amplitude, 1, 10);
|
|
@@ -3260,10 +3141,8 @@
|
|
|
3260
3141
|
|
|
3261
3142
|
/**
|
|
3262
3143
|
* @typedef {Object} EasesFunctions
|
|
3263
|
-
* @property {typeof
|
|
3264
|
-
* @property {typeof
|
|
3265
|
-
* @property {typeof steps} steps
|
|
3266
|
-
* @property {typeof cubicBezier} cubicBezier
|
|
3144
|
+
* @property {typeof none} linear
|
|
3145
|
+
* @property {typeof none} none
|
|
3267
3146
|
* @property {PowerEasing} in
|
|
3268
3147
|
* @property {PowerEasing} out
|
|
3269
3148
|
* @property {PowerEasing} inOut
|
|
@@ -3311,7 +3190,7 @@
|
|
|
3311
3190
|
*/
|
|
3312
3191
|
|
|
3313
3192
|
const eases = (/*#__PURE__ */ (() => {
|
|
3314
|
-
const list = { linear
|
|
3193
|
+
const list = { linear: none, none: none };
|
|
3315
3194
|
for (let type in easeTypes) {
|
|
3316
3195
|
for (let name in easeInFunctions) {
|
|
3317
3196
|
const easeIn = easeInFunctions[name];
|
|
@@ -3327,15 +3206,43 @@
|
|
|
3327
3206
|
})());
|
|
3328
3207
|
|
|
3329
3208
|
/** @type {Record<String, EasingFunction>} */
|
|
3330
|
-
const
|
|
3209
|
+
const easesLookups = { linear: none, none: none };
|
|
3210
|
+
|
|
3211
|
+
/**
|
|
3212
|
+
* @param {String} string
|
|
3213
|
+
* @return {EasingFunction}
|
|
3214
|
+
*/
|
|
3215
|
+
const parseEaseString = (string) => {
|
|
3216
|
+
if (easesLookups[string]) return easesLookups[string];
|
|
3217
|
+
if (string.indexOf('(') <= -1) {
|
|
3218
|
+
const hasParams = easeTypes[string] || string.includes('Back') || string.includes('Elastic');
|
|
3219
|
+
const parsedFn = /** @type {EasingFunction} */(hasParams ? /** @type {EasingFunctionWithParams} */(eases[string])() : eases[string]);
|
|
3220
|
+
return parsedFn ? easesLookups[string] = parsedFn : none;
|
|
3221
|
+
} else {
|
|
3222
|
+
const split = string.slice(0, -1).split('(');
|
|
3223
|
+
const parsedFn = /** @type {EasingFunctionWithParams} */(eases[split[0]]);
|
|
3224
|
+
return parsedFn ? easesLookups[string] = parsedFn(...split[1].split(',')) : none;
|
|
3225
|
+
}
|
|
3226
|
+
};
|
|
3227
|
+
|
|
3228
|
+
const deprecated = ['steps(', 'irregular(', 'linear(', 'cubicBezier('];
|
|
3331
3229
|
|
|
3332
3230
|
/**
|
|
3333
3231
|
* @param {EasingParam} ease
|
|
3334
3232
|
* @return {EasingFunction}
|
|
3335
3233
|
*/
|
|
3336
|
-
const parseEase = ease =>
|
|
3337
|
-
|
|
3338
|
-
|
|
3234
|
+
const parseEase = ease => {
|
|
3235
|
+
if (isStr(ease)) {
|
|
3236
|
+
for (let i = 0, l = deprecated.length; i < l; i++) {
|
|
3237
|
+
if (stringStartsWith(ease, deprecated[i])) {
|
|
3238
|
+
console.warn(`String syntax for \`ease: "${ease}"\` has been removed from the core and replaced by importing and passing the easing function directly: \`ease: ${ease}\``);
|
|
3239
|
+
return none;
|
|
3240
|
+
}
|
|
3241
|
+
}
|
|
3242
|
+
}
|
|
3243
|
+
const easeFunc = isFnc(ease) ? ease : isStr(ease) ? parseEaseString(/** @type {String} */(ease)) : none;
|
|
3244
|
+
return easeFunc;
|
|
3245
|
+
};
|
|
3339
3246
|
|
|
3340
3247
|
|
|
3341
3248
|
|
|
@@ -3343,6 +3250,7 @@
|
|
|
3343
3250
|
// TODO: Maybe move the objects creation to values.js and use the decompose function to create the base object
|
|
3344
3251
|
const fromTargetObject = createDecomposedValueTargetObject();
|
|
3345
3252
|
const toTargetObject = createDecomposedValueTargetObject();
|
|
3253
|
+
const inlineStylesStore = {};
|
|
3346
3254
|
const toFunctionStore = { func: null };
|
|
3347
3255
|
const keyframesTargetArray = [null];
|
|
3348
3256
|
const fastSetValuesArray = [null, null];
|
|
@@ -3487,15 +3395,15 @@
|
|
|
3487
3395
|
const animEase = animaPlaybackEase ? parseEase(animaPlaybackEase) : null;
|
|
3488
3396
|
const hasSpring = !isUnd(ease) && !isUnd(/** @type {Spring} */(ease).ease);
|
|
3489
3397
|
const tEasing = hasSpring ? /** @type {Spring} */(ease).ease : setValue(ease, animEase ? 'linear' : animDefaults.ease);
|
|
3490
|
-
const tDuration = hasSpring ? /** @type {Spring} */(ease).
|
|
3398
|
+
const tDuration = hasSpring ? /** @type {Spring} */(ease).settlingDuration : setValue(duration, animDefaults.duration);
|
|
3491
3399
|
const tDelay = setValue(delay, animDefaults.delay);
|
|
3492
3400
|
const tModifier = modifier || animDefaults.modifier;
|
|
3493
3401
|
// If no composition is defined and the targets length is high (>= 1000) set the composition to 'none' (0) for faster tween creation
|
|
3494
3402
|
const tComposition = isUnd(composition) && targetsLength >= K ? compositionTypes.none : !isUnd(composition) ? composition : animDefaults.composition;
|
|
3495
|
-
// TODO: Do not create an empty object until we know the animation will generate inline styles
|
|
3496
|
-
const animInlineStyles = {};
|
|
3497
3403
|
// const absoluteOffsetTime = this._offset;
|
|
3498
3404
|
const absoluteOffsetTime = this._offset + (parent ? parent._offset : 0);
|
|
3405
|
+
// This allows targeting the current animation in the spring onComplete callback
|
|
3406
|
+
if (hasSpring) /** @type {Spring} */(ease).parent = this;
|
|
3499
3407
|
|
|
3500
3408
|
let iterationDuration = NaN;
|
|
3501
3409
|
let iterationDelay = NaN;
|
|
@@ -3597,7 +3505,7 @@
|
|
|
3597
3505
|
// Easing are treated differently and don't accept function based value to prevent having to pass a function wrapper that returns an other function all the time
|
|
3598
3506
|
const tweenEasing = hasSpring ? /** @type {Spring} */(keyEasing).ease : keyEasing || tEasing;
|
|
3599
3507
|
// Calculate default individual keyframe duration by dividing the tl of keyframes
|
|
3600
|
-
const tweenDuration = hasSpring ? /** @type {Spring} */(keyEasing).
|
|
3508
|
+
const tweenDuration = hasSpring ? /** @type {Spring} */(keyEasing).settlingDuration : getFunctionValue(setValue(key.duration, (l > 1 ? getFunctionValue(tDuration, target, ti, tl) / l : tDuration)), target, ti, tl);
|
|
3601
3509
|
// Default delay value should only be applied to the first tween
|
|
3602
3510
|
const tweenDelay = getFunctionValue(setValue(key.delay, (!tweenIndex ? tDelay : 0)), target, ti, tl);
|
|
3603
3511
|
const computedComposition = getFunctionValue(setValue(key.composition, tComposition), target, ti, tl);
|
|
@@ -3647,7 +3555,7 @@
|
|
|
3647
3555
|
}
|
|
3648
3556
|
} else {
|
|
3649
3557
|
decomposeRawValue(
|
|
3650
|
-
getOriginalAnimatableValue(target, propName, tweenType,
|
|
3558
|
+
getOriginalAnimatableValue(target, propName, tweenType, inlineStylesStore),
|
|
3651
3559
|
decomposedOriginalValue
|
|
3652
3560
|
);
|
|
3653
3561
|
if (decomposedOriginalValue.t === valueTypes.UNIT) {
|
|
@@ -3665,7 +3573,7 @@
|
|
|
3665
3573
|
} else {
|
|
3666
3574
|
// No need to get and parse the original value if the tween is part of a timeline and has a previous sibling part of the same timeline
|
|
3667
3575
|
decomposeRawValue(parent && prevSibling && prevSibling.parent.parent === parent ? prevSibling._value :
|
|
3668
|
-
getOriginalAnimatableValue(target, propName, tweenType,
|
|
3576
|
+
getOriginalAnimatableValue(target, propName, tweenType, inlineStylesStore), toTargetObject);
|
|
3669
3577
|
}
|
|
3670
3578
|
}
|
|
3671
3579
|
if (hasFromvalue) {
|
|
@@ -3676,7 +3584,7 @@
|
|
|
3676
3584
|
} else {
|
|
3677
3585
|
decomposeRawValue(parent && prevSibling && prevSibling.parent.parent === parent ? prevSibling._value :
|
|
3678
3586
|
// No need to get and parse the original value if the tween is part of a timeline and has a previous sibling part of the same timeline
|
|
3679
|
-
getOriginalAnimatableValue(target, propName, tweenType,
|
|
3587
|
+
getOriginalAnimatableValue(target, propName, tweenType, inlineStylesStore), fromTargetObject);
|
|
3680
3588
|
}
|
|
3681
3589
|
}
|
|
3682
3590
|
}
|
|
@@ -3685,7 +3593,7 @@
|
|
|
3685
3593
|
if (fromTargetObject.o) {
|
|
3686
3594
|
fromTargetObject.n = getRelativeValue(
|
|
3687
3595
|
!prevSibling ? decomposeRawValue(
|
|
3688
|
-
getOriginalAnimatableValue(target, propName, tweenType,
|
|
3596
|
+
getOriginalAnimatableValue(target, propName, tweenType, inlineStylesStore),
|
|
3689
3597
|
decomposedOriginalValue
|
|
3690
3598
|
).n : prevSibling._toNumber,
|
|
3691
3599
|
fromTargetObject.n,
|
|
@@ -3741,6 +3649,10 @@
|
|
|
3741
3649
|
// Rounding is necessary here to minimize floating point errors when working in seconds
|
|
3742
3650
|
const tweenUpdateDuration = round$1(+tweenDuration || minValue, 12);
|
|
3743
3651
|
|
|
3652
|
+
// Copy the value of the iniline style if it exist and imediatly nullify it to prevents false positive on other targets
|
|
3653
|
+
let inlineValue = inlineStylesStore[propName];
|
|
3654
|
+
if (!isNil(inlineValue)) inlineStylesStore[propName] = null;
|
|
3655
|
+
|
|
3744
3656
|
/** @type {Tween} */
|
|
3745
3657
|
const tween = {
|
|
3746
3658
|
parent: this,
|
|
@@ -3772,6 +3684,7 @@
|
|
|
3772
3684
|
_isOverlapped: 0,
|
|
3773
3685
|
_isOverridden: 0,
|
|
3774
3686
|
_renderTransforms: 0,
|
|
3687
|
+
_inlineValue: inlineValue,
|
|
3775
3688
|
_prevRep: null, // For replaced tween
|
|
3776
3689
|
_nextRep: null, // For replaced tween
|
|
3777
3690
|
_prevAdd: null, // For additive tween
|
|
@@ -3874,8 +3787,6 @@
|
|
|
3874
3787
|
// this._offset += parent ? iterationDelay : 0;
|
|
3875
3788
|
/** @type {Number} */
|
|
3876
3789
|
this.iterationDuration = iterationDuration;
|
|
3877
|
-
/** @type {{}} */
|
|
3878
|
-
this._inlineStyles = animInlineStyles;
|
|
3879
3790
|
|
|
3880
3791
|
if (!this._autoplay && shouldTriggerRender) this.onRender(this);
|
|
3881
3792
|
}
|
|
@@ -3909,6 +3820,7 @@
|
|
|
3909
3820
|
if (tweenFunc) {
|
|
3910
3821
|
const ogValue = getOriginalAnimatableValue(tween.target, tween.property, tween._tweenType);
|
|
3911
3822
|
decomposeRawValue(ogValue, decomposedOriginalValue);
|
|
3823
|
+
// TODO: Check for from / to Array based values here,
|
|
3912
3824
|
decomposeRawValue(tweenFunc(), toTargetObject);
|
|
3913
3825
|
tween._fromNumbers = cloneArray(decomposedOriginalValue.d);
|
|
3914
3826
|
tween._fromNumber = decomposedOriginalValue.n;
|
|
@@ -3918,6 +3830,8 @@
|
|
|
3918
3830
|
tween._toNumber = toTargetObject.o ? getRelativeValue(decomposedOriginalValue.n, toTargetObject.n, toTargetObject.o) : toTargetObject.n;
|
|
3919
3831
|
}
|
|
3920
3832
|
});
|
|
3833
|
+
// This forces setter animations to render once
|
|
3834
|
+
if (this.duration === minValue) this.restart();
|
|
3921
3835
|
return this;
|
|
3922
3836
|
}
|
|
3923
3837
|
|
|
@@ -3960,16 +3874,18 @@
|
|
|
3960
3874
|
* @param {DOMTarget} $el
|
|
3961
3875
|
* @param {String} [property]
|
|
3962
3876
|
* @param {WAAPIAnimation} [parent]
|
|
3877
|
+
* @return {globalThis.Animation}
|
|
3963
3878
|
*/
|
|
3964
3879
|
const removeWAAPIAnimation = ($el, property, parent) => {
|
|
3965
3880
|
let nextLookup = WAAPIAnimationsLookups._head;
|
|
3881
|
+
let anim;
|
|
3966
3882
|
while (nextLookup) {
|
|
3967
3883
|
const next = nextLookup._next;
|
|
3968
3884
|
const matchTarget = nextLookup.$el === $el;
|
|
3969
3885
|
const matchProperty = !property || nextLookup.property === property;
|
|
3970
3886
|
const matchParent = !parent || nextLookup.parent === parent;
|
|
3971
3887
|
if (matchTarget && matchProperty && matchParent) {
|
|
3972
|
-
|
|
3888
|
+
anim = nextLookup.animation;
|
|
3973
3889
|
try { anim.commitStyles(); } catch {} anim.cancel();
|
|
3974
3890
|
removeChild(WAAPIAnimationsLookups, nextLookup);
|
|
3975
3891
|
const lookupParent = nextLookup.parent;
|
|
@@ -3977,8 +3893,8 @@
|
|
|
3977
3893
|
lookupParent._completed++;
|
|
3978
3894
|
if (lookupParent.animations.length === lookupParent._completed) {
|
|
3979
3895
|
lookupParent.completed = true;
|
|
3896
|
+
lookupParent.paused = true;
|
|
3980
3897
|
if (!lookupParent.muteCallbacks) {
|
|
3981
|
-
lookupParent.paused = true;
|
|
3982
3898
|
lookupParent.onComplete(lookupParent);
|
|
3983
3899
|
lookupParent._resolve(lookupParent);
|
|
3984
3900
|
}
|
|
@@ -3987,6 +3903,7 @@
|
|
|
3987
3903
|
}
|
|
3988
3904
|
nextLookup = next;
|
|
3989
3905
|
}
|
|
3906
|
+
return anim;
|
|
3990
3907
|
};
|
|
3991
3908
|
|
|
3992
3909
|
/**
|
|
@@ -3995,7 +3912,7 @@
|
|
|
3995
3912
|
* @param {String} property
|
|
3996
3913
|
* @param {PropertyIndexedKeyframes} keyframes
|
|
3997
3914
|
* @param {KeyframeAnimationOptions} params
|
|
3998
|
-
* @retun {Animation}
|
|
3915
|
+
* @retun {globalThis.Animation}
|
|
3999
3916
|
*/
|
|
4000
3917
|
const addWAAPIAnimation = (parent, $el, property, keyframes, params) => {
|
|
4001
3918
|
const animation = $el.animate(keyframes, params);
|
|
@@ -4010,8 +3927,11 @@
|
|
|
4010
3927
|
removeWAAPIAnimation($el, property);
|
|
4011
3928
|
addChild(WAAPIAnimationsLookups, { parent, animation, $el, property, _next: null, _prev: null });
|
|
4012
3929
|
const handleRemove = () => { removeWAAPIAnimation($el, property, parent); };
|
|
3930
|
+
animation.oncancel = handleRemove;
|
|
4013
3931
|
animation.onremove = handleRemove;
|
|
4014
|
-
|
|
3932
|
+
if (!parent.persist) {
|
|
3933
|
+
animation.onfinish = handleRemove;
|
|
3934
|
+
}
|
|
4015
3935
|
return animation;
|
|
4016
3936
|
};
|
|
4017
3937
|
|
|
@@ -4639,8 +4559,10 @@
|
|
|
4639
4559
|
|
|
4640
4560
|
|
|
4641
4561
|
|
|
4562
|
+
|
|
4563
|
+
|
|
4642
4564
|
/*
|
|
4643
|
-
* Spring
|
|
4565
|
+
* Spring easing solver adapted from https://webkit.org/demos/spring/spring.js
|
|
4644
4566
|
* (c) 2016 Webkit - Apple Inc
|
|
4645
4567
|
*/
|
|
4646
4568
|
|
|
@@ -4651,25 +4573,46 @@
|
|
|
4651
4573
|
* @param {SpringParams} [parameters]
|
|
4652
4574
|
*/
|
|
4653
4575
|
constructor(parameters = {}) {
|
|
4576
|
+
const hasBounceOrDuration = !isUnd(parameters.bounce) || !isUnd(parameters.duration);
|
|
4654
4577
|
this.timeStep = .02; // Interval fed to the solver to calculate duration
|
|
4655
4578
|
this.restThreshold = .0005; // Values below this threshold are considered resting position
|
|
4656
4579
|
this.restDuration = 200; // Duration in ms used to check if the spring is resting after reaching restThreshold
|
|
4657
4580
|
this.maxDuration = 60000; // The maximum allowed spring duration in ms (default 1 min)
|
|
4658
4581
|
this.maxRestSteps = this.restDuration / this.timeStep / K; // How many steps allowed after reaching restThreshold before stopping the duration calculation
|
|
4659
4582
|
this.maxIterations = this.maxDuration / this.timeStep / K; // Calculate the maximum iterations allowed based on maxDuration
|
|
4660
|
-
this.
|
|
4661
|
-
this.
|
|
4662
|
-
this.
|
|
4583
|
+
this.bn = clamp$1(setValue(parameters.bounce, .5), -1, 1); // The bounce percentage between -1 and 1.
|
|
4584
|
+
this.pd = clamp$1(setValue(parameters.duration, 628), 10 * globals.timeScale, maxSpringParamValue * globals.timeScale); // The perceived duration
|
|
4585
|
+
this.m = clamp$1(setValue(parameters.mass, 1), 1, maxSpringParamValue);
|
|
4586
|
+
this.s = clamp$1(setValue(parameters.stiffness, 100), minValue, maxSpringParamValue);
|
|
4587
|
+
this.d = clamp$1(setValue(parameters.damping, 10), minValue, maxSpringParamValue);
|
|
4663
4588
|
this.v = clamp$1(setValue(parameters.velocity, 0), -maxSpringParamValue, maxSpringParamValue);
|
|
4664
4589
|
this.w0 = 0;
|
|
4665
4590
|
this.zeta = 0;
|
|
4666
4591
|
this.wd = 0;
|
|
4667
4592
|
this.b = 0;
|
|
4593
|
+
this.completed = false;
|
|
4668
4594
|
this.solverDuration = 0;
|
|
4669
|
-
this.
|
|
4595
|
+
this.settlingDuration = 0;
|
|
4596
|
+
/** @type {JSAnimation} */
|
|
4597
|
+
this.parent = null;
|
|
4598
|
+
/** @type {Callback<JSAnimation>} */
|
|
4599
|
+
this.onComplete = parameters.onComplete || noop;
|
|
4600
|
+
if (hasBounceOrDuration) this.calculateSDFromBD();
|
|
4670
4601
|
this.compute();
|
|
4671
4602
|
/** @type {EasingFunction} */
|
|
4672
|
-
this.ease = t =>
|
|
4603
|
+
this.ease = t => {
|
|
4604
|
+
const currentTime = t * this.settlingDuration;
|
|
4605
|
+
const completed = this.completed;
|
|
4606
|
+
const perceivedTime = this.pd;
|
|
4607
|
+
if (currentTime >= perceivedTime && !completed) {
|
|
4608
|
+
this.completed = true;
|
|
4609
|
+
this.onComplete(this.parent);
|
|
4610
|
+
}
|
|
4611
|
+
if (currentTime < perceivedTime && completed) {
|
|
4612
|
+
this.completed = false;
|
|
4613
|
+
}
|
|
4614
|
+
return t === 0 || t === 1 ? t : this.solve(t * this.solverDuration);
|
|
4615
|
+
};
|
|
4673
4616
|
}
|
|
4674
4617
|
|
|
4675
4618
|
/** @type {EasingFunction} */
|
|
@@ -4677,23 +4620,83 @@
|
|
|
4677
4620
|
const { zeta, w0, wd, b } = this;
|
|
4678
4621
|
let t = time;
|
|
4679
4622
|
if (zeta < 1) {
|
|
4623
|
+
// Underdamped
|
|
4680
4624
|
t = exp(-t * zeta * w0) * (1 * cos(wd * t) + b * sin(wd * t));
|
|
4681
|
-
} else {
|
|
4625
|
+
} else if (zeta === 1) {
|
|
4626
|
+
// Critically damped
|
|
4682
4627
|
t = (1 + b * t) * exp(-t * w0);
|
|
4628
|
+
} else {
|
|
4629
|
+
// Overdamped
|
|
4630
|
+
// Using exponential instead of cosh and sinh functions to prevent Infinity
|
|
4631
|
+
// Original exp(-zeta * w0 * t) * (cosh(wd * t) + b * sinh(wd * t))
|
|
4632
|
+
t = ((1 + b) * exp((-zeta * w0 + wd) * t) + (1 - b) * exp((-zeta * w0 - wd) * t)) / 2;
|
|
4683
4633
|
}
|
|
4684
4634
|
return 1 - t;
|
|
4685
4635
|
}
|
|
4686
4636
|
|
|
4637
|
+
calculateSDFromBD() {
|
|
4638
|
+
// Apple's SwiftUI perceived spring duration implementation https://developer.apple.com/videos/play/wwdc2023/10158/?time=1010
|
|
4639
|
+
// Equations taken from Kevin Grajeda's article https://www.kvin.me/posts/effortless-ui-spring-animations
|
|
4640
|
+
const pds = globals.timeScale === 1 ? this.pd / K : this.pd;
|
|
4641
|
+
// Mass and velocity should be set to their default values
|
|
4642
|
+
this.m = 1;
|
|
4643
|
+
this.v = 0;
|
|
4644
|
+
// Stiffness = (2π ÷ perceptualDuration)²
|
|
4645
|
+
this.s = pow((2 * PI) / pds, 2);
|
|
4646
|
+
if (this.bn >= 0) {
|
|
4647
|
+
// For bounce ≥ 0 (critically damped to underdamped)
|
|
4648
|
+
// damping = ((1 - bounce) × 4π) ÷ perceptualDuration
|
|
4649
|
+
this.d = ((1 - this.bn) * 4 * PI) / pds;
|
|
4650
|
+
} else {
|
|
4651
|
+
// For bounce < 0 (overdamped)
|
|
4652
|
+
// damping = 4π ÷ (perceptualDuration × (1 + bounce))
|
|
4653
|
+
// Note: (1 + bounce) is positive since bounce is negative
|
|
4654
|
+
this.d = (4 * PI) / (pds * (1 + this.bn));
|
|
4655
|
+
}
|
|
4656
|
+
this.s = round$1(clamp$1(this.s, minValue, maxSpringParamValue), 3);
|
|
4657
|
+
this.d = round$1(clamp$1(this.d, minValue, 300), 3); // Clamping to 300 is needed to prevent insane values in the solver
|
|
4658
|
+
}
|
|
4659
|
+
|
|
4660
|
+
calculateBDFromSD() {
|
|
4661
|
+
// Calculate perceived duration and bounce from stiffness and damping
|
|
4662
|
+
// Note: We assumes m = 1 and v = 0 for these calculations
|
|
4663
|
+
const pds = (2 * PI) / sqrt(this.s);
|
|
4664
|
+
this.pd = pds * (globals.timeScale === 1 ? K : 1);
|
|
4665
|
+
const zeta = this.d / (2 * sqrt(this.s));
|
|
4666
|
+
if (zeta <= 1) {
|
|
4667
|
+
// Critically damped to underdamped
|
|
4668
|
+
this.bn = 1 - (this.d * pds) / (4 * PI);
|
|
4669
|
+
} else {
|
|
4670
|
+
// Overdamped
|
|
4671
|
+
this.bn = (4 * PI) / (this.d * pds) - 1;
|
|
4672
|
+
}
|
|
4673
|
+
this.bn = round$1(clamp$1(this.bn, -1, 1), 3);
|
|
4674
|
+
this.pd = round$1(clamp$1(this.pd, 10 * globals.timeScale, maxSpringParamValue * globals.timeScale), 3);
|
|
4675
|
+
}
|
|
4676
|
+
|
|
4687
4677
|
compute() {
|
|
4688
4678
|
const { maxRestSteps, maxIterations, restThreshold, timeStep, m, d, s, v } = this;
|
|
4689
4679
|
const w0 = this.w0 = clamp$1(sqrt(s / m), minValue, K);
|
|
4690
|
-
const
|
|
4691
|
-
|
|
4692
|
-
|
|
4680
|
+
const bouncedZeta = this.zeta = d / (2 * sqrt(s * m));
|
|
4681
|
+
// Calculate wd based on damping type
|
|
4682
|
+
if (bouncedZeta < 1) {
|
|
4683
|
+
// Underdamped
|
|
4684
|
+
this.wd = w0 * sqrt(1 - bouncedZeta * bouncedZeta);
|
|
4685
|
+
this.b = (bouncedZeta * w0 + -v) / this.wd;
|
|
4686
|
+
} else if (bouncedZeta === 1) {
|
|
4687
|
+
// Critically damped
|
|
4688
|
+
this.wd = 0;
|
|
4689
|
+
this.b = -v + w0;
|
|
4690
|
+
} else {
|
|
4691
|
+
// Overdamped
|
|
4692
|
+
this.wd = w0 * sqrt(bouncedZeta * bouncedZeta - 1);
|
|
4693
|
+
this.b = (bouncedZeta * w0 + -v) / this.wd;
|
|
4694
|
+
}
|
|
4695
|
+
|
|
4693
4696
|
let solverTime = 0;
|
|
4694
4697
|
let restSteps = 0;
|
|
4695
4698
|
let iterations = 0;
|
|
4696
|
-
while (restSteps
|
|
4699
|
+
while (restSteps <= maxRestSteps && iterations <= maxIterations) {
|
|
4697
4700
|
if (abs(1 - this.solve(solverTime)) < restThreshold) {
|
|
4698
4701
|
restSteps++;
|
|
4699
4702
|
} else {
|
|
@@ -4703,15 +4706,26 @@
|
|
|
4703
4706
|
solverTime += timeStep;
|
|
4704
4707
|
iterations++;
|
|
4705
4708
|
}
|
|
4706
|
-
this.
|
|
4709
|
+
this.settlingDuration = round$1(this.solverDuration * K, 0) * globals.timeScale;
|
|
4707
4710
|
}
|
|
4708
4711
|
|
|
4709
|
-
get
|
|
4710
|
-
return this.
|
|
4712
|
+
get bounce() {
|
|
4713
|
+
return this.bn;
|
|
4711
4714
|
}
|
|
4712
4715
|
|
|
4713
|
-
set
|
|
4714
|
-
this.
|
|
4716
|
+
set bounce(v) {
|
|
4717
|
+
this.bn = clamp$1(setValue(v, 1), -1, 1);
|
|
4718
|
+
this.calculateSDFromBD();
|
|
4719
|
+
this.compute();
|
|
4720
|
+
}
|
|
4721
|
+
|
|
4722
|
+
get duration() {
|
|
4723
|
+
return this.pd;
|
|
4724
|
+
}
|
|
4725
|
+
|
|
4726
|
+
set duration(v) {
|
|
4727
|
+
this.pd = clamp$1(setValue(v, 1), 10 * globals.timeScale, maxSpringParamValue * globals.timeScale);
|
|
4728
|
+
this.calculateSDFromBD();
|
|
4715
4729
|
this.compute();
|
|
4716
4730
|
}
|
|
4717
4731
|
|
|
@@ -4720,7 +4734,8 @@
|
|
|
4720
4734
|
}
|
|
4721
4735
|
|
|
4722
4736
|
set stiffness(v) {
|
|
4723
|
-
this.s = clamp$1(setValue(v, 100),
|
|
4737
|
+
this.s = clamp$1(setValue(v, 100), minValue, maxSpringParamValue);
|
|
4738
|
+
this.calculateBDFromSD();
|
|
4724
4739
|
this.compute();
|
|
4725
4740
|
}
|
|
4726
4741
|
|
|
@@ -4729,7 +4744,17 @@
|
|
|
4729
4744
|
}
|
|
4730
4745
|
|
|
4731
4746
|
set damping(v) {
|
|
4732
|
-
this.d = clamp$1(setValue(v, 10),
|
|
4747
|
+
this.d = clamp$1(setValue(v, 10), minValue, maxSpringParamValue);
|
|
4748
|
+
this.calculateBDFromSD();
|
|
4749
|
+
this.compute();
|
|
4750
|
+
}
|
|
4751
|
+
|
|
4752
|
+
get mass() {
|
|
4753
|
+
return this.m;
|
|
4754
|
+
}
|
|
4755
|
+
|
|
4756
|
+
set mass(v) {
|
|
4757
|
+
this.m = clamp$1(setValue(v, 1), 1, maxSpringParamValue);
|
|
4733
4758
|
this.compute();
|
|
4734
4759
|
}
|
|
4735
4760
|
|
|
@@ -4747,7 +4772,18 @@
|
|
|
4747
4772
|
* @param {SpringParams} [parameters]
|
|
4748
4773
|
* @returns {Spring}
|
|
4749
4774
|
*/
|
|
4750
|
-
const
|
|
4775
|
+
const spring = (parameters) => new Spring(parameters);
|
|
4776
|
+
|
|
4777
|
+
/**
|
|
4778
|
+
* @deprecated createSpring() is deprecated use spring() instead
|
|
4779
|
+
*
|
|
4780
|
+
* @param {SpringParams} [parameters]
|
|
4781
|
+
* @returns {Spring}
|
|
4782
|
+
*/
|
|
4783
|
+
const createSpring = (parameters) => {
|
|
4784
|
+
console.warn('createSpring() is deprecated use spring() instead');
|
|
4785
|
+
return new Spring(parameters);
|
|
4786
|
+
};
|
|
4751
4787
|
|
|
4752
4788
|
|
|
4753
4789
|
|
|
@@ -4928,13 +4964,13 @@
|
|
|
4928
4964
|
/** @type {Boolean|DraggableCursorParams} */
|
|
4929
4965
|
this.cursor = false;
|
|
4930
4966
|
/** @type {Spring} */
|
|
4931
|
-
this.releaseXSpring = hasSpring ? /** @type {Spring} */(ease) :
|
|
4967
|
+
this.releaseXSpring = hasSpring ? /** @type {Spring} */(ease) : spring({
|
|
4932
4968
|
mass: setValue(parameters.releaseMass, 1),
|
|
4933
4969
|
stiffness: setValue(parameters.releaseStiffness, 80),
|
|
4934
4970
|
damping: setValue(parameters.releaseDamping, 20),
|
|
4935
4971
|
});
|
|
4936
4972
|
/** @type {Spring} */
|
|
4937
|
-
this.releaseYSpring = hasSpring ? /** @type {Spring} */(ease) :
|
|
4973
|
+
this.releaseYSpring = hasSpring ? /** @type {Spring} */(ease) : spring({
|
|
4938
4974
|
mass: setValue(parameters.releaseMass, 1),
|
|
4939
4975
|
stiffness: setValue(parameters.releaseStiffness, 80),
|
|
4940
4976
|
damping: setValue(parameters.releaseDamping, 20),
|
|
@@ -5651,8 +5687,8 @@
|
|
|
5651
5687
|
this.$trigger.addEventListener('touchmove', preventDefault, { passive: false });
|
|
5652
5688
|
this.$trigger.addEventListener('touchend', preventDefault);
|
|
5653
5689
|
|
|
5654
|
-
|
|
5655
|
-
if ((!this.disabled[0] && abs(movedX) > 3) || (!this.disabled[1] && abs(movedY) > 3)) {
|
|
5690
|
+
// Don't check for a miminim distance move if already dragging
|
|
5691
|
+
if (this.dragged || (!this.disabled[0] && abs(movedX) > 3) || (!this.disabled[1] && abs(movedY) > 3)) {
|
|
5656
5692
|
|
|
5657
5693
|
this.updateTicker.resume();
|
|
5658
5694
|
this.pointer[2] = this.pointer[0];
|
|
@@ -5718,8 +5754,8 @@
|
|
|
5718
5754
|
const directionX = dx === cr ? cx > cr ? -1 : 1 : cx < cl ? -1 : 1;
|
|
5719
5755
|
const distanceX = round$1(cx - dx, 0);
|
|
5720
5756
|
springX.velocity = disabledY && hasReleaseSpring ? distanceX ? (ds * directionX) / abs(distanceX) : 0 : pv;
|
|
5721
|
-
const { ease,
|
|
5722
|
-
durationX = cx === dx ? 0 : hasReleaseSpring ?
|
|
5757
|
+
const { ease, settlingDuration, restDuration } = springX;
|
|
5758
|
+
durationX = cx === dx ? 0 : hasReleaseSpring ? settlingDuration : settlingDuration - (restDuration * globals.timeScale);
|
|
5723
5759
|
if (hasReleaseSpring) easeX = ease;
|
|
5724
5760
|
if (durationX > longestReleaseDuration) longestReleaseDuration = durationX;
|
|
5725
5761
|
}
|
|
@@ -5728,8 +5764,8 @@
|
|
|
5728
5764
|
const directionY = dy === cb ? cy > cb ? -1 : 1 : cy < ct ? -1 : 1;
|
|
5729
5765
|
const distanceY = round$1(cy - dy, 0);
|
|
5730
5766
|
springY.velocity = disabledX && hasReleaseSpring ? distanceY ? (ds * directionY) / abs(distanceY) : 0 : pv;
|
|
5731
|
-
const { ease,
|
|
5732
|
-
durationY = cy === dy ? 0 : hasReleaseSpring ?
|
|
5767
|
+
const { ease, settlingDuration, restDuration } = springY;
|
|
5768
|
+
durationY = cy === dy ? 0 : hasReleaseSpring ? settlingDuration : settlingDuration - (restDuration * globals.timeScale);
|
|
5733
5769
|
if (hasReleaseSpring) easeY = ease;
|
|
5734
5770
|
if (durationY > longestReleaseDuration) longestReleaseDuration = durationY;
|
|
5735
5771
|
}
|
|
@@ -6582,6 +6618,8 @@
|
|
|
6582
6618
|
/** @type {Boolean} */
|
|
6583
6619
|
this.reverted = false;
|
|
6584
6620
|
/** @type {Boolean} */
|
|
6621
|
+
this.ready = false;
|
|
6622
|
+
/** @type {Boolean} */
|
|
6585
6623
|
this.completed = false;
|
|
6586
6624
|
/** @type {Boolean} */
|
|
6587
6625
|
this.began = false;
|
|
@@ -6591,8 +6629,6 @@
|
|
|
6591
6629
|
this.forceEnter = false;
|
|
6592
6630
|
/** @type {Boolean} */
|
|
6593
6631
|
this.hasEntered = false;
|
|
6594
|
-
// /** @type {Array.<Number>} */
|
|
6595
|
-
// this.offsets = [];
|
|
6596
6632
|
/** @type {Number} */
|
|
6597
6633
|
this.offset = 0;
|
|
6598
6634
|
/** @type {Number} */
|
|
@@ -6640,6 +6676,8 @@
|
|
|
6640
6676
|
// Make sure to pause the linked object in case it's added later
|
|
6641
6677
|
linked.pause();
|
|
6642
6678
|
this.linked = linked;
|
|
6679
|
+
// Forces WAAPI Animation to persist; otherwise, they will stop syncing on finish.
|
|
6680
|
+
if (!isUnd(/** @type {WAAPIAnimation} */(linked))) /** @type {WAAPIAnimation} */(linked).persist = true;
|
|
6643
6681
|
// Try to use a target of the linked object if no target parameters specified
|
|
6644
6682
|
if (!this._params.target) {
|
|
6645
6683
|
/** @type {HTMLElement} */
|
|
@@ -6679,6 +6717,8 @@
|
|
|
6679
6717
|
}
|
|
6680
6718
|
|
|
6681
6719
|
refresh() {
|
|
6720
|
+
// This flag is used to prevent running handleScroll() outside of this.refresh() with values not yet calculated
|
|
6721
|
+
this.ready = true;
|
|
6682
6722
|
this.reverted = false;
|
|
6683
6723
|
const params = this._params;
|
|
6684
6724
|
this.repeat = setValue(parseScrollObserverFunctionParameter(params.repeat, this), true);
|
|
@@ -6924,8 +6964,6 @@
|
|
|
6924
6964
|
const offsetStart = parsedEnterTarget + offset - parsedEnterContainer;
|
|
6925
6965
|
const offsetEnd = parsedLeaveTarget + offset - parsedLeaveContainer;
|
|
6926
6966
|
const scrollDelta = offsetEnd - offsetStart;
|
|
6927
|
-
// this.offsets[0] = offsetX;
|
|
6928
|
-
// this.offsets[1] = offsetY;
|
|
6929
6967
|
this.offset = offset;
|
|
6930
6968
|
this.offsetStart = offsetStart;
|
|
6931
6969
|
this.offsetEnd = offsetEnd;
|
|
@@ -6944,6 +6982,7 @@
|
|
|
6944
6982
|
}
|
|
6945
6983
|
|
|
6946
6984
|
handleScroll() {
|
|
6985
|
+
if (!this.ready) return;
|
|
6947
6986
|
const linked = this.linked;
|
|
6948
6987
|
const sync = this.sync;
|
|
6949
6988
|
const syncEase = this.syncEase;
|
|
@@ -7067,6 +7106,7 @@
|
|
|
7067
7106
|
this.removeDebug();
|
|
7068
7107
|
}
|
|
7069
7108
|
this.reverted = true;
|
|
7109
|
+
this.ready = false;
|
|
7070
7110
|
return this;
|
|
7071
7111
|
}
|
|
7072
7112
|
|
|
@@ -7078,13 +7118,142 @@
|
|
|
7078
7118
|
*/
|
|
7079
7119
|
const onScroll = (parameters = {}) => new ScrollObserver(parameters);
|
|
7080
7120
|
|
|
7121
|
+
|
|
7122
|
+
|
|
7123
|
+
/**
|
|
7124
|
+
* Cubic Bezier solver adapted from https://github.com/gre/bezier-easing
|
|
7125
|
+
* (c) 2014 Gaëtan Renaudeau
|
|
7126
|
+
*/
|
|
7127
|
+
|
|
7128
|
+
/**
|
|
7129
|
+
* @param {Number} aT
|
|
7130
|
+
* @param {Number} aA1
|
|
7131
|
+
* @param {Number} aA2
|
|
7132
|
+
* @return {Number}
|
|
7133
|
+
*/
|
|
7134
|
+
const calcBezier = (aT, aA1, aA2) => (((1 - 3 * aA2 + 3 * aA1) * aT + (3 * aA2 - 6 * aA1)) * aT + (3 * aA1)) * aT;
|
|
7135
|
+
|
|
7136
|
+
/**
|
|
7137
|
+
* @param {Number} aX
|
|
7138
|
+
* @param {Number} mX1
|
|
7139
|
+
* @param {Number} mX2
|
|
7140
|
+
* @return {Number}
|
|
7141
|
+
*/
|
|
7142
|
+
const binarySubdivide = (aX, mX1, mX2) => {
|
|
7143
|
+
let aA = 0, aB = 1, currentX, currentT, i = 0;
|
|
7144
|
+
do {
|
|
7145
|
+
currentT = aA + (aB - aA) / 2;
|
|
7146
|
+
currentX = calcBezier(currentT, mX1, mX2) - aX;
|
|
7147
|
+
if (currentX > 0) {
|
|
7148
|
+
aB = currentT;
|
|
7149
|
+
} else {
|
|
7150
|
+
aA = currentT;
|
|
7151
|
+
}
|
|
7152
|
+
} while (abs(currentX) > .0000001 && ++i < 100);
|
|
7153
|
+
return currentT;
|
|
7154
|
+
};
|
|
7155
|
+
|
|
7156
|
+
/**
|
|
7157
|
+
* @param {Number} [mX1] The x coordinate of the first point
|
|
7158
|
+
* @param {Number} [mY1] The y coordinate of the first point
|
|
7159
|
+
* @param {Number} [mX2] The x coordinate of the second point
|
|
7160
|
+
* @param {Number} [mY2] The y coordinate of the second point
|
|
7161
|
+
* @return {EasingFunction}
|
|
7162
|
+
*/
|
|
7163
|
+
|
|
7164
|
+
const cubicBezier = (mX1 = 0.5, mY1 = 0.0, mX2 = 0.5, mY2 = 1.0) => (mX1 === mY1 && mX2 === mY2) ? none :
|
|
7165
|
+
t => t === 0 || t === 1 ? t :
|
|
7166
|
+
calcBezier(binarySubdivide(t, mX1, mX2), mY1, mY2);
|
|
7167
|
+
|
|
7168
|
+
|
|
7169
|
+
|
|
7170
|
+
/**
|
|
7171
|
+
* Steps ease implementation https://developer.mozilla.org/fr/docs/Web/CSS/transition-timing-function
|
|
7172
|
+
* Only covers 'end' and 'start' jumpterms
|
|
7173
|
+
* @param {Number} steps
|
|
7174
|
+
* @param {Boolean} [fromStart]
|
|
7175
|
+
* @return {EasingFunction}
|
|
7176
|
+
*/
|
|
7177
|
+
const steps = (steps = 10, fromStart) => {
|
|
7178
|
+
const roundMethod = fromStart ? ceil : floor;
|
|
7179
|
+
return t => roundMethod(clamp$1(t, 0, 1) * steps) * (1 / steps);
|
|
7180
|
+
};
|
|
7181
|
+
|
|
7182
|
+
|
|
7183
|
+
|
|
7184
|
+
/**
|
|
7185
|
+
* Without parameters, the linear function creates a non-eased transition.
|
|
7186
|
+
* Parameters, if used, creates a piecewise linear easing by interpolating linearly between the specified points.
|
|
7187
|
+
*
|
|
7188
|
+
* @param {...(String|Number)} args - Points
|
|
7189
|
+
* @return {EasingFunction}
|
|
7190
|
+
*/
|
|
7191
|
+
const linear = (...args) => {
|
|
7192
|
+
const argsLength = args.length;
|
|
7193
|
+
if (!argsLength) return none;
|
|
7194
|
+
const totalPoints = argsLength - 1;
|
|
7195
|
+
const firstArg = args[0];
|
|
7196
|
+
const lastArg = args[totalPoints];
|
|
7197
|
+
const xPoints = [0];
|
|
7198
|
+
const yPoints = [parseNumber(firstArg)];
|
|
7199
|
+
for (let i = 1; i < totalPoints; i++) {
|
|
7200
|
+
const arg = args[i];
|
|
7201
|
+
const splitValue = isStr(arg) ?
|
|
7202
|
+
/** @type {String} */(arg).trim().split(' ') :
|
|
7203
|
+
[arg];
|
|
7204
|
+
const value = splitValue[0];
|
|
7205
|
+
const percent = splitValue[1];
|
|
7206
|
+
xPoints.push(!isUnd(percent) ? parseNumber(percent) / 100 : i / totalPoints);
|
|
7207
|
+
yPoints.push(parseNumber(value));
|
|
7208
|
+
}
|
|
7209
|
+
yPoints.push(parseNumber(lastArg));
|
|
7210
|
+
xPoints.push(1);
|
|
7211
|
+
return function easeLinear(t) {
|
|
7212
|
+
for (let i = 1, l = xPoints.length; i < l; i++) {
|
|
7213
|
+
const currentX = xPoints[i];
|
|
7214
|
+
if (t <= currentX) {
|
|
7215
|
+
const prevX = xPoints[i - 1];
|
|
7216
|
+
const prevY = yPoints[i - 1];
|
|
7217
|
+
return prevY + (yPoints[i] - prevY) * (t - prevX) / (currentX - prevX);
|
|
7218
|
+
}
|
|
7219
|
+
}
|
|
7220
|
+
return yPoints[yPoints.length - 1];
|
|
7221
|
+
}
|
|
7222
|
+
};
|
|
7223
|
+
|
|
7224
|
+
|
|
7225
|
+
|
|
7226
|
+
/**
|
|
7227
|
+
* Generate random steps
|
|
7228
|
+
* @param {Number} [length] - The number of steps
|
|
7229
|
+
* @param {Number} [randomness] - How strong the randomness is
|
|
7230
|
+
* @return {EasingFunction}
|
|
7231
|
+
*/
|
|
7232
|
+
const irregular = (length = 10, randomness = 1) => {
|
|
7233
|
+
const values = [0];
|
|
7234
|
+
const total = length - 1;
|
|
7235
|
+
for (let i = 1; i < total; i++) {
|
|
7236
|
+
const previousValue = values[i - 1];
|
|
7237
|
+
const spacing = i / total;
|
|
7238
|
+
const segmentEnd = (i + 1) / total;
|
|
7239
|
+
const randomVariation = spacing + (segmentEnd - spacing) * Math.random();
|
|
7240
|
+
// Mix the even spacing and random variation based on the randomness parameter
|
|
7241
|
+
const randomValue = spacing * (1 - randomness) + randomVariation * randomness;
|
|
7242
|
+
values.push(clamp$1(randomValue, previousValue, 1));
|
|
7243
|
+
}
|
|
7244
|
+
values.push(1);
|
|
7245
|
+
return linear(...values);
|
|
7246
|
+
};
|
|
7247
|
+
|
|
7081
7248
|
var index$3 = /*#__PURE__*/Object.freeze({
|
|
7082
7249
|
__proto__: null,
|
|
7250
|
+
Spring: Spring,
|
|
7251
|
+
createSpring: createSpring,
|
|
7083
7252
|
cubicBezier: cubicBezier,
|
|
7084
7253
|
eases: eases,
|
|
7085
7254
|
irregular: irregular,
|
|
7086
7255
|
linear: linear,
|
|
7087
|
-
|
|
7256
|
+
spring: spring,
|
|
7088
7257
|
steps: steps
|
|
7089
7258
|
});
|
|
7090
7259
|
|
|
@@ -8140,21 +8309,11 @@
|
|
|
8140
8309
|
*/
|
|
8141
8310
|
const easingToLinear = (fn, samples = 100) => {
|
|
8142
8311
|
const points = [];
|
|
8143
|
-
for (let i = 0; i <= samples; i++) points.push(fn(i / samples));
|
|
8312
|
+
for (let i = 0; i <= samples; i++) points.push(round$1(fn(i / samples), 4));
|
|
8144
8313
|
return `linear(${points.join(', ')})`;
|
|
8145
8314
|
};
|
|
8146
8315
|
|
|
8147
|
-
const WAAPIEasesLookups = {
|
|
8148
|
-
in: 'ease-in',
|
|
8149
|
-
out: 'ease-out',
|
|
8150
|
-
inOut: 'ease-in-out',
|
|
8151
|
-
};
|
|
8152
|
-
|
|
8153
|
-
const WAAPIeases = /*#__PURE__*/(() => {
|
|
8154
|
-
const list = {};
|
|
8155
|
-
for (let type in easeTypes) list[type] = (/** @type {String|Number} */p) => easeTypes[type](easeInPower(p));
|
|
8156
|
-
return /** @type {Record<String, EasingFunction>} */(list);
|
|
8157
|
-
})();
|
|
8316
|
+
const WAAPIEasesLookups = {};
|
|
8158
8317
|
|
|
8159
8318
|
/**
|
|
8160
8319
|
* @param {EasingParam} ease
|
|
@@ -8175,9 +8334,10 @@
|
|
|
8175
8334
|
} else if (stringStartsWith(ease, 'cubicB')) {
|
|
8176
8335
|
parsedEase = toLowerCase(ease);
|
|
8177
8336
|
} else {
|
|
8178
|
-
const parsed = parseEaseString(ease
|
|
8337
|
+
const parsed = parseEaseString(ease);
|
|
8179
8338
|
if (isFnc(parsed)) parsedEase = parsed === none ? 'linear' : easingToLinear(parsed);
|
|
8180
8339
|
}
|
|
8340
|
+
// Only cache string based easing name, otherwise function arguments get lost
|
|
8181
8341
|
WAAPIEasesLookups[ease] = parsedEase;
|
|
8182
8342
|
} else if (isFnc(ease)) {
|
|
8183
8343
|
const easing = easingToLinear(ease);
|
|
@@ -8218,7 +8378,8 @@
|
|
|
8218
8378
|
* @return {String}
|
|
8219
8379
|
*/
|
|
8220
8380
|
const normalizeTweenValue = (propName, value, $el, i, targetsLength) => {
|
|
8221
|
-
|
|
8381
|
+
// Do not try to compute strings with getFunctionValue otherwise it will convert CSS variables
|
|
8382
|
+
let v = isStr(value) ? value : getFunctionValue(/** @type {any} */(value), $el, i, targetsLength);
|
|
8222
8383
|
if (!isNum(v)) return v;
|
|
8223
8384
|
if (commonDefaultPXProperties.includes(propName) || stringStartsWith(propName, 'translate')) return `${v}px`;
|
|
8224
8385
|
if (stringStartsWith(propName, 'rotate') || stringStartsWith(propName, 'skew')) return `${v}deg`;
|
|
@@ -8298,7 +8459,7 @@
|
|
|
8298
8459
|
/** @type {PlaybackDirection} */
|
|
8299
8460
|
const direction = alternate ? reversed ? 'alternate-reverse' : 'alternate' : reversed ? 'reverse' : 'normal';
|
|
8300
8461
|
/** @type {FillMode} */
|
|
8301
|
-
const fill = '
|
|
8462
|
+
const fill = 'both'; // We use 'both' here because the animation can be reversed during playback
|
|
8302
8463
|
/** @type {String} */
|
|
8303
8464
|
const easing = parseWAAPIEasing(ease);
|
|
8304
8465
|
const timeScale = (globals.timeScale === 1 ? 1 : K);
|
|
@@ -8310,7 +8471,7 @@
|
|
|
8310
8471
|
/** @type {globalThis.Animation}] */
|
|
8311
8472
|
this.controlAnimation = null;
|
|
8312
8473
|
/** @type {Callback<this>} */
|
|
8313
|
-
this.onComplete = params.onComplete ||
|
|
8474
|
+
this.onComplete = params.onComplete || /** @type {Callback<WAAPIAnimation>} */(/** @type {unknown} */(globals.defaults.onComplete));
|
|
8314
8475
|
/** @type {Number} */
|
|
8315
8476
|
this.duration = 0;
|
|
8316
8477
|
/** @type {Boolean} */
|
|
@@ -8321,6 +8482,8 @@
|
|
|
8321
8482
|
this.paused = !autoplay || scroll !== false;
|
|
8322
8483
|
/** @type {Boolean} */
|
|
8323
8484
|
this.reversed = reversed;
|
|
8485
|
+
/** @type {Boolean} */
|
|
8486
|
+
this.persist = setValue(params.persist, globals.defaults.persist);
|
|
8324
8487
|
/** @type {Boolean|ScrollObserver} */
|
|
8325
8488
|
this.autoplay = autoplay;
|
|
8326
8489
|
/** @type {Number} */
|
|
@@ -8329,17 +8492,18 @@
|
|
|
8329
8492
|
this._resolve = noop; // Used by .then()
|
|
8330
8493
|
/** @type {Number} */
|
|
8331
8494
|
this._completed = 0;
|
|
8332
|
-
/** @type {Array
|
|
8333
|
-
this._inlineStyles =
|
|
8495
|
+
/** @type {Array.<Object>} */
|
|
8496
|
+
this._inlineStyles = [];
|
|
8334
8497
|
|
|
8335
8498
|
parsedTargets.forEach(($el, i) => {
|
|
8336
8499
|
|
|
8337
8500
|
const cachedTransforms = $el[transformsSymbol];
|
|
8338
|
-
|
|
8339
8501
|
const hasIndividualTransforms = validIndividualTransforms.some(t => params.hasOwnProperty(t));
|
|
8502
|
+
const elStyle = $el.style;
|
|
8503
|
+
const inlineStyles = this._inlineStyles[i] = {};
|
|
8340
8504
|
|
|
8341
8505
|
/** @type {Number} */
|
|
8342
|
-
const duration = (spring ? /** @type {Spring} */(spring).
|
|
8506
|
+
const duration = (spring ? /** @type {Spring} */(spring).settlingDuration : getFunctionValue(setValue(params.duration, globals.defaults.duration), $el, i, targetsLength)) * timeScale;
|
|
8343
8507
|
/** @type {Number} */
|
|
8344
8508
|
const delay = getFunctionValue(setValue(params.delay, globals.defaults.delay), $el, i, targetsLength) * timeScale;
|
|
8345
8509
|
/** @type {CompositeOperation} */
|
|
@@ -8353,6 +8517,12 @@
|
|
|
8353
8517
|
const tweenParams = { iterations, direction, fill, easing, duration, delay, composite };
|
|
8354
8518
|
const propertyValue = params[name];
|
|
8355
8519
|
const individualTransformProperty = hasIndividualTransforms ? validTransforms.includes(name) ? name : shortTransforms.get(name) : false;
|
|
8520
|
+
|
|
8521
|
+
const styleName = individualTransformProperty ? 'transform' : name;
|
|
8522
|
+
if (!inlineStyles[styleName]) {
|
|
8523
|
+
inlineStyles[styleName] = elStyle[styleName];
|
|
8524
|
+
}
|
|
8525
|
+
|
|
8356
8526
|
let parsedPropertyValue;
|
|
8357
8527
|
if (isObj(propertyValue)) {
|
|
8358
8528
|
const tweenOptions = /** @type {WAAPITweenOptions} */(propertyValue);
|
|
@@ -8361,7 +8531,7 @@
|
|
|
8361
8531
|
const to = /** @type {WAAPITweenOptions} */(tweenOptions).to;
|
|
8362
8532
|
const from = /** @type {WAAPITweenOptions} */(tweenOptions).from;
|
|
8363
8533
|
/** @type {Number} */
|
|
8364
|
-
tweenParams.duration = (tweenOptionsSpring ? /** @type {Spring} */(tweenOptionsSpring).
|
|
8534
|
+
tweenParams.duration = (tweenOptionsSpring ? /** @type {Spring} */(tweenOptionsSpring).settlingDuration : getFunctionValue(setValue(tweenOptions.duration, duration), $el, i, targetsLength)) * timeScale;
|
|
8365
8535
|
/** @type {Number} */
|
|
8366
8536
|
tweenParams.delay = getFunctionValue(setValue(tweenOptions.delay, delay), $el, i, targetsLength) * timeScale;
|
|
8367
8537
|
/** @type {CompositeOperation} */
|
|
@@ -8378,10 +8548,10 @@
|
|
|
8378
8548
|
addWAAPIAnimation(this, $el, name, keyframes, tweenParams);
|
|
8379
8549
|
if (!isUnd(from)) {
|
|
8380
8550
|
if (!individualTransformProperty) {
|
|
8381
|
-
|
|
8551
|
+
elStyle[name] = keyframes[name][0];
|
|
8382
8552
|
} else {
|
|
8383
8553
|
const key = `--${individualTransformProperty}`;
|
|
8384
|
-
|
|
8554
|
+
elStyle.setProperty(key, keyframes[key][0]);
|
|
8385
8555
|
}
|
|
8386
8556
|
}
|
|
8387
8557
|
} else {
|
|
@@ -8402,7 +8572,7 @@
|
|
|
8402
8572
|
for (let t in cachedTransforms) {
|
|
8403
8573
|
transforms += `${transformsFragmentStrings[t]}var(--${t})) `;
|
|
8404
8574
|
}
|
|
8405
|
-
|
|
8575
|
+
elStyle.transform = transforms;
|
|
8406
8576
|
}
|
|
8407
8577
|
});
|
|
8408
8578
|
|
|
@@ -8447,7 +8617,8 @@
|
|
|
8447
8617
|
// Make sure the animation playState is not 'paused' in order to properly trigger an onfinish callback.
|
|
8448
8618
|
// The "paused" play state supersedes the "finished" play state; if the animation is both paused and finished, the "paused" state is the one that will be reported.
|
|
8449
8619
|
// https://developer.mozilla.org/en-US/docs/Web/API/Animation/finish_event
|
|
8450
|
-
|
|
8620
|
+
// This is not needed for persisting animations since they never finish.
|
|
8621
|
+
if (!this.persist && t >= this.duration) anim.play();
|
|
8451
8622
|
anim.currentTime = t;
|
|
8452
8623
|
});
|
|
8453
8624
|
}
|
|
@@ -8517,13 +8688,30 @@
|
|
|
8517
8688
|
}
|
|
8518
8689
|
|
|
8519
8690
|
cancel() {
|
|
8520
|
-
this.
|
|
8521
|
-
return this.
|
|
8691
|
+
this.muteCallbacks = true; // This prevents triggering the onComplete callback and resolving the Promise
|
|
8692
|
+
return this.commitStyles().forEach('cancel');
|
|
8522
8693
|
}
|
|
8523
8694
|
|
|
8524
8695
|
revert() {
|
|
8525
|
-
|
|
8526
|
-
|
|
8696
|
+
// NOTE: We need a better way to revert the transforms, since right now the entire transform property value is reverted,
|
|
8697
|
+
// This means if you have multiple animations animating different transforms on the same target,
|
|
8698
|
+
// reverting one of them will also override the transform property of the other animations.
|
|
8699
|
+
// A better approach would be to store the original custom property values is they exist instead of the entire transform value,
|
|
8700
|
+
// and update the CSS variables with the orignal value
|
|
8701
|
+
this.cancel().targets.forEach(($el, i) => {
|
|
8702
|
+
const targetStyle = $el.style;
|
|
8703
|
+
const targetInlineStyles = this._inlineStyles[i];
|
|
8704
|
+
for (let name in targetInlineStyles) {
|
|
8705
|
+
const originalInlinedValue = targetInlineStyles[name];
|
|
8706
|
+
if (isUnd(originalInlinedValue) || originalInlinedValue === emptyString) {
|
|
8707
|
+
targetStyle.removeProperty(toLowerCase(name));
|
|
8708
|
+
} else {
|
|
8709
|
+
targetStyle[name] = originalInlinedValue;
|
|
8710
|
+
}
|
|
8711
|
+
}
|
|
8712
|
+
// Remove style attribute if empty
|
|
8713
|
+
if ($el.getAttribute('style') === emptyString) $el.removeAttribute('style');
|
|
8714
|
+
});
|
|
8527
8715
|
return this;
|
|
8528
8716
|
}
|
|
8529
8717
|
|
|
@@ -8593,7 +8781,6 @@
|
|
|
8593
8781
|
exports.linear = linear;
|
|
8594
8782
|
exports.mapRange = mapRange;
|
|
8595
8783
|
exports.morphTo = morphTo;
|
|
8596
|
-
exports.none = none;
|
|
8597
8784
|
exports.onScroll = onScroll;
|
|
8598
8785
|
exports.padEnd = padEnd;
|
|
8599
8786
|
exports.padStart = padStart;
|
|
@@ -8609,6 +8796,7 @@
|
|
|
8609
8796
|
exports.snap = snap;
|
|
8610
8797
|
exports.split = split;
|
|
8611
8798
|
exports.splitText = splitText;
|
|
8799
|
+
exports.spring = spring;
|
|
8612
8800
|
exports.stagger = stagger;
|
|
8613
8801
|
exports.steps = steps;
|
|
8614
8802
|
exports.svg = index$1;
|