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
|
|
@@ -682,6 +693,8 @@ const maxFps = 120;
|
|
|
682
693
|
// Strings
|
|
683
694
|
|
|
684
695
|
const emptyString = '';
|
|
696
|
+
const cssVarPrefix = 'var(';
|
|
697
|
+
|
|
685
698
|
const shortTransforms = /*#__PURE__*/ (() => {
|
|
686
699
|
const map = new Map();
|
|
687
700
|
map.set('x', 'translateX');
|
|
@@ -705,9 +718,9 @@ const validTransforms = [
|
|
|
705
718
|
'skew',
|
|
706
719
|
'skewX',
|
|
707
720
|
'skewY',
|
|
708
|
-
'perspective',
|
|
709
721
|
'matrix',
|
|
710
722
|
'matrix3d',
|
|
723
|
+
'perspective',
|
|
711
724
|
];
|
|
712
725
|
|
|
713
726
|
const transformsFragmentStrings = /*#__PURE__*/ validTransforms.reduce((a, v) => ({...a, [v]: v + '('}), {});
|
|
@@ -731,6 +744,7 @@ const unitsExecRgx = /^([-+]?\d*\.?\d+(?:e[-+]?\d+)?)([a-z]+|%)$/i;
|
|
|
731
744
|
const lowerCaseRgx = /([a-z])([A-Z])/g;
|
|
732
745
|
const transformsExecRgx = /(\w+)(\([^)]+\)+)/g; // Match inline transforms with cacl() values, returns the value wrapped in ()
|
|
733
746
|
const relativeValuesExecRgx = /(\*=|\+=|-=)/;
|
|
747
|
+
const cssVariableMatchRgx = /var\(\s*(--[\w-]+)(?:\s*,\s*([^)]+))?\s*\)/;
|
|
734
748
|
|
|
735
749
|
|
|
736
750
|
|
|
@@ -745,6 +759,7 @@ const defaults = {
|
|
|
745
759
|
reversed: false,
|
|
746
760
|
alternate: false,
|
|
747
761
|
autoplay: true,
|
|
762
|
+
persist: false,
|
|
748
763
|
duration: K,
|
|
749
764
|
delay: 0,
|
|
750
765
|
loopDelay: 0,
|
|
@@ -1168,19 +1183,30 @@ const setValue = (targetValue, defaultValue) => {
|
|
|
1168
1183
|
* @return {any}
|
|
1169
1184
|
*/
|
|
1170
1185
|
const getFunctionValue = (value, target, index, total, store) => {
|
|
1186
|
+
let func;
|
|
1171
1187
|
if (isFnc(value)) {
|
|
1172
|
-
|
|
1188
|
+
func = () => {
|
|
1173
1189
|
const computed = /** @type {Function} */(value)(target, index, total);
|
|
1174
1190
|
// Fallback to 0 if the function returns undefined / NaN / null / false / 0
|
|
1175
1191
|
return !isNaN(+computed) ? +computed : computed || 0;
|
|
1176
1192
|
};
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1193
|
+
} else if (isStr(value) && stringStartsWith(value, cssVarPrefix)) {
|
|
1194
|
+
func = () => {
|
|
1195
|
+
const match = value.match(cssVariableMatchRgx);
|
|
1196
|
+
const cssVarName = match[1];
|
|
1197
|
+
const fallbackValue = match[2];
|
|
1198
|
+
let computed = getComputedStyle(/** @type {HTMLElement} */(target))?.getPropertyValue(cssVarName);
|
|
1199
|
+
// Use fallback if CSS variable is not set or empty
|
|
1200
|
+
if ((!computed || computed.trim() === emptyString) && fallbackValue) {
|
|
1201
|
+
computed = fallbackValue.trim();
|
|
1202
|
+
}
|
|
1203
|
+
return computed || 0;
|
|
1204
|
+
};
|
|
1181
1205
|
} else {
|
|
1182
1206
|
return value;
|
|
1183
1207
|
}
|
|
1208
|
+
if (store) store.func = func;
|
|
1209
|
+
return func();
|
|
1184
1210
|
};
|
|
1185
1211
|
|
|
1186
1212
|
/**
|
|
@@ -1587,7 +1613,9 @@ const render = (tickable, time, muteCallbacks, internalRender, tickMode) => {
|
|
|
1587
1613
|
// Handle setters on timeline differently and allow re-trigering the onComplete callback when seeking backwards
|
|
1588
1614
|
if (parent && isSetter) {
|
|
1589
1615
|
if (!muteCallbacks && (
|
|
1590
|
-
(
|
|
1616
|
+
// (tickableAbsoluteTime > 0 instead) of (tickableAbsoluteTime >= duration) to prevent floating point precision issues
|
|
1617
|
+
// see: https://github.com/juliangarnier/anime/issues/1088
|
|
1618
|
+
(parent.began && !isRunningBackwards && tickableAbsoluteTime > 0 && !completed) ||
|
|
1591
1619
|
(isRunningBackwards && tickableAbsoluteTime <= minValue && completed)
|
|
1592
1620
|
)) {
|
|
1593
1621
|
tickable.onComplete(/** @type {CallbackArgument} */(tickable));
|
|
@@ -1689,12 +1717,11 @@ const tick = (tickable, time, muteCallbacks, internalRender, tickMode) => {
|
|
|
1689
1717
|
}
|
|
1690
1718
|
};
|
|
1691
1719
|
|
|
1692
|
-
const propertyNamesCache = {};
|
|
1693
|
-
|
|
1694
1720
|
|
|
1695
1721
|
|
|
1696
1722
|
|
|
1697
1723
|
|
|
1724
|
+
const propertyNamesCache = {};
|
|
1698
1725
|
|
|
1699
1726
|
/**
|
|
1700
1727
|
* @param {String} propertyName
|
|
@@ -1742,10 +1769,11 @@ const cleanInlineStyles = renderable => {
|
|
|
1742
1769
|
const tweenTarget = tween.target;
|
|
1743
1770
|
if (tweenTarget[isDomSymbol]) {
|
|
1744
1771
|
const targetStyle = /** @type {DOMTarget} */(tweenTarget).style;
|
|
1745
|
-
const originalInlinedValue =
|
|
1772
|
+
const originalInlinedValue = tween._inlineValue;
|
|
1773
|
+
const tweenHadNoInlineValue = isNil(originalInlinedValue) || originalInlinedValue === emptyString;
|
|
1746
1774
|
if (tween._tweenType === tweenTypes.TRANSFORM) {
|
|
1747
1775
|
const cachedTransforms = tweenTarget[transformsSymbol];
|
|
1748
|
-
if (
|
|
1776
|
+
if (tweenHadNoInlineValue) {
|
|
1749
1777
|
delete cachedTransforms[tweenProperty];
|
|
1750
1778
|
} else {
|
|
1751
1779
|
cachedTransforms[tweenProperty] = originalInlinedValue;
|
|
@@ -1762,8 +1790,8 @@ const cleanInlineStyles = renderable => {
|
|
|
1762
1790
|
}
|
|
1763
1791
|
}
|
|
1764
1792
|
} else {
|
|
1765
|
-
if (
|
|
1766
|
-
targetStyle.removeProperty(tweenProperty);
|
|
1793
|
+
if (tweenHadNoInlineValue) {
|
|
1794
|
+
targetStyle.removeProperty(toLowerCase(tweenProperty));
|
|
1767
1795
|
} else {
|
|
1768
1796
|
targetStyle[tweenProperty] = originalInlinedValue;
|
|
1769
1797
|
}
|
|
@@ -3048,6 +3076,7 @@ const none = t => t;
|
|
|
3048
3076
|
|
|
3049
3077
|
|
|
3050
3078
|
|
|
3079
|
+
|
|
3051
3080
|
/** @type {PowerEasing} */
|
|
3052
3081
|
const easeInPower = (p = 1.68) => t => pow(t, +p);
|
|
3053
3082
|
|
|
@@ -3065,154 +3094,6 @@ const easeTypes = {
|
|
|
3065
3094
|
outIn: easeIn => t => t < .5 ? (1 - easeIn(1 - t * 2)) / 2 : (easeIn(t * 2 - 1) + 1) / 2,
|
|
3066
3095
|
};
|
|
3067
3096
|
|
|
3068
|
-
/**
|
|
3069
|
-
* @param {String} string
|
|
3070
|
-
* @param {Record<String, EasingFunctionWithParams|EasingFunction>} easesFunctions
|
|
3071
|
-
* @param {Object} easesLookups
|
|
3072
|
-
* @return {EasingFunction}
|
|
3073
|
-
*/
|
|
3074
|
-
const parseEaseString = (string, easesFunctions, easesLookups) => {
|
|
3075
|
-
if (easesLookups[string]) return easesLookups[string];
|
|
3076
|
-
if (string.indexOf('(') <= -1) {
|
|
3077
|
-
const hasParams = easeTypes[string] || string.includes('Back') || string.includes('Elastic');
|
|
3078
|
-
const parsedFn = /** @type {EasingFunction} */(hasParams ? /** @type {EasingFunctionWithParams} */(easesFunctions[string])() : easesFunctions[string]);
|
|
3079
|
-
return parsedFn ? easesLookups[string] = parsedFn : none;
|
|
3080
|
-
} else {
|
|
3081
|
-
const split = string.slice(0, -1).split('(');
|
|
3082
|
-
const parsedFn = /** @type {EasingFunctionWithParams} */(easesFunctions[split[0]]);
|
|
3083
|
-
return parsedFn ? easesLookups[string] = parsedFn(...split[1].split(',')) : none;
|
|
3084
|
-
}
|
|
3085
|
-
};
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
/**
|
|
3090
|
-
* Cubic Bezier solver adapted from https://github.com/gre/bezier-easing
|
|
3091
|
-
* (c) 2014 Gaëtan Renaudeau
|
|
3092
|
-
*/
|
|
3093
|
-
|
|
3094
|
-
/**
|
|
3095
|
-
* @param {Number} aT
|
|
3096
|
-
* @param {Number} aA1
|
|
3097
|
-
* @param {Number} aA2
|
|
3098
|
-
* @return {Number}
|
|
3099
|
-
*/
|
|
3100
|
-
const calcBezier = (aT, aA1, aA2) => (((1 - 3 * aA2 + 3 * aA1) * aT + (3 * aA2 - 6 * aA1)) * aT + (3 * aA1)) * aT;
|
|
3101
|
-
|
|
3102
|
-
/**
|
|
3103
|
-
* @param {Number} aX
|
|
3104
|
-
* @param {Number} mX1
|
|
3105
|
-
* @param {Number} mX2
|
|
3106
|
-
* @return {Number}
|
|
3107
|
-
*/
|
|
3108
|
-
const binarySubdivide = (aX, mX1, mX2) => {
|
|
3109
|
-
let aA = 0, aB = 1, currentX, currentT, i = 0;
|
|
3110
|
-
do {
|
|
3111
|
-
currentT = aA + (aB - aA) / 2;
|
|
3112
|
-
currentX = calcBezier(currentT, mX1, mX2) - aX;
|
|
3113
|
-
if (currentX > 0) {
|
|
3114
|
-
aB = currentT;
|
|
3115
|
-
} else {
|
|
3116
|
-
aA = currentT;
|
|
3117
|
-
}
|
|
3118
|
-
} while (abs(currentX) > .0000001 && ++i < 100);
|
|
3119
|
-
return currentT;
|
|
3120
|
-
};
|
|
3121
|
-
|
|
3122
|
-
/**
|
|
3123
|
-
* @param {Number} [mX1] The x coordinate of the first point
|
|
3124
|
-
* @param {Number} [mY1] The y coordinate of the first point
|
|
3125
|
-
* @param {Number} [mX2] The x coordinate of the second point
|
|
3126
|
-
* @param {Number} [mY2] The y coordinate of the second point
|
|
3127
|
-
* @return {EasingFunction}
|
|
3128
|
-
*/
|
|
3129
|
-
|
|
3130
|
-
const cubicBezier = (mX1 = 0.5, mY1 = 0.0, mX2 = 0.5, mY2 = 1.0) => (mX1 === mY1 && mX2 === mY2) ? none :
|
|
3131
|
-
t => t === 0 || t === 1 ? t :
|
|
3132
|
-
calcBezier(binarySubdivide(t, mX1, mX2), mY1, mY2);
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
/**
|
|
3137
|
-
* Steps ease implementation https://developer.mozilla.org/fr/docs/Web/CSS/transition-timing-function
|
|
3138
|
-
* Only covers 'end' and 'start' jumpterms
|
|
3139
|
-
* @param {Number} steps
|
|
3140
|
-
* @param {Boolean} [fromStart]
|
|
3141
|
-
* @return {EasingFunction}
|
|
3142
|
-
*/
|
|
3143
|
-
const steps = (steps = 10, fromStart) => {
|
|
3144
|
-
const roundMethod = fromStart ? ceil : floor;
|
|
3145
|
-
return t => roundMethod(clamp$1(t, 0, 1) * steps) * (1 / steps);
|
|
3146
|
-
};
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
/**
|
|
3151
|
-
* Without parameters, the linear function creates a non-eased transition.
|
|
3152
|
-
* Parameters, if used, creates a piecewise linear easing by interpolating linearly between the specified points.
|
|
3153
|
-
*
|
|
3154
|
-
* @param {...(String|Number)} args - Points
|
|
3155
|
-
* @return {EasingFunction}
|
|
3156
|
-
*/
|
|
3157
|
-
const linear = (...args) => {
|
|
3158
|
-
const argsLength = args.length;
|
|
3159
|
-
if (!argsLength) return none;
|
|
3160
|
-
const totalPoints = argsLength - 1;
|
|
3161
|
-
const firstArg = args[0];
|
|
3162
|
-
const lastArg = args[totalPoints];
|
|
3163
|
-
const xPoints = [0];
|
|
3164
|
-
const yPoints = [parseNumber(firstArg)];
|
|
3165
|
-
for (let i = 1; i < totalPoints; i++) {
|
|
3166
|
-
const arg = args[i];
|
|
3167
|
-
const splitValue = isStr(arg) ?
|
|
3168
|
-
/** @type {String} */(arg).trim().split(' ') :
|
|
3169
|
-
[arg];
|
|
3170
|
-
const value = splitValue[0];
|
|
3171
|
-
const percent = splitValue[1];
|
|
3172
|
-
xPoints.push(!isUnd(percent) ? parseNumber(percent) / 100 : i / totalPoints);
|
|
3173
|
-
yPoints.push(parseNumber(value));
|
|
3174
|
-
}
|
|
3175
|
-
yPoints.push(parseNumber(lastArg));
|
|
3176
|
-
xPoints.push(1);
|
|
3177
|
-
return function easeLinear(t) {
|
|
3178
|
-
for (let i = 1, l = xPoints.length; i < l; i++) {
|
|
3179
|
-
const currentX = xPoints[i];
|
|
3180
|
-
if (t <= currentX) {
|
|
3181
|
-
const prevX = xPoints[i - 1];
|
|
3182
|
-
const prevY = yPoints[i - 1];
|
|
3183
|
-
return prevY + (yPoints[i] - prevY) * (t - prevX) / (currentX - prevX);
|
|
3184
|
-
}
|
|
3185
|
-
}
|
|
3186
|
-
return yPoints[yPoints.length - 1];
|
|
3187
|
-
}
|
|
3188
|
-
};
|
|
3189
|
-
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
/**
|
|
3193
|
-
* Generate random steps
|
|
3194
|
-
* @param {Number} [length] - The number of steps
|
|
3195
|
-
* @param {Number} [randomness] - How strong the randomness is
|
|
3196
|
-
* @return {EasingFunction}
|
|
3197
|
-
*/
|
|
3198
|
-
const irregular = (length = 10, randomness = 1) => {
|
|
3199
|
-
const values = [0];
|
|
3200
|
-
const total = length - 1;
|
|
3201
|
-
for (let i = 1; i < total; i++) {
|
|
3202
|
-
const previousValue = values[i - 1];
|
|
3203
|
-
const spacing = i / total;
|
|
3204
|
-
const segmentEnd = (i + 1) / total;
|
|
3205
|
-
const randomVariation = spacing + (segmentEnd - spacing) * Math.random();
|
|
3206
|
-
// Mix the even spacing and random variation based on the randomness parameter
|
|
3207
|
-
const randomValue = spacing * (1 - randomness) + randomVariation * randomness;
|
|
3208
|
-
values.push(clamp$1(randomValue, previousValue, 1));
|
|
3209
|
-
}
|
|
3210
|
-
values.push(1);
|
|
3211
|
-
return linear(...values);
|
|
3212
|
-
};
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
3097
|
/**
|
|
3217
3098
|
* Easing functions adapted and simplified from https://robertpenner.com/easing/
|
|
3218
3099
|
* (c) 2001 Robert Penner
|
|
@@ -3241,7 +3122,7 @@ const easeInFunctions = {
|
|
|
3241
3122
|
return 1 / pow(4, 3 - b) - 7.5625 * pow((pow2 * 3 - 2) / 22 - t, 2);
|
|
3242
3123
|
},
|
|
3243
3124
|
/** @type {BackEasing} */
|
|
3244
|
-
Back: (overshoot = 1.
|
|
3125
|
+
Back: (overshoot = 1.7) => t => (+overshoot + 1) * t * t * t - +overshoot * t * t,
|
|
3245
3126
|
/** @type {ElasticEasing} */
|
|
3246
3127
|
Elastic: (amplitude = 1, period = .3) => {
|
|
3247
3128
|
const a = clamp$1(+amplitude, 1, 10);
|
|
@@ -3254,10 +3135,8 @@ const easeInFunctions = {
|
|
|
3254
3135
|
|
|
3255
3136
|
/**
|
|
3256
3137
|
* @typedef {Object} EasesFunctions
|
|
3257
|
-
* @property {typeof
|
|
3258
|
-
* @property {typeof
|
|
3259
|
-
* @property {typeof steps} steps
|
|
3260
|
-
* @property {typeof cubicBezier} cubicBezier
|
|
3138
|
+
* @property {typeof none} linear
|
|
3139
|
+
* @property {typeof none} none
|
|
3261
3140
|
* @property {PowerEasing} in
|
|
3262
3141
|
* @property {PowerEasing} out
|
|
3263
3142
|
* @property {PowerEasing} inOut
|
|
@@ -3305,7 +3184,7 @@ const easeInFunctions = {
|
|
|
3305
3184
|
*/
|
|
3306
3185
|
|
|
3307
3186
|
const eases = (/*#__PURE__ */ (() => {
|
|
3308
|
-
const list = { linear
|
|
3187
|
+
const list = { linear: none, none: none };
|
|
3309
3188
|
for (let type in easeTypes) {
|
|
3310
3189
|
for (let name in easeInFunctions) {
|
|
3311
3190
|
const easeIn = easeInFunctions[name];
|
|
@@ -3321,15 +3200,43 @@ const eases = (/*#__PURE__ */ (() => {
|
|
|
3321
3200
|
})());
|
|
3322
3201
|
|
|
3323
3202
|
/** @type {Record<String, EasingFunction>} */
|
|
3324
|
-
const
|
|
3203
|
+
const easesLookups = { linear: none, none: none };
|
|
3204
|
+
|
|
3205
|
+
/**
|
|
3206
|
+
* @param {String} string
|
|
3207
|
+
* @return {EasingFunction}
|
|
3208
|
+
*/
|
|
3209
|
+
const parseEaseString = (string) => {
|
|
3210
|
+
if (easesLookups[string]) return easesLookups[string];
|
|
3211
|
+
if (string.indexOf('(') <= -1) {
|
|
3212
|
+
const hasParams = easeTypes[string] || string.includes('Back') || string.includes('Elastic');
|
|
3213
|
+
const parsedFn = /** @type {EasingFunction} */(hasParams ? /** @type {EasingFunctionWithParams} */(eases[string])() : eases[string]);
|
|
3214
|
+
return parsedFn ? easesLookups[string] = parsedFn : none;
|
|
3215
|
+
} else {
|
|
3216
|
+
const split = string.slice(0, -1).split('(');
|
|
3217
|
+
const parsedFn = /** @type {EasingFunctionWithParams} */(eases[split[0]]);
|
|
3218
|
+
return parsedFn ? easesLookups[string] = parsedFn(...split[1].split(',')) : none;
|
|
3219
|
+
}
|
|
3220
|
+
};
|
|
3221
|
+
|
|
3222
|
+
const deprecated = ['steps(', 'irregular(', 'linear(', 'cubicBezier('];
|
|
3325
3223
|
|
|
3326
3224
|
/**
|
|
3327
3225
|
* @param {EasingParam} ease
|
|
3328
3226
|
* @return {EasingFunction}
|
|
3329
3227
|
*/
|
|
3330
|
-
const parseEase = ease =>
|
|
3331
|
-
|
|
3332
|
-
|
|
3228
|
+
const parseEase = ease => {
|
|
3229
|
+
if (isStr(ease)) {
|
|
3230
|
+
for (let i = 0, l = deprecated.length; i < l; i++) {
|
|
3231
|
+
if (stringStartsWith(ease, deprecated[i])) {
|
|
3232
|
+
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}\``);
|
|
3233
|
+
return none;
|
|
3234
|
+
}
|
|
3235
|
+
}
|
|
3236
|
+
}
|
|
3237
|
+
const easeFunc = isFnc(ease) ? ease : isStr(ease) ? parseEaseString(/** @type {String} */(ease)) : none;
|
|
3238
|
+
return easeFunc;
|
|
3239
|
+
};
|
|
3333
3240
|
|
|
3334
3241
|
|
|
3335
3242
|
|
|
@@ -3337,6 +3244,7 @@ const parseEase = ease => isFnc(ease) ? ease :
|
|
|
3337
3244
|
// TODO: Maybe move the objects creation to values.js and use the decompose function to create the base object
|
|
3338
3245
|
const fromTargetObject = createDecomposedValueTargetObject();
|
|
3339
3246
|
const toTargetObject = createDecomposedValueTargetObject();
|
|
3247
|
+
const inlineStylesStore = {};
|
|
3340
3248
|
const toFunctionStore = { func: null };
|
|
3341
3249
|
const keyframesTargetArray = [null];
|
|
3342
3250
|
const fastSetValuesArray = [null, null];
|
|
@@ -3481,15 +3389,15 @@ class JSAnimation extends Timer {
|
|
|
3481
3389
|
const animEase = animaPlaybackEase ? parseEase(animaPlaybackEase) : null;
|
|
3482
3390
|
const hasSpring = !isUnd(ease) && !isUnd(/** @type {Spring} */(ease).ease);
|
|
3483
3391
|
const tEasing = hasSpring ? /** @type {Spring} */(ease).ease : setValue(ease, animEase ? 'linear' : animDefaults.ease);
|
|
3484
|
-
const tDuration = hasSpring ? /** @type {Spring} */(ease).
|
|
3392
|
+
const tDuration = hasSpring ? /** @type {Spring} */(ease).settlingDuration : setValue(duration, animDefaults.duration);
|
|
3485
3393
|
const tDelay = setValue(delay, animDefaults.delay);
|
|
3486
3394
|
const tModifier = modifier || animDefaults.modifier;
|
|
3487
3395
|
// If no composition is defined and the targets length is high (>= 1000) set the composition to 'none' (0) for faster tween creation
|
|
3488
3396
|
const tComposition = isUnd(composition) && targetsLength >= K ? compositionTypes.none : !isUnd(composition) ? composition : animDefaults.composition;
|
|
3489
|
-
// TODO: Do not create an empty object until we know the animation will generate inline styles
|
|
3490
|
-
const animInlineStyles = {};
|
|
3491
3397
|
// const absoluteOffsetTime = this._offset;
|
|
3492
3398
|
const absoluteOffsetTime = this._offset + (parent ? parent._offset : 0);
|
|
3399
|
+
// This allows targeting the current animation in the spring onComplete callback
|
|
3400
|
+
if (hasSpring) /** @type {Spring} */(ease).parent = this;
|
|
3493
3401
|
|
|
3494
3402
|
let iterationDuration = NaN;
|
|
3495
3403
|
let iterationDelay = NaN;
|
|
@@ -3591,7 +3499,7 @@ class JSAnimation extends Timer {
|
|
|
3591
3499
|
// 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
|
|
3592
3500
|
const tweenEasing = hasSpring ? /** @type {Spring} */(keyEasing).ease : keyEasing || tEasing;
|
|
3593
3501
|
// Calculate default individual keyframe duration by dividing the tl of keyframes
|
|
3594
|
-
const tweenDuration = hasSpring ? /** @type {Spring} */(keyEasing).
|
|
3502
|
+
const tweenDuration = hasSpring ? /** @type {Spring} */(keyEasing).settlingDuration : getFunctionValue(setValue(key.duration, (l > 1 ? getFunctionValue(tDuration, target, ti, tl) / l : tDuration)), target, ti, tl);
|
|
3595
3503
|
// Default delay value should only be applied to the first tween
|
|
3596
3504
|
const tweenDelay = getFunctionValue(setValue(key.delay, (!tweenIndex ? tDelay : 0)), target, ti, tl);
|
|
3597
3505
|
const computedComposition = getFunctionValue(setValue(key.composition, tComposition), target, ti, tl);
|
|
@@ -3641,7 +3549,7 @@ class JSAnimation extends Timer {
|
|
|
3641
3549
|
}
|
|
3642
3550
|
} else {
|
|
3643
3551
|
decomposeRawValue(
|
|
3644
|
-
getOriginalAnimatableValue(target, propName, tweenType,
|
|
3552
|
+
getOriginalAnimatableValue(target, propName, tweenType, inlineStylesStore),
|
|
3645
3553
|
decomposedOriginalValue
|
|
3646
3554
|
);
|
|
3647
3555
|
if (decomposedOriginalValue.t === valueTypes.UNIT) {
|
|
@@ -3659,7 +3567,7 @@ class JSAnimation extends Timer {
|
|
|
3659
3567
|
} else {
|
|
3660
3568
|
// 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
|
|
3661
3569
|
decomposeRawValue(parent && prevSibling && prevSibling.parent.parent === parent ? prevSibling._value :
|
|
3662
|
-
getOriginalAnimatableValue(target, propName, tweenType,
|
|
3570
|
+
getOriginalAnimatableValue(target, propName, tweenType, inlineStylesStore), toTargetObject);
|
|
3663
3571
|
}
|
|
3664
3572
|
}
|
|
3665
3573
|
if (hasFromvalue) {
|
|
@@ -3670,7 +3578,7 @@ class JSAnimation extends Timer {
|
|
|
3670
3578
|
} else {
|
|
3671
3579
|
decomposeRawValue(parent && prevSibling && prevSibling.parent.parent === parent ? prevSibling._value :
|
|
3672
3580
|
// 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
|
|
3673
|
-
getOriginalAnimatableValue(target, propName, tweenType,
|
|
3581
|
+
getOriginalAnimatableValue(target, propName, tweenType, inlineStylesStore), fromTargetObject);
|
|
3674
3582
|
}
|
|
3675
3583
|
}
|
|
3676
3584
|
}
|
|
@@ -3679,7 +3587,7 @@ class JSAnimation extends Timer {
|
|
|
3679
3587
|
if (fromTargetObject.o) {
|
|
3680
3588
|
fromTargetObject.n = getRelativeValue(
|
|
3681
3589
|
!prevSibling ? decomposeRawValue(
|
|
3682
|
-
getOriginalAnimatableValue(target, propName, tweenType,
|
|
3590
|
+
getOriginalAnimatableValue(target, propName, tweenType, inlineStylesStore),
|
|
3683
3591
|
decomposedOriginalValue
|
|
3684
3592
|
).n : prevSibling._toNumber,
|
|
3685
3593
|
fromTargetObject.n,
|
|
@@ -3735,6 +3643,10 @@ class JSAnimation extends Timer {
|
|
|
3735
3643
|
// Rounding is necessary here to minimize floating point errors when working in seconds
|
|
3736
3644
|
const tweenUpdateDuration = round$1(+tweenDuration || minValue, 12);
|
|
3737
3645
|
|
|
3646
|
+
// Copy the value of the iniline style if it exist and imediatly nullify it to prevents false positive on other targets
|
|
3647
|
+
let inlineValue = inlineStylesStore[propName];
|
|
3648
|
+
if (!isNil(inlineValue)) inlineStylesStore[propName] = null;
|
|
3649
|
+
|
|
3738
3650
|
/** @type {Tween} */
|
|
3739
3651
|
const tween = {
|
|
3740
3652
|
parent: this,
|
|
@@ -3766,6 +3678,7 @@ class JSAnimation extends Timer {
|
|
|
3766
3678
|
_isOverlapped: 0,
|
|
3767
3679
|
_isOverridden: 0,
|
|
3768
3680
|
_renderTransforms: 0,
|
|
3681
|
+
_inlineValue: inlineValue,
|
|
3769
3682
|
_prevRep: null, // For replaced tween
|
|
3770
3683
|
_nextRep: null, // For replaced tween
|
|
3771
3684
|
_prevAdd: null, // For additive tween
|
|
@@ -3868,8 +3781,6 @@ class JSAnimation extends Timer {
|
|
|
3868
3781
|
// this._offset += parent ? iterationDelay : 0;
|
|
3869
3782
|
/** @type {Number} */
|
|
3870
3783
|
this.iterationDuration = iterationDuration;
|
|
3871
|
-
/** @type {{}} */
|
|
3872
|
-
this._inlineStyles = animInlineStyles;
|
|
3873
3784
|
|
|
3874
3785
|
if (!this._autoplay && shouldTriggerRender) this.onRender(this);
|
|
3875
3786
|
}
|
|
@@ -3903,6 +3814,7 @@ class JSAnimation extends Timer {
|
|
|
3903
3814
|
if (tweenFunc) {
|
|
3904
3815
|
const ogValue = getOriginalAnimatableValue(tween.target, tween.property, tween._tweenType);
|
|
3905
3816
|
decomposeRawValue(ogValue, decomposedOriginalValue);
|
|
3817
|
+
// TODO: Check for from / to Array based values here,
|
|
3906
3818
|
decomposeRawValue(tweenFunc(), toTargetObject);
|
|
3907
3819
|
tween._fromNumbers = cloneArray(decomposedOriginalValue.d);
|
|
3908
3820
|
tween._fromNumber = decomposedOriginalValue.n;
|
|
@@ -3912,6 +3824,8 @@ class JSAnimation extends Timer {
|
|
|
3912
3824
|
tween._toNumber = toTargetObject.o ? getRelativeValue(decomposedOriginalValue.n, toTargetObject.n, toTargetObject.o) : toTargetObject.n;
|
|
3913
3825
|
}
|
|
3914
3826
|
});
|
|
3827
|
+
// This forces setter animations to render once
|
|
3828
|
+
if (this.duration === minValue) this.restart();
|
|
3915
3829
|
return this;
|
|
3916
3830
|
}
|
|
3917
3831
|
|
|
@@ -3954,16 +3868,18 @@ const WAAPIAnimationsLookups = {
|
|
|
3954
3868
|
* @param {DOMTarget} $el
|
|
3955
3869
|
* @param {String} [property]
|
|
3956
3870
|
* @param {WAAPIAnimation} [parent]
|
|
3871
|
+
* @return {globalThis.Animation}
|
|
3957
3872
|
*/
|
|
3958
3873
|
const removeWAAPIAnimation = ($el, property, parent) => {
|
|
3959
3874
|
let nextLookup = WAAPIAnimationsLookups._head;
|
|
3875
|
+
let anim;
|
|
3960
3876
|
while (nextLookup) {
|
|
3961
3877
|
const next = nextLookup._next;
|
|
3962
3878
|
const matchTarget = nextLookup.$el === $el;
|
|
3963
3879
|
const matchProperty = !property || nextLookup.property === property;
|
|
3964
3880
|
const matchParent = !parent || nextLookup.parent === parent;
|
|
3965
3881
|
if (matchTarget && matchProperty && matchParent) {
|
|
3966
|
-
|
|
3882
|
+
anim = nextLookup.animation;
|
|
3967
3883
|
try { anim.commitStyles(); } catch {} anim.cancel();
|
|
3968
3884
|
removeChild(WAAPIAnimationsLookups, nextLookup);
|
|
3969
3885
|
const lookupParent = nextLookup.parent;
|
|
@@ -3971,8 +3887,8 @@ const removeWAAPIAnimation = ($el, property, parent) => {
|
|
|
3971
3887
|
lookupParent._completed++;
|
|
3972
3888
|
if (lookupParent.animations.length === lookupParent._completed) {
|
|
3973
3889
|
lookupParent.completed = true;
|
|
3890
|
+
lookupParent.paused = true;
|
|
3974
3891
|
if (!lookupParent.muteCallbacks) {
|
|
3975
|
-
lookupParent.paused = true;
|
|
3976
3892
|
lookupParent.onComplete(lookupParent);
|
|
3977
3893
|
lookupParent._resolve(lookupParent);
|
|
3978
3894
|
}
|
|
@@ -3981,6 +3897,7 @@ const removeWAAPIAnimation = ($el, property, parent) => {
|
|
|
3981
3897
|
}
|
|
3982
3898
|
nextLookup = next;
|
|
3983
3899
|
}
|
|
3900
|
+
return anim;
|
|
3984
3901
|
};
|
|
3985
3902
|
|
|
3986
3903
|
/**
|
|
@@ -3989,7 +3906,7 @@ const removeWAAPIAnimation = ($el, property, parent) => {
|
|
|
3989
3906
|
* @param {String} property
|
|
3990
3907
|
* @param {PropertyIndexedKeyframes} keyframes
|
|
3991
3908
|
* @param {KeyframeAnimationOptions} params
|
|
3992
|
-
* @retun {Animation}
|
|
3909
|
+
* @retun {globalThis.Animation}
|
|
3993
3910
|
*/
|
|
3994
3911
|
const addWAAPIAnimation = (parent, $el, property, keyframes, params) => {
|
|
3995
3912
|
const animation = $el.animate(keyframes, params);
|
|
@@ -4004,8 +3921,11 @@ const addWAAPIAnimation = (parent, $el, property, keyframes, params) => {
|
|
|
4004
3921
|
removeWAAPIAnimation($el, property);
|
|
4005
3922
|
addChild(WAAPIAnimationsLookups, { parent, animation, $el, property, _next: null, _prev: null });
|
|
4006
3923
|
const handleRemove = () => { removeWAAPIAnimation($el, property, parent); };
|
|
3924
|
+
animation.oncancel = handleRemove;
|
|
4007
3925
|
animation.onremove = handleRemove;
|
|
4008
|
-
|
|
3926
|
+
if (!parent.persist) {
|
|
3927
|
+
animation.onfinish = handleRemove;
|
|
3928
|
+
}
|
|
4009
3929
|
return animation;
|
|
4010
3930
|
};
|
|
4011
3931
|
|
|
@@ -4633,8 +4553,10 @@ var numberImports = /*#__PURE__*/Object.freeze({
|
|
|
4633
4553
|
|
|
4634
4554
|
|
|
4635
4555
|
|
|
4556
|
+
|
|
4557
|
+
|
|
4636
4558
|
/*
|
|
4637
|
-
* Spring
|
|
4559
|
+
* Spring easing solver adapted from https://webkit.org/demos/spring/spring.js
|
|
4638
4560
|
* (c) 2016 Webkit - Apple Inc
|
|
4639
4561
|
*/
|
|
4640
4562
|
|
|
@@ -4645,25 +4567,46 @@ class Spring {
|
|
|
4645
4567
|
* @param {SpringParams} [parameters]
|
|
4646
4568
|
*/
|
|
4647
4569
|
constructor(parameters = {}) {
|
|
4570
|
+
const hasBounceOrDuration = !isUnd(parameters.bounce) || !isUnd(parameters.duration);
|
|
4648
4571
|
this.timeStep = .02; // Interval fed to the solver to calculate duration
|
|
4649
4572
|
this.restThreshold = .0005; // Values below this threshold are considered resting position
|
|
4650
4573
|
this.restDuration = 200; // Duration in ms used to check if the spring is resting after reaching restThreshold
|
|
4651
4574
|
this.maxDuration = 60000; // The maximum allowed spring duration in ms (default 1 min)
|
|
4652
4575
|
this.maxRestSteps = this.restDuration / this.timeStep / K; // How many steps allowed after reaching restThreshold before stopping the duration calculation
|
|
4653
4576
|
this.maxIterations = this.maxDuration / this.timeStep / K; // Calculate the maximum iterations allowed based on maxDuration
|
|
4654
|
-
this.
|
|
4655
|
-
this.
|
|
4656
|
-
this.
|
|
4577
|
+
this.bn = clamp$1(setValue(parameters.bounce, .5), -1, 1); // The bounce percentage between -1 and 1.
|
|
4578
|
+
this.pd = clamp$1(setValue(parameters.duration, 628), 10 * globals.timeScale, maxSpringParamValue * globals.timeScale); // The perceived duration
|
|
4579
|
+
this.m = clamp$1(setValue(parameters.mass, 1), 1, maxSpringParamValue);
|
|
4580
|
+
this.s = clamp$1(setValue(parameters.stiffness, 100), minValue, maxSpringParamValue);
|
|
4581
|
+
this.d = clamp$1(setValue(parameters.damping, 10), minValue, maxSpringParamValue);
|
|
4657
4582
|
this.v = clamp$1(setValue(parameters.velocity, 0), -maxSpringParamValue, maxSpringParamValue);
|
|
4658
4583
|
this.w0 = 0;
|
|
4659
4584
|
this.zeta = 0;
|
|
4660
4585
|
this.wd = 0;
|
|
4661
4586
|
this.b = 0;
|
|
4587
|
+
this.completed = false;
|
|
4662
4588
|
this.solverDuration = 0;
|
|
4663
|
-
this.
|
|
4589
|
+
this.settlingDuration = 0;
|
|
4590
|
+
/** @type {JSAnimation} */
|
|
4591
|
+
this.parent = null;
|
|
4592
|
+
/** @type {Callback<JSAnimation>} */
|
|
4593
|
+
this.onComplete = parameters.onComplete || noop;
|
|
4594
|
+
if (hasBounceOrDuration) this.calculateSDFromBD();
|
|
4664
4595
|
this.compute();
|
|
4665
4596
|
/** @type {EasingFunction} */
|
|
4666
|
-
this.ease = t =>
|
|
4597
|
+
this.ease = t => {
|
|
4598
|
+
const currentTime = t * this.settlingDuration;
|
|
4599
|
+
const completed = this.completed;
|
|
4600
|
+
const perceivedTime = this.pd;
|
|
4601
|
+
if (currentTime >= perceivedTime && !completed) {
|
|
4602
|
+
this.completed = true;
|
|
4603
|
+
this.onComplete(this.parent);
|
|
4604
|
+
}
|
|
4605
|
+
if (currentTime < perceivedTime && completed) {
|
|
4606
|
+
this.completed = false;
|
|
4607
|
+
}
|
|
4608
|
+
return t === 0 || t === 1 ? t : this.solve(t * this.solverDuration);
|
|
4609
|
+
};
|
|
4667
4610
|
}
|
|
4668
4611
|
|
|
4669
4612
|
/** @type {EasingFunction} */
|
|
@@ -4671,23 +4614,83 @@ class Spring {
|
|
|
4671
4614
|
const { zeta, w0, wd, b } = this;
|
|
4672
4615
|
let t = time;
|
|
4673
4616
|
if (zeta < 1) {
|
|
4617
|
+
// Underdamped
|
|
4674
4618
|
t = exp(-t * zeta * w0) * (1 * cos(wd * t) + b * sin(wd * t));
|
|
4675
|
-
} else {
|
|
4619
|
+
} else if (zeta === 1) {
|
|
4620
|
+
// Critically damped
|
|
4676
4621
|
t = (1 + b * t) * exp(-t * w0);
|
|
4622
|
+
} else {
|
|
4623
|
+
// Overdamped
|
|
4624
|
+
// Using exponential instead of cosh and sinh functions to prevent Infinity
|
|
4625
|
+
// Original exp(-zeta * w0 * t) * (cosh(wd * t) + b * sinh(wd * t))
|
|
4626
|
+
t = ((1 + b) * exp((-zeta * w0 + wd) * t) + (1 - b) * exp((-zeta * w0 - wd) * t)) / 2;
|
|
4677
4627
|
}
|
|
4678
4628
|
return 1 - t;
|
|
4679
4629
|
}
|
|
4680
4630
|
|
|
4631
|
+
calculateSDFromBD() {
|
|
4632
|
+
// Apple's SwiftUI perceived spring duration implementation https://developer.apple.com/videos/play/wwdc2023/10158/?time=1010
|
|
4633
|
+
// Equations taken from Kevin Grajeda's article https://www.kvin.me/posts/effortless-ui-spring-animations
|
|
4634
|
+
const pds = globals.timeScale === 1 ? this.pd / K : this.pd;
|
|
4635
|
+
// Mass and velocity should be set to their default values
|
|
4636
|
+
this.m = 1;
|
|
4637
|
+
this.v = 0;
|
|
4638
|
+
// Stiffness = (2π ÷ perceptualDuration)²
|
|
4639
|
+
this.s = pow((2 * PI) / pds, 2);
|
|
4640
|
+
if (this.bn >= 0) {
|
|
4641
|
+
// For bounce ≥ 0 (critically damped to underdamped)
|
|
4642
|
+
// damping = ((1 - bounce) × 4π) ÷ perceptualDuration
|
|
4643
|
+
this.d = ((1 - this.bn) * 4 * PI) / pds;
|
|
4644
|
+
} else {
|
|
4645
|
+
// For bounce < 0 (overdamped)
|
|
4646
|
+
// damping = 4π ÷ (perceptualDuration × (1 + bounce))
|
|
4647
|
+
// Note: (1 + bounce) is positive since bounce is negative
|
|
4648
|
+
this.d = (4 * PI) / (pds * (1 + this.bn));
|
|
4649
|
+
}
|
|
4650
|
+
this.s = round$1(clamp$1(this.s, minValue, maxSpringParamValue), 3);
|
|
4651
|
+
this.d = round$1(clamp$1(this.d, minValue, 300), 3); // Clamping to 300 is needed to prevent insane values in the solver
|
|
4652
|
+
}
|
|
4653
|
+
|
|
4654
|
+
calculateBDFromSD() {
|
|
4655
|
+
// Calculate perceived duration and bounce from stiffness and damping
|
|
4656
|
+
// Note: We assumes m = 1 and v = 0 for these calculations
|
|
4657
|
+
const pds = (2 * PI) / sqrt(this.s);
|
|
4658
|
+
this.pd = pds * (globals.timeScale === 1 ? K : 1);
|
|
4659
|
+
const zeta = this.d / (2 * sqrt(this.s));
|
|
4660
|
+
if (zeta <= 1) {
|
|
4661
|
+
// Critically damped to underdamped
|
|
4662
|
+
this.bn = 1 - (this.d * pds) / (4 * PI);
|
|
4663
|
+
} else {
|
|
4664
|
+
// Overdamped
|
|
4665
|
+
this.bn = (4 * PI) / (this.d * pds) - 1;
|
|
4666
|
+
}
|
|
4667
|
+
this.bn = round$1(clamp$1(this.bn, -1, 1), 3);
|
|
4668
|
+
this.pd = round$1(clamp$1(this.pd, 10 * globals.timeScale, maxSpringParamValue * globals.timeScale), 3);
|
|
4669
|
+
}
|
|
4670
|
+
|
|
4681
4671
|
compute() {
|
|
4682
4672
|
const { maxRestSteps, maxIterations, restThreshold, timeStep, m, d, s, v } = this;
|
|
4683
4673
|
const w0 = this.w0 = clamp$1(sqrt(s / m), minValue, K);
|
|
4684
|
-
const
|
|
4685
|
-
|
|
4686
|
-
|
|
4674
|
+
const bouncedZeta = this.zeta = d / (2 * sqrt(s * m));
|
|
4675
|
+
// Calculate wd based on damping type
|
|
4676
|
+
if (bouncedZeta < 1) {
|
|
4677
|
+
// Underdamped
|
|
4678
|
+
this.wd = w0 * sqrt(1 - bouncedZeta * bouncedZeta);
|
|
4679
|
+
this.b = (bouncedZeta * w0 + -v) / this.wd;
|
|
4680
|
+
} else if (bouncedZeta === 1) {
|
|
4681
|
+
// Critically damped
|
|
4682
|
+
this.wd = 0;
|
|
4683
|
+
this.b = -v + w0;
|
|
4684
|
+
} else {
|
|
4685
|
+
// Overdamped
|
|
4686
|
+
this.wd = w0 * sqrt(bouncedZeta * bouncedZeta - 1);
|
|
4687
|
+
this.b = (bouncedZeta * w0 + -v) / this.wd;
|
|
4688
|
+
}
|
|
4689
|
+
|
|
4687
4690
|
let solverTime = 0;
|
|
4688
4691
|
let restSteps = 0;
|
|
4689
4692
|
let iterations = 0;
|
|
4690
|
-
while (restSteps
|
|
4693
|
+
while (restSteps <= maxRestSteps && iterations <= maxIterations) {
|
|
4691
4694
|
if (abs(1 - this.solve(solverTime)) < restThreshold) {
|
|
4692
4695
|
restSteps++;
|
|
4693
4696
|
} else {
|
|
@@ -4697,15 +4700,26 @@ class Spring {
|
|
|
4697
4700
|
solverTime += timeStep;
|
|
4698
4701
|
iterations++;
|
|
4699
4702
|
}
|
|
4700
|
-
this.
|
|
4703
|
+
this.settlingDuration = round$1(this.solverDuration * K, 0) * globals.timeScale;
|
|
4701
4704
|
}
|
|
4702
4705
|
|
|
4703
|
-
get
|
|
4704
|
-
return this.
|
|
4706
|
+
get bounce() {
|
|
4707
|
+
return this.bn;
|
|
4705
4708
|
}
|
|
4706
4709
|
|
|
4707
|
-
set
|
|
4708
|
-
this.
|
|
4710
|
+
set bounce(v) {
|
|
4711
|
+
this.bn = clamp$1(setValue(v, 1), -1, 1);
|
|
4712
|
+
this.calculateSDFromBD();
|
|
4713
|
+
this.compute();
|
|
4714
|
+
}
|
|
4715
|
+
|
|
4716
|
+
get duration() {
|
|
4717
|
+
return this.pd;
|
|
4718
|
+
}
|
|
4719
|
+
|
|
4720
|
+
set duration(v) {
|
|
4721
|
+
this.pd = clamp$1(setValue(v, 1), 10 * globals.timeScale, maxSpringParamValue * globals.timeScale);
|
|
4722
|
+
this.calculateSDFromBD();
|
|
4709
4723
|
this.compute();
|
|
4710
4724
|
}
|
|
4711
4725
|
|
|
@@ -4714,7 +4728,8 @@ class Spring {
|
|
|
4714
4728
|
}
|
|
4715
4729
|
|
|
4716
4730
|
set stiffness(v) {
|
|
4717
|
-
this.s = clamp$1(setValue(v, 100),
|
|
4731
|
+
this.s = clamp$1(setValue(v, 100), minValue, maxSpringParamValue);
|
|
4732
|
+
this.calculateBDFromSD();
|
|
4718
4733
|
this.compute();
|
|
4719
4734
|
}
|
|
4720
4735
|
|
|
@@ -4723,7 +4738,17 @@ class Spring {
|
|
|
4723
4738
|
}
|
|
4724
4739
|
|
|
4725
4740
|
set damping(v) {
|
|
4726
|
-
this.d = clamp$1(setValue(v, 10),
|
|
4741
|
+
this.d = clamp$1(setValue(v, 10), minValue, maxSpringParamValue);
|
|
4742
|
+
this.calculateBDFromSD();
|
|
4743
|
+
this.compute();
|
|
4744
|
+
}
|
|
4745
|
+
|
|
4746
|
+
get mass() {
|
|
4747
|
+
return this.m;
|
|
4748
|
+
}
|
|
4749
|
+
|
|
4750
|
+
set mass(v) {
|
|
4751
|
+
this.m = clamp$1(setValue(v, 1), 1, maxSpringParamValue);
|
|
4727
4752
|
this.compute();
|
|
4728
4753
|
}
|
|
4729
4754
|
|
|
@@ -4741,7 +4766,18 @@ class Spring {
|
|
|
4741
4766
|
* @param {SpringParams} [parameters]
|
|
4742
4767
|
* @returns {Spring}
|
|
4743
4768
|
*/
|
|
4744
|
-
const
|
|
4769
|
+
const spring = (parameters) => new Spring(parameters);
|
|
4770
|
+
|
|
4771
|
+
/**
|
|
4772
|
+
* @deprecated createSpring() is deprecated use spring() instead
|
|
4773
|
+
*
|
|
4774
|
+
* @param {SpringParams} [parameters]
|
|
4775
|
+
* @returns {Spring}
|
|
4776
|
+
*/
|
|
4777
|
+
const createSpring = (parameters) => {
|
|
4778
|
+
console.warn('createSpring() is deprecated use spring() instead');
|
|
4779
|
+
return new Spring(parameters);
|
|
4780
|
+
};
|
|
4745
4781
|
|
|
4746
4782
|
|
|
4747
4783
|
|
|
@@ -4922,13 +4958,13 @@ class Draggable {
|
|
|
4922
4958
|
/** @type {Boolean|DraggableCursorParams} */
|
|
4923
4959
|
this.cursor = false;
|
|
4924
4960
|
/** @type {Spring} */
|
|
4925
|
-
this.releaseXSpring = hasSpring ? /** @type {Spring} */(ease) :
|
|
4961
|
+
this.releaseXSpring = hasSpring ? /** @type {Spring} */(ease) : spring({
|
|
4926
4962
|
mass: setValue(parameters.releaseMass, 1),
|
|
4927
4963
|
stiffness: setValue(parameters.releaseStiffness, 80),
|
|
4928
4964
|
damping: setValue(parameters.releaseDamping, 20),
|
|
4929
4965
|
});
|
|
4930
4966
|
/** @type {Spring} */
|
|
4931
|
-
this.releaseYSpring = hasSpring ? /** @type {Spring} */(ease) :
|
|
4967
|
+
this.releaseYSpring = 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),
|
|
@@ -5645,8 +5681,8 @@ class Draggable {
|
|
|
5645
5681
|
this.$trigger.addEventListener('touchmove', preventDefault, { passive: false });
|
|
5646
5682
|
this.$trigger.addEventListener('touchend', preventDefault);
|
|
5647
5683
|
|
|
5648
|
-
|
|
5649
|
-
if ((!this.disabled[0] && abs(movedX) > 3) || (!this.disabled[1] && abs(movedY) > 3)) {
|
|
5684
|
+
// Don't check for a miminim distance move if already dragging
|
|
5685
|
+
if (this.dragged || (!this.disabled[0] && abs(movedX) > 3) || (!this.disabled[1] && abs(movedY) > 3)) {
|
|
5650
5686
|
|
|
5651
5687
|
this.updateTicker.resume();
|
|
5652
5688
|
this.pointer[2] = this.pointer[0];
|
|
@@ -5712,8 +5748,8 @@ class Draggable {
|
|
|
5712
5748
|
const directionX = dx === cr ? cx > cr ? -1 : 1 : cx < cl ? -1 : 1;
|
|
5713
5749
|
const distanceX = round$1(cx - dx, 0);
|
|
5714
5750
|
springX.velocity = disabledY && hasReleaseSpring ? distanceX ? (ds * directionX) / abs(distanceX) : 0 : pv;
|
|
5715
|
-
const { ease,
|
|
5716
|
-
durationX = cx === dx ? 0 : hasReleaseSpring ?
|
|
5751
|
+
const { ease, settlingDuration, restDuration } = springX;
|
|
5752
|
+
durationX = cx === dx ? 0 : hasReleaseSpring ? settlingDuration : settlingDuration - (restDuration * globals.timeScale);
|
|
5717
5753
|
if (hasReleaseSpring) easeX = ease;
|
|
5718
5754
|
if (durationX > longestReleaseDuration) longestReleaseDuration = durationX;
|
|
5719
5755
|
}
|
|
@@ -5722,8 +5758,8 @@ class Draggable {
|
|
|
5722
5758
|
const directionY = dy === cb ? cy > cb ? -1 : 1 : cy < ct ? -1 : 1;
|
|
5723
5759
|
const distanceY = round$1(cy - dy, 0);
|
|
5724
5760
|
springY.velocity = disabledX && hasReleaseSpring ? distanceY ? (ds * directionY) / abs(distanceY) : 0 : pv;
|
|
5725
|
-
const { ease,
|
|
5726
|
-
durationY = cy === dy ? 0 : hasReleaseSpring ?
|
|
5761
|
+
const { ease, settlingDuration, restDuration } = springY;
|
|
5762
|
+
durationY = cy === dy ? 0 : hasReleaseSpring ? settlingDuration : settlingDuration - (restDuration * globals.timeScale);
|
|
5727
5763
|
if (hasReleaseSpring) easeY = ease;
|
|
5728
5764
|
if (durationY > longestReleaseDuration) longestReleaseDuration = durationY;
|
|
5729
5765
|
}
|
|
@@ -6576,6 +6612,8 @@ class ScrollObserver {
|
|
|
6576
6612
|
/** @type {Boolean} */
|
|
6577
6613
|
this.reverted = false;
|
|
6578
6614
|
/** @type {Boolean} */
|
|
6615
|
+
this.ready = false;
|
|
6616
|
+
/** @type {Boolean} */
|
|
6579
6617
|
this.completed = false;
|
|
6580
6618
|
/** @type {Boolean} */
|
|
6581
6619
|
this.began = false;
|
|
@@ -6585,8 +6623,6 @@ class ScrollObserver {
|
|
|
6585
6623
|
this.forceEnter = false;
|
|
6586
6624
|
/** @type {Boolean} */
|
|
6587
6625
|
this.hasEntered = false;
|
|
6588
|
-
// /** @type {Array.<Number>} */
|
|
6589
|
-
// this.offsets = [];
|
|
6590
6626
|
/** @type {Number} */
|
|
6591
6627
|
this.offset = 0;
|
|
6592
6628
|
/** @type {Number} */
|
|
@@ -6634,6 +6670,8 @@ class ScrollObserver {
|
|
|
6634
6670
|
// Make sure to pause the linked object in case it's added later
|
|
6635
6671
|
linked.pause();
|
|
6636
6672
|
this.linked = linked;
|
|
6673
|
+
// Forces WAAPI Animation to persist; otherwise, they will stop syncing on finish.
|
|
6674
|
+
if (!isUnd(/** @type {WAAPIAnimation} */(linked))) /** @type {WAAPIAnimation} */(linked).persist = true;
|
|
6637
6675
|
// Try to use a target of the linked object if no target parameters specified
|
|
6638
6676
|
if (!this._params.target) {
|
|
6639
6677
|
/** @type {HTMLElement} */
|
|
@@ -6673,6 +6711,8 @@ class ScrollObserver {
|
|
|
6673
6711
|
}
|
|
6674
6712
|
|
|
6675
6713
|
refresh() {
|
|
6714
|
+
// This flag is used to prevent running handleScroll() outside of this.refresh() with values not yet calculated
|
|
6715
|
+
this.ready = true;
|
|
6676
6716
|
this.reverted = false;
|
|
6677
6717
|
const params = this._params;
|
|
6678
6718
|
this.repeat = setValue(parseScrollObserverFunctionParameter(params.repeat, this), true);
|
|
@@ -6918,8 +6958,6 @@ class ScrollObserver {
|
|
|
6918
6958
|
const offsetStart = parsedEnterTarget + offset - parsedEnterContainer;
|
|
6919
6959
|
const offsetEnd = parsedLeaveTarget + offset - parsedLeaveContainer;
|
|
6920
6960
|
const scrollDelta = offsetEnd - offsetStart;
|
|
6921
|
-
// this.offsets[0] = offsetX;
|
|
6922
|
-
// this.offsets[1] = offsetY;
|
|
6923
6961
|
this.offset = offset;
|
|
6924
6962
|
this.offsetStart = offsetStart;
|
|
6925
6963
|
this.offsetEnd = offsetEnd;
|
|
@@ -6938,6 +6976,7 @@ class ScrollObserver {
|
|
|
6938
6976
|
}
|
|
6939
6977
|
|
|
6940
6978
|
handleScroll() {
|
|
6979
|
+
if (!this.ready) return;
|
|
6941
6980
|
const linked = this.linked;
|
|
6942
6981
|
const sync = this.sync;
|
|
6943
6982
|
const syncEase = this.syncEase;
|
|
@@ -7061,6 +7100,7 @@ class ScrollObserver {
|
|
|
7061
7100
|
this.removeDebug();
|
|
7062
7101
|
}
|
|
7063
7102
|
this.reverted = true;
|
|
7103
|
+
this.ready = false;
|
|
7064
7104
|
return this;
|
|
7065
7105
|
}
|
|
7066
7106
|
|
|
@@ -7072,13 +7112,142 @@ class ScrollObserver {
|
|
|
7072
7112
|
*/
|
|
7073
7113
|
const onScroll = (parameters = {}) => new ScrollObserver(parameters);
|
|
7074
7114
|
|
|
7115
|
+
|
|
7116
|
+
|
|
7117
|
+
/**
|
|
7118
|
+
* Cubic Bezier solver adapted from https://github.com/gre/bezier-easing
|
|
7119
|
+
* (c) 2014 Gaëtan Renaudeau
|
|
7120
|
+
*/
|
|
7121
|
+
|
|
7122
|
+
/**
|
|
7123
|
+
* @param {Number} aT
|
|
7124
|
+
* @param {Number} aA1
|
|
7125
|
+
* @param {Number} aA2
|
|
7126
|
+
* @return {Number}
|
|
7127
|
+
*/
|
|
7128
|
+
const calcBezier = (aT, aA1, aA2) => (((1 - 3 * aA2 + 3 * aA1) * aT + (3 * aA2 - 6 * aA1)) * aT + (3 * aA1)) * aT;
|
|
7129
|
+
|
|
7130
|
+
/**
|
|
7131
|
+
* @param {Number} aX
|
|
7132
|
+
* @param {Number} mX1
|
|
7133
|
+
* @param {Number} mX2
|
|
7134
|
+
* @return {Number}
|
|
7135
|
+
*/
|
|
7136
|
+
const binarySubdivide = (aX, mX1, mX2) => {
|
|
7137
|
+
let aA = 0, aB = 1, currentX, currentT, i = 0;
|
|
7138
|
+
do {
|
|
7139
|
+
currentT = aA + (aB - aA) / 2;
|
|
7140
|
+
currentX = calcBezier(currentT, mX1, mX2) - aX;
|
|
7141
|
+
if (currentX > 0) {
|
|
7142
|
+
aB = currentT;
|
|
7143
|
+
} else {
|
|
7144
|
+
aA = currentT;
|
|
7145
|
+
}
|
|
7146
|
+
} while (abs(currentX) > .0000001 && ++i < 100);
|
|
7147
|
+
return currentT;
|
|
7148
|
+
};
|
|
7149
|
+
|
|
7150
|
+
/**
|
|
7151
|
+
* @param {Number} [mX1] The x coordinate of the first point
|
|
7152
|
+
* @param {Number} [mY1] The y coordinate of the first point
|
|
7153
|
+
* @param {Number} [mX2] The x coordinate of the second point
|
|
7154
|
+
* @param {Number} [mY2] The y coordinate of the second point
|
|
7155
|
+
* @return {EasingFunction}
|
|
7156
|
+
*/
|
|
7157
|
+
|
|
7158
|
+
const cubicBezier = (mX1 = 0.5, mY1 = 0.0, mX2 = 0.5, mY2 = 1.0) => (mX1 === mY1 && mX2 === mY2) ? none :
|
|
7159
|
+
t => t === 0 || t === 1 ? t :
|
|
7160
|
+
calcBezier(binarySubdivide(t, mX1, mX2), mY1, mY2);
|
|
7161
|
+
|
|
7162
|
+
|
|
7163
|
+
|
|
7164
|
+
/**
|
|
7165
|
+
* Steps ease implementation https://developer.mozilla.org/fr/docs/Web/CSS/transition-timing-function
|
|
7166
|
+
* Only covers 'end' and 'start' jumpterms
|
|
7167
|
+
* @param {Number} steps
|
|
7168
|
+
* @param {Boolean} [fromStart]
|
|
7169
|
+
* @return {EasingFunction}
|
|
7170
|
+
*/
|
|
7171
|
+
const steps = (steps = 10, fromStart) => {
|
|
7172
|
+
const roundMethod = fromStart ? ceil : floor;
|
|
7173
|
+
return t => roundMethod(clamp$1(t, 0, 1) * steps) * (1 / steps);
|
|
7174
|
+
};
|
|
7175
|
+
|
|
7176
|
+
|
|
7177
|
+
|
|
7178
|
+
/**
|
|
7179
|
+
* Without parameters, the linear function creates a non-eased transition.
|
|
7180
|
+
* Parameters, if used, creates a piecewise linear easing by interpolating linearly between the specified points.
|
|
7181
|
+
*
|
|
7182
|
+
* @param {...(String|Number)} args - Points
|
|
7183
|
+
* @return {EasingFunction}
|
|
7184
|
+
*/
|
|
7185
|
+
const linear = (...args) => {
|
|
7186
|
+
const argsLength = args.length;
|
|
7187
|
+
if (!argsLength) return none;
|
|
7188
|
+
const totalPoints = argsLength - 1;
|
|
7189
|
+
const firstArg = args[0];
|
|
7190
|
+
const lastArg = args[totalPoints];
|
|
7191
|
+
const xPoints = [0];
|
|
7192
|
+
const yPoints = [parseNumber(firstArg)];
|
|
7193
|
+
for (let i = 1; i < totalPoints; i++) {
|
|
7194
|
+
const arg = args[i];
|
|
7195
|
+
const splitValue = isStr(arg) ?
|
|
7196
|
+
/** @type {String} */(arg).trim().split(' ') :
|
|
7197
|
+
[arg];
|
|
7198
|
+
const value = splitValue[0];
|
|
7199
|
+
const percent = splitValue[1];
|
|
7200
|
+
xPoints.push(!isUnd(percent) ? parseNumber(percent) / 100 : i / totalPoints);
|
|
7201
|
+
yPoints.push(parseNumber(value));
|
|
7202
|
+
}
|
|
7203
|
+
yPoints.push(parseNumber(lastArg));
|
|
7204
|
+
xPoints.push(1);
|
|
7205
|
+
return function easeLinear(t) {
|
|
7206
|
+
for (let i = 1, l = xPoints.length; i < l; i++) {
|
|
7207
|
+
const currentX = xPoints[i];
|
|
7208
|
+
if (t <= currentX) {
|
|
7209
|
+
const prevX = xPoints[i - 1];
|
|
7210
|
+
const prevY = yPoints[i - 1];
|
|
7211
|
+
return prevY + (yPoints[i] - prevY) * (t - prevX) / (currentX - prevX);
|
|
7212
|
+
}
|
|
7213
|
+
}
|
|
7214
|
+
return yPoints[yPoints.length - 1];
|
|
7215
|
+
}
|
|
7216
|
+
};
|
|
7217
|
+
|
|
7218
|
+
|
|
7219
|
+
|
|
7220
|
+
/**
|
|
7221
|
+
* Generate random steps
|
|
7222
|
+
* @param {Number} [length] - The number of steps
|
|
7223
|
+
* @param {Number} [randomness] - How strong the randomness is
|
|
7224
|
+
* @return {EasingFunction}
|
|
7225
|
+
*/
|
|
7226
|
+
const irregular = (length = 10, randomness = 1) => {
|
|
7227
|
+
const values = [0];
|
|
7228
|
+
const total = length - 1;
|
|
7229
|
+
for (let i = 1; i < total; i++) {
|
|
7230
|
+
const previousValue = values[i - 1];
|
|
7231
|
+
const spacing = i / total;
|
|
7232
|
+
const segmentEnd = (i + 1) / total;
|
|
7233
|
+
const randomVariation = spacing + (segmentEnd - spacing) * Math.random();
|
|
7234
|
+
// Mix the even spacing and random variation based on the randomness parameter
|
|
7235
|
+
const randomValue = spacing * (1 - randomness) + randomVariation * randomness;
|
|
7236
|
+
values.push(clamp$1(randomValue, previousValue, 1));
|
|
7237
|
+
}
|
|
7238
|
+
values.push(1);
|
|
7239
|
+
return linear(...values);
|
|
7240
|
+
};
|
|
7241
|
+
|
|
7075
7242
|
var index$3 = /*#__PURE__*/Object.freeze({
|
|
7076
7243
|
__proto__: null,
|
|
7244
|
+
Spring: Spring,
|
|
7245
|
+
createSpring: createSpring,
|
|
7077
7246
|
cubicBezier: cubicBezier,
|
|
7078
7247
|
eases: eases,
|
|
7079
7248
|
irregular: irregular,
|
|
7080
7249
|
linear: linear,
|
|
7081
|
-
|
|
7250
|
+
spring: spring,
|
|
7082
7251
|
steps: steps
|
|
7083
7252
|
});
|
|
7084
7253
|
|
|
@@ -8134,21 +8303,11 @@ var index = /*#__PURE__*/Object.freeze({
|
|
|
8134
8303
|
*/
|
|
8135
8304
|
const easingToLinear = (fn, samples = 100) => {
|
|
8136
8305
|
const points = [];
|
|
8137
|
-
for (let i = 0; i <= samples; i++) points.push(fn(i / samples));
|
|
8306
|
+
for (let i = 0; i <= samples; i++) points.push(round$1(fn(i / samples), 4));
|
|
8138
8307
|
return `linear(${points.join(', ')})`;
|
|
8139
8308
|
};
|
|
8140
8309
|
|
|
8141
|
-
const WAAPIEasesLookups = {
|
|
8142
|
-
in: 'ease-in',
|
|
8143
|
-
out: 'ease-out',
|
|
8144
|
-
inOut: 'ease-in-out',
|
|
8145
|
-
};
|
|
8146
|
-
|
|
8147
|
-
const WAAPIeases = /*#__PURE__*/(() => {
|
|
8148
|
-
const list = {};
|
|
8149
|
-
for (let type in easeTypes) list[type] = (/** @type {String|Number} */p) => easeTypes[type](easeInPower(p));
|
|
8150
|
-
return /** @type {Record<String, EasingFunction>} */(list);
|
|
8151
|
-
})();
|
|
8310
|
+
const WAAPIEasesLookups = {};
|
|
8152
8311
|
|
|
8153
8312
|
/**
|
|
8154
8313
|
* @param {EasingParam} ease
|
|
@@ -8169,9 +8328,10 @@ const parseWAAPIEasing = (ease) => {
|
|
|
8169
8328
|
} else if (stringStartsWith(ease, 'cubicB')) {
|
|
8170
8329
|
parsedEase = toLowerCase(ease);
|
|
8171
8330
|
} else {
|
|
8172
|
-
const parsed = parseEaseString(ease
|
|
8331
|
+
const parsed = parseEaseString(ease);
|
|
8173
8332
|
if (isFnc(parsed)) parsedEase = parsed === none ? 'linear' : easingToLinear(parsed);
|
|
8174
8333
|
}
|
|
8334
|
+
// Only cache string based easing name, otherwise function arguments get lost
|
|
8175
8335
|
WAAPIEasesLookups[ease] = parsedEase;
|
|
8176
8336
|
} else if (isFnc(ease)) {
|
|
8177
8337
|
const easing = easingToLinear(ease);
|
|
@@ -8212,7 +8372,8 @@ let transformsPropertiesRegistered = null;
|
|
|
8212
8372
|
* @return {String}
|
|
8213
8373
|
*/
|
|
8214
8374
|
const normalizeTweenValue = (propName, value, $el, i, targetsLength) => {
|
|
8215
|
-
|
|
8375
|
+
// Do not try to compute strings with getFunctionValue otherwise it will convert CSS variables
|
|
8376
|
+
let v = isStr(value) ? value : getFunctionValue(/** @type {any} */(value), $el, i, targetsLength);
|
|
8216
8377
|
if (!isNum(v)) return v;
|
|
8217
8378
|
if (commonDefaultPXProperties.includes(propName) || stringStartsWith(propName, 'translate')) return `${v}px`;
|
|
8218
8379
|
if (stringStartsWith(propName, 'rotate') || stringStartsWith(propName, 'skew')) return `${v}deg`;
|
|
@@ -8292,7 +8453,7 @@ class WAAPIAnimation {
|
|
|
8292
8453
|
/** @type {PlaybackDirection} */
|
|
8293
8454
|
const direction = alternate ? reversed ? 'alternate-reverse' : 'alternate' : reversed ? 'reverse' : 'normal';
|
|
8294
8455
|
/** @type {FillMode} */
|
|
8295
|
-
const fill = '
|
|
8456
|
+
const fill = 'both'; // We use 'both' here because the animation can be reversed during playback
|
|
8296
8457
|
/** @type {String} */
|
|
8297
8458
|
const easing = parseWAAPIEasing(ease);
|
|
8298
8459
|
const timeScale = (globals.timeScale === 1 ? 1 : K);
|
|
@@ -8304,7 +8465,7 @@ class WAAPIAnimation {
|
|
|
8304
8465
|
/** @type {globalThis.Animation}] */
|
|
8305
8466
|
this.controlAnimation = null;
|
|
8306
8467
|
/** @type {Callback<this>} */
|
|
8307
|
-
this.onComplete = params.onComplete ||
|
|
8468
|
+
this.onComplete = params.onComplete || /** @type {Callback<WAAPIAnimation>} */(/** @type {unknown} */(globals.defaults.onComplete));
|
|
8308
8469
|
/** @type {Number} */
|
|
8309
8470
|
this.duration = 0;
|
|
8310
8471
|
/** @type {Boolean} */
|
|
@@ -8315,6 +8476,8 @@ class WAAPIAnimation {
|
|
|
8315
8476
|
this.paused = !autoplay || scroll !== false;
|
|
8316
8477
|
/** @type {Boolean} */
|
|
8317
8478
|
this.reversed = reversed;
|
|
8479
|
+
/** @type {Boolean} */
|
|
8480
|
+
this.persist = setValue(params.persist, globals.defaults.persist);
|
|
8318
8481
|
/** @type {Boolean|ScrollObserver} */
|
|
8319
8482
|
this.autoplay = autoplay;
|
|
8320
8483
|
/** @type {Number} */
|
|
@@ -8323,17 +8486,18 @@ class WAAPIAnimation {
|
|
|
8323
8486
|
this._resolve = noop; // Used by .then()
|
|
8324
8487
|
/** @type {Number} */
|
|
8325
8488
|
this._completed = 0;
|
|
8326
|
-
/** @type {Array
|
|
8327
|
-
this._inlineStyles =
|
|
8489
|
+
/** @type {Array.<Object>} */
|
|
8490
|
+
this._inlineStyles = [];
|
|
8328
8491
|
|
|
8329
8492
|
parsedTargets.forEach(($el, i) => {
|
|
8330
8493
|
|
|
8331
8494
|
const cachedTransforms = $el[transformsSymbol];
|
|
8332
|
-
|
|
8333
8495
|
const hasIndividualTransforms = validIndividualTransforms.some(t => params.hasOwnProperty(t));
|
|
8496
|
+
const elStyle = $el.style;
|
|
8497
|
+
const inlineStyles = this._inlineStyles[i] = {};
|
|
8334
8498
|
|
|
8335
8499
|
/** @type {Number} */
|
|
8336
|
-
const duration = (spring ? /** @type {Spring} */(spring).
|
|
8500
|
+
const duration = (spring ? /** @type {Spring} */(spring).settlingDuration : getFunctionValue(setValue(params.duration, globals.defaults.duration), $el, i, targetsLength)) * timeScale;
|
|
8337
8501
|
/** @type {Number} */
|
|
8338
8502
|
const delay = getFunctionValue(setValue(params.delay, globals.defaults.delay), $el, i, targetsLength) * timeScale;
|
|
8339
8503
|
/** @type {CompositeOperation} */
|
|
@@ -8347,6 +8511,12 @@ class WAAPIAnimation {
|
|
|
8347
8511
|
const tweenParams = { iterations, direction, fill, easing, duration, delay, composite };
|
|
8348
8512
|
const propertyValue = params[name];
|
|
8349
8513
|
const individualTransformProperty = hasIndividualTransforms ? validTransforms.includes(name) ? name : shortTransforms.get(name) : false;
|
|
8514
|
+
|
|
8515
|
+
const styleName = individualTransformProperty ? 'transform' : name;
|
|
8516
|
+
if (!inlineStyles[styleName]) {
|
|
8517
|
+
inlineStyles[styleName] = elStyle[styleName];
|
|
8518
|
+
}
|
|
8519
|
+
|
|
8350
8520
|
let parsedPropertyValue;
|
|
8351
8521
|
if (isObj(propertyValue)) {
|
|
8352
8522
|
const tweenOptions = /** @type {WAAPITweenOptions} */(propertyValue);
|
|
@@ -8355,7 +8525,7 @@ class WAAPIAnimation {
|
|
|
8355
8525
|
const to = /** @type {WAAPITweenOptions} */(tweenOptions).to;
|
|
8356
8526
|
const from = /** @type {WAAPITweenOptions} */(tweenOptions).from;
|
|
8357
8527
|
/** @type {Number} */
|
|
8358
|
-
tweenParams.duration = (tweenOptionsSpring ? /** @type {Spring} */(tweenOptionsSpring).
|
|
8528
|
+
tweenParams.duration = (tweenOptionsSpring ? /** @type {Spring} */(tweenOptionsSpring).settlingDuration : getFunctionValue(setValue(tweenOptions.duration, duration), $el, i, targetsLength)) * timeScale;
|
|
8359
8529
|
/** @type {Number} */
|
|
8360
8530
|
tweenParams.delay = getFunctionValue(setValue(tweenOptions.delay, delay), $el, i, targetsLength) * timeScale;
|
|
8361
8531
|
/** @type {CompositeOperation} */
|
|
@@ -8372,10 +8542,10 @@ class WAAPIAnimation {
|
|
|
8372
8542
|
addWAAPIAnimation(this, $el, name, keyframes, tweenParams);
|
|
8373
8543
|
if (!isUnd(from)) {
|
|
8374
8544
|
if (!individualTransformProperty) {
|
|
8375
|
-
|
|
8545
|
+
elStyle[name] = keyframes[name][0];
|
|
8376
8546
|
} else {
|
|
8377
8547
|
const key = `--${individualTransformProperty}`;
|
|
8378
|
-
|
|
8548
|
+
elStyle.setProperty(key, keyframes[key][0]);
|
|
8379
8549
|
}
|
|
8380
8550
|
}
|
|
8381
8551
|
} else {
|
|
@@ -8396,7 +8566,7 @@ class WAAPIAnimation {
|
|
|
8396
8566
|
for (let t in cachedTransforms) {
|
|
8397
8567
|
transforms += `${transformsFragmentStrings[t]}var(--${t})) `;
|
|
8398
8568
|
}
|
|
8399
|
-
|
|
8569
|
+
elStyle.transform = transforms;
|
|
8400
8570
|
}
|
|
8401
8571
|
});
|
|
8402
8572
|
|
|
@@ -8441,7 +8611,8 @@ class WAAPIAnimation {
|
|
|
8441
8611
|
// Make sure the animation playState is not 'paused' in order to properly trigger an onfinish callback.
|
|
8442
8612
|
// 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.
|
|
8443
8613
|
// https://developer.mozilla.org/en-US/docs/Web/API/Animation/finish_event
|
|
8444
|
-
|
|
8614
|
+
// This is not needed for persisting animations since they never finish.
|
|
8615
|
+
if (!this.persist && t >= this.duration) anim.play();
|
|
8445
8616
|
anim.currentTime = t;
|
|
8446
8617
|
});
|
|
8447
8618
|
}
|
|
@@ -8511,13 +8682,30 @@ class WAAPIAnimation {
|
|
|
8511
8682
|
}
|
|
8512
8683
|
|
|
8513
8684
|
cancel() {
|
|
8514
|
-
this.
|
|
8515
|
-
return this.
|
|
8685
|
+
this.muteCallbacks = true; // This prevents triggering the onComplete callback and resolving the Promise
|
|
8686
|
+
return this.commitStyles().forEach('cancel');
|
|
8516
8687
|
}
|
|
8517
8688
|
|
|
8518
8689
|
revert() {
|
|
8519
|
-
|
|
8520
|
-
|
|
8690
|
+
// NOTE: We need a better way to revert the transforms, since right now the entire transform property value is reverted,
|
|
8691
|
+
// This means if you have multiple animations animating different transforms on the same target,
|
|
8692
|
+
// reverting one of them will also override the transform property of the other animations.
|
|
8693
|
+
// A better approach would be to store the original custom property values is they exist instead of the entire transform value,
|
|
8694
|
+
// and update the CSS variables with the orignal value
|
|
8695
|
+
this.cancel().targets.forEach(($el, i) => {
|
|
8696
|
+
const targetStyle = $el.style;
|
|
8697
|
+
const targetInlineStyles = this._inlineStyles[i];
|
|
8698
|
+
for (let name in targetInlineStyles) {
|
|
8699
|
+
const originalInlinedValue = targetInlineStyles[name];
|
|
8700
|
+
if (isUnd(originalInlinedValue) || originalInlinedValue === emptyString) {
|
|
8701
|
+
targetStyle.removeProperty(toLowerCase(name));
|
|
8702
|
+
} else {
|
|
8703
|
+
targetStyle[name] = originalInlinedValue;
|
|
8704
|
+
}
|
|
8705
|
+
}
|
|
8706
|
+
// Remove style attribute if empty
|
|
8707
|
+
if ($el.getAttribute('style') === emptyString) $el.removeAttribute('style');
|
|
8708
|
+
});
|
|
8521
8709
|
return this;
|
|
8522
8710
|
}
|
|
8523
8711
|
|
|
@@ -8551,4 +8739,4 @@ const waapi = {
|
|
|
8551
8739
|
convertEase: easingToLinear
|
|
8552
8740
|
};
|
|
8553
8741
|
|
|
8554
|
-
export { registerTargets as $, Animatable, Draggable, JSAnimation, Scope, ScrollObserver, Spring, TextSplitter, Timeline, Timer, WAAPIAnimation, animate, clamp, cleanInlineStyles, createAnimatable, createDraggable, createDrawable, createMotionPath, createScope, createSeededRandom, createSpring, createTimeline, createTimer, cubicBezier, damp, degToRad, eases, index$3 as easings, engine, get, irregular, keepTime, lerp, linear, mapRange, morphTo,
|
|
8742
|
+
export { registerTargets as $, Animatable, Draggable, JSAnimation, Scope, ScrollObserver, Spring, TextSplitter, Timeline, Timer, WAAPIAnimation, animate, clamp, cleanInlineStyles, createAnimatable, createDraggable, createDrawable, createMotionPath, createScope, createSeededRandom, createSpring, createTimeline, createTimer, cubicBezier, damp, degToRad, eases, index$3 as easings, engine, get, irregular, keepTime, lerp, linear, mapRange, morphTo, onScroll, padEnd, padStart, radToDeg, random, randomPick, remove, round, roundPad, scrollContainers, set, shuffle, snap, split, splitText, spring, stagger, steps, index$1 as svg, sync, index as text, index$2 as utils, waapi, wrap };
|