animejs 4.2.0-beta.0 → 4.2.1

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.
Files changed (147) hide show
  1. package/README.md +6 -1
  2. package/dist/bundles/anime.esm.js +543 -304
  3. package/dist/bundles/anime.esm.min.js +2 -2
  4. package/dist/bundles/anime.umd.js +544 -305
  5. package/dist/bundles/anime.umd.min.js +2 -2
  6. package/dist/modules/animatable/animatable.cjs +4 -4
  7. package/dist/modules/animatable/animatable.js +3 -3
  8. package/dist/modules/animatable/index.cjs +1 -1
  9. package/dist/modules/animatable/index.js +1 -1
  10. package/dist/modules/animation/additive.cjs +1 -1
  11. package/dist/modules/animation/additive.js +1 -1
  12. package/dist/modules/animation/animation.cjs +28 -17
  13. package/dist/modules/animation/animation.d.ts +8 -5
  14. package/dist/modules/animation/animation.js +27 -16
  15. package/dist/modules/animation/composition.cjs +1 -1
  16. package/dist/modules/animation/composition.js +1 -1
  17. package/dist/modules/animation/index.cjs +1 -1
  18. package/dist/modules/animation/index.js +1 -1
  19. package/dist/modules/core/clock.cjs +1 -1
  20. package/dist/modules/core/clock.js +1 -1
  21. package/dist/modules/core/colors.cjs +1 -1
  22. package/dist/modules/core/colors.js +1 -1
  23. package/dist/modules/core/consts.cjs +7 -2
  24. package/dist/modules/core/consts.d.ts +2 -0
  25. package/dist/modules/core/consts.js +6 -3
  26. package/dist/modules/core/globals.cjs +3 -2
  27. package/dist/modules/core/globals.js +3 -2
  28. package/dist/modules/core/helpers.cjs +1 -1
  29. package/dist/modules/core/helpers.js +1 -1
  30. package/dist/modules/core/render.cjs +4 -2
  31. package/dist/modules/core/render.js +4 -2
  32. package/dist/modules/core/styles.cjs +8 -8
  33. package/dist/modules/core/styles.js +10 -10
  34. package/dist/modules/core/targets.cjs +1 -1
  35. package/dist/modules/core/targets.js +1 -1
  36. package/dist/modules/core/transforms.cjs +1 -1
  37. package/dist/modules/core/transforms.js +1 -1
  38. package/dist/modules/core/units.cjs +1 -1
  39. package/dist/modules/core/units.js +1 -1
  40. package/dist/modules/core/values.cjs +17 -6
  41. package/dist/modules/core/values.js +19 -8
  42. package/dist/modules/draggable/draggable.cjs +32 -19
  43. package/dist/modules/draggable/draggable.d.ts +3 -1
  44. package/dist/modules/draggable/draggable.js +28 -15
  45. package/dist/modules/draggable/index.cjs +1 -1
  46. package/dist/modules/draggable/index.js +1 -1
  47. package/dist/modules/easings/{cubic-bezier.cjs → cubic-bezier/index.cjs} +4 -4
  48. package/dist/modules/easings/{cubic-bezier.d.ts → cubic-bezier/index.d.ts} +1 -1
  49. package/dist/modules/easings/{cubic-bezier.js → cubic-bezier/index.js} +4 -4
  50. package/dist/modules/easings/eases/index.cjs +14 -0
  51. package/dist/modules/easings/eases/index.d.ts +1 -0
  52. package/dist/modules/easings/eases/index.js +8 -0
  53. package/dist/modules/easings/{eases.cjs → eases/parser.cjs} +69 -27
  54. package/dist/modules/easings/{eases.d.ts → eases/parser.d.ts} +31 -17
  55. package/dist/modules/easings/{eases.js → eases/parser.js} +60 -21
  56. package/dist/modules/easings/index.cjs +15 -13
  57. package/dist/modules/easings/index.d.ts +6 -6
  58. package/dist/modules/easings/index.js +7 -7
  59. package/dist/modules/easings/{irregular.cjs → irregular/index.cjs} +5 -5
  60. package/dist/modules/easings/{irregular.d.ts → irregular/index.d.ts} +1 -1
  61. package/dist/modules/easings/{irregular.js → irregular/index.js} +4 -4
  62. package/dist/modules/easings/{linear.cjs → linear/index.cjs} +4 -4
  63. package/dist/modules/easings/{linear.d.ts → linear/index.d.ts} +1 -1
  64. package/dist/modules/easings/{linear.js → linear/index.js} +4 -4
  65. package/dist/modules/easings/none.cjs +1 -1
  66. package/dist/modules/easings/none.js +1 -1
  67. package/dist/modules/easings/spring/index.cjs +255 -0
  68. package/dist/modules/{spring/spring.d.ts → easings/spring/index.d.ts} +21 -5
  69. package/dist/modules/easings/spring/index.js +251 -0
  70. package/dist/modules/easings/{steps.cjs → steps/index.cjs} +3 -3
  71. package/dist/modules/easings/{steps.d.ts → steps/index.d.ts} +1 -1
  72. package/dist/modules/easings/{steps.js → steps/index.js} +3 -3
  73. package/dist/modules/engine/engine.cjs +1 -1
  74. package/dist/modules/engine/engine.js +1 -1
  75. package/dist/modules/engine/index.cjs +1 -1
  76. package/dist/modules/engine/index.js +1 -1
  77. package/dist/modules/events/index.cjs +1 -1
  78. package/dist/modules/events/index.js +1 -1
  79. package/dist/modules/events/scroll.cjs +17 -9
  80. package/dist/modules/events/scroll.d.ts +4 -0
  81. package/dist/modules/events/scroll.js +16 -8
  82. package/dist/modules/index.cjs +15 -16
  83. package/dist/modules/index.d.ts +0 -1
  84. package/dist/modules/index.js +7 -8
  85. package/dist/modules/scope/index.cjs +1 -1
  86. package/dist/modules/scope/index.js +1 -1
  87. package/dist/modules/scope/scope.cjs +1 -1
  88. package/dist/modules/scope/scope.js +1 -1
  89. package/dist/modules/svg/drawable.cjs +1 -1
  90. package/dist/modules/svg/drawable.js +1 -1
  91. package/dist/modules/svg/helpers.cjs +1 -1
  92. package/dist/modules/svg/helpers.js +1 -1
  93. package/dist/modules/svg/index.cjs +1 -1
  94. package/dist/modules/svg/index.js +1 -1
  95. package/dist/modules/svg/morphto.cjs +12 -2
  96. package/dist/modules/svg/morphto.js +12 -2
  97. package/dist/modules/svg/motionpath.cjs +18 -11
  98. package/dist/modules/svg/motionpath.d.ts +1 -1
  99. package/dist/modules/svg/motionpath.js +18 -11
  100. package/dist/modules/text/index.cjs +1 -1
  101. package/dist/modules/text/index.js +1 -1
  102. package/dist/modules/text/split.cjs +1 -1
  103. package/dist/modules/text/split.js +1 -1
  104. package/dist/modules/timeline/index.cjs +1 -1
  105. package/dist/modules/timeline/index.js +1 -1
  106. package/dist/modules/timeline/position.cjs +1 -1
  107. package/dist/modules/timeline/position.js +1 -1
  108. package/dist/modules/timeline/timeline.cjs +11 -7
  109. package/dist/modules/timeline/timeline.d.ts +8 -3
  110. package/dist/modules/timeline/timeline.js +10 -6
  111. package/dist/modules/timer/index.cjs +1 -1
  112. package/dist/modules/timer/index.js +1 -1
  113. package/dist/modules/timer/timer.cjs +17 -14
  114. package/dist/modules/timer/timer.d.ts +12 -7
  115. package/dist/modules/timer/timer.js +17 -14
  116. package/dist/modules/types/index.d.ts +35 -14
  117. package/dist/modules/utils/chainable.cjs +1 -1
  118. package/dist/modules/utils/chainable.js +1 -1
  119. package/dist/modules/utils/index.cjs +1 -1
  120. package/dist/modules/utils/index.js +1 -1
  121. package/dist/modules/utils/number.cjs +1 -1
  122. package/dist/modules/utils/number.js +1 -1
  123. package/dist/modules/utils/random.cjs +1 -1
  124. package/dist/modules/utils/random.js +1 -1
  125. package/dist/modules/utils/stagger.cjs +4 -4
  126. package/dist/modules/utils/stagger.js +3 -3
  127. package/dist/modules/utils/target.cjs +1 -1
  128. package/dist/modules/utils/target.js +1 -1
  129. package/dist/modules/utils/time.cjs +1 -1
  130. package/dist/modules/utils/time.js +1 -1
  131. package/dist/modules/waapi/composition.cjs +11 -5
  132. package/dist/modules/waapi/composition.d.ts +1 -1
  133. package/dist/modules/waapi/composition.js +11 -5
  134. package/dist/modules/waapi/index.cjs +1 -1
  135. package/dist/modules/waapi/index.js +1 -1
  136. package/dist/modules/waapi/waapi.cjs +58 -36
  137. package/dist/modules/waapi/waapi.d.ts +12 -7
  138. package/dist/modules/waapi/waapi.js +59 -37
  139. package/package.json +48 -13
  140. package/dist/modules/easings/parser.cjs +0 -59
  141. package/dist/modules/easings/parser.d.ts +0 -21
  142. package/dist/modules/easings/parser.js +0 -55
  143. package/dist/modules/spring/index.cjs +0 -15
  144. package/dist/modules/spring/index.d.ts +0 -1
  145. package/dist/modules/spring/index.js +0 -8
  146. package/dist/modules/spring/spring.cjs +0 -133
  147. package/dist/modules/spring/spring.js +0 -130
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - UMD bundle
3
- * @version v4.2.0
3
+ * @version v4.2.1
4
4
  * @license MIT
5
5
  * @copyright 2025 - Julian Garnier
6
6
  */
@@ -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 {(tickable: Tickable) => void} [onBegin]
28
- * @property {(tickable: Tickable) => void} [onBeforeUpdate]
29
- * @property {(tickable: Tickable) => void} [onUpdate]
30
- * @property {(tickable: Tickable) => void} [onLoop]
31
- * @property {(tickable: Tickable) => void} [onPause]
32
- * @property {(tickable: Tickable) => void} [onComplete]
33
- * @property {(renderable: Renderable) => void} [onRender]
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'|'linear(x1, x2 25%, x3)'|'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'|'irregular'|'cubicBezier'|'steps'|'in(p = 1.675)'|'out(p = 1.675)'|'inOut(p = 1.675)'|'inBack(overshoot = 1.70158)'|'outBack(overshoot = 1.70158)'|'inOutBack(overshoot = 1.70158)'|'inElastic(amplitude = 1, period = .3)'|'outElastic(amplitude = 1, period = .3)'|'inOutElastic(amplitude = 1, period = .3)'|'irregular(length = 10, randomness = 1)'|'cubicBezier(x1, y1, x2, y2)'|'steps(steps = 10)')} EaseStringParamNames
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.70158]
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
@@ -375,17 +385,13 @@
375
385
  * @typedef {WAAPITweenValue|WAAPIFunctionValue|Array<String|Number|WAAPIFunctionValue>} WAAPIKeyframeValue
376
386
  */
377
387
 
378
- /**
379
- * @typedef {(animation: WAAPIAnimation) => void} WAAPICallback
380
- */
381
-
382
388
  /**
383
389
  * @typedef {Object} WAAPITweenOptions
384
390
  * @property {WAAPIKeyframeValue} [to]
385
391
  * @property {WAAPIKeyframeValue} [from]
386
392
  * @property {Number|WAAPIFunctionValue} [duration]
387
393
  * @property {Number|WAAPIFunctionValue} [delay]
388
- * @property {EasingParam} [ease]
394
+ * @property {WAAPIEasingParam} [ease]
389
395
  * @property {CompositeOperation} [composition]
390
396
  */
391
397
 
@@ -398,13 +404,14 @@
398
404
  * @property {Number} [playbackRate]
399
405
  * @property {Number|WAAPIFunctionValue} [duration]
400
406
  * @property {Number|WAAPIFunctionValue} [delay]
401
- * @property {EasingParam} [ease]
407
+ * @property {WAAPIEasingParam} [ease]
402
408
  * @property {CompositeOperation} [composition]
403
- * @property {WAAPICallback} [onComplete]
409
+ * @property {Boolean} [persist]
410
+ * @property {Callback<WAAPIAnimation>} [onComplete]
404
411
  */
405
412
 
406
413
  /**
407
- * @typedef {Record<String, WAAPIKeyframeValue | WAAPIAnimationOptions | Boolean | ScrollObserver | WAAPICallback | EasingParam | WAAPITweenOptions> & WAAPIAnimationOptions} WAAPIAnimationParams
414
+ * @typedef {Record<String, WAAPIKeyframeValue | WAAPIAnimationOptions | Boolean | ScrollObserver | Callback<WAAPIAnimation> | WAAPIEasingParam | WAAPITweenOptions> & WAAPIAnimationOptions} WAAPIAnimationParams
408
415
  */
409
416
 
410
417
  // Animatable types
@@ -547,6 +554,12 @@
547
554
  * @property {String} [onGrab]
548
555
  */
549
556
 
557
+ /**
558
+ * @typedef {Object} DraggableDragThresholdParams
559
+ * @property {Number} [mouse]
560
+ * @property {Number} [touch]
561
+ */
562
+
550
563
  /**
551
564
  * @typedef {Object} DraggableParams
552
565
  * @property {DOMTargetSelector} [trigger]
@@ -559,6 +572,7 @@
559
572
  * @property {Number|((draggable: Draggable) => Number)} [containerFriction]
560
573
  * @property {Number|((draggable: Draggable) => Number)} [releaseContainerFriction]
561
574
  * @property {Number|((draggable: Draggable) => Number)} [dragSpeed]
575
+ * @property {Number|DraggableDragThresholdParams|((draggable: Draggable) => Number|DraggableDragThresholdParams)} [dragThreshold]
562
576
  * @property {Number|((draggable: Draggable) => Number)} [scrollSpeed]
563
577
  * @property {Number|((draggable: Draggable) => Number)} [scrollThreshold]
564
578
  * @property {Number|((draggable: Draggable) => Number)} [minVelocity]
@@ -688,6 +702,8 @@
688
702
  // Strings
689
703
 
690
704
  const emptyString = '';
705
+ const cssVarPrefix = 'var(';
706
+
691
707
  const shortTransforms = /*#__PURE__*/ (() => {
692
708
  const map = new Map();
693
709
  map.set('x', 'translateX');
@@ -711,9 +727,9 @@
711
727
  'skew',
712
728
  'skewX',
713
729
  'skewY',
714
- 'perspective',
715
730
  'matrix',
716
731
  'matrix3d',
732
+ 'perspective',
717
733
  ];
718
734
 
719
735
  const transformsFragmentStrings = /*#__PURE__*/ validTransforms.reduce((a, v) => ({...a, [v]: v + '('}), {});
@@ -737,6 +753,7 @@
737
753
  const lowerCaseRgx = /([a-z])([A-Z])/g;
738
754
  const transformsExecRgx = /(\w+)(\([^)]+\)+)/g; // Match inline transforms with cacl() values, returns the value wrapped in ()
739
755
  const relativeValuesExecRgx = /(\*=|\+=|-=)/;
756
+ const cssVariableMatchRgx = /var\(\s*(--[\w-]+)(?:\s*,\s*([^)]+))?\s*\)/;
740
757
 
741
758
 
742
759
 
@@ -751,6 +768,7 @@
751
768
  reversed: false,
752
769
  alternate: false,
753
770
  autoplay: true,
771
+ persist: false,
754
772
  duration: K,
755
773
  delay: 0,
756
774
  loopDelay: 0,
@@ -784,7 +802,7 @@
784
802
  tickThreshold: 200,
785
803
  };
786
804
 
787
- const globalVersions = { version: '4.2.0', engine: null };
805
+ const globalVersions = { version: '4.2.1', engine: null };
788
806
 
789
807
  if (isBrowser) {
790
808
  if (!win.AnimeJS) win.AnimeJS = [];
@@ -1174,19 +1192,30 @@
1174
1192
  * @return {any}
1175
1193
  */
1176
1194
  const getFunctionValue = (value, target, index, total, store) => {
1195
+ let func;
1177
1196
  if (isFnc(value)) {
1178
- const func = () => {
1197
+ func = () => {
1179
1198
  const computed = /** @type {Function} */(value)(target, index, total);
1180
1199
  // Fallback to 0 if the function returns undefined / NaN / null / false / 0
1181
1200
  return !isNaN(+computed) ? +computed : computed || 0;
1182
1201
  };
1183
- if (store) {
1184
- store.func = func;
1185
- }
1186
- return func();
1202
+ } else if (isStr(value) && stringStartsWith(value, cssVarPrefix)) {
1203
+ func = () => {
1204
+ const match = value.match(cssVariableMatchRgx);
1205
+ const cssVarName = match[1];
1206
+ const fallbackValue = match[2];
1207
+ let computed = getComputedStyle(/** @type {HTMLElement} */(target))?.getPropertyValue(cssVarName);
1208
+ // Use fallback if CSS variable is not set or empty
1209
+ if ((!computed || computed.trim() === emptyString) && fallbackValue) {
1210
+ computed = fallbackValue.trim();
1211
+ }
1212
+ return computed || 0;
1213
+ };
1187
1214
  } else {
1188
1215
  return value;
1189
1216
  }
1217
+ if (store) store.func = func;
1218
+ return func();
1190
1219
  };
1191
1220
 
1192
1221
  /**
@@ -1593,7 +1622,9 @@
1593
1622
  // Handle setters on timeline differently and allow re-trigering the onComplete callback when seeking backwards
1594
1623
  if (parent && isSetter) {
1595
1624
  if (!muteCallbacks && (
1596
- (parent.began && !isRunningBackwards && tickableAbsoluteTime >= duration && !completed) ||
1625
+ // (tickableAbsoluteTime > 0 instead) of (tickableAbsoluteTime >= duration) to prevent floating point precision issues
1626
+ // see: https://github.com/juliangarnier/anime/issues/1088
1627
+ (parent.began && !isRunningBackwards && tickableAbsoluteTime > 0 && !completed) ||
1597
1628
  (isRunningBackwards && tickableAbsoluteTime <= minValue && completed)
1598
1629
  )) {
1599
1630
  tickable.onComplete(/** @type {CallbackArgument} */(tickable));
@@ -1695,13 +1726,12 @@
1695
1726
  }
1696
1727
  };
1697
1728
 
1698
- const propertyNamesCache = {};
1699
-
1700
-
1701
1729
 
1702
1730
 
1703
1731
 
1704
1732
 
1733
+ const propertyNamesCache = {};
1734
+
1705
1735
  /**
1706
1736
  * @param {String} propertyName
1707
1737
  * @param {Target} target
@@ -1748,10 +1778,11 @@
1748
1778
  const tweenTarget = tween.target;
1749
1779
  if (tweenTarget[isDomSymbol]) {
1750
1780
  const targetStyle = /** @type {DOMTarget} */(tweenTarget).style;
1751
- const originalInlinedValue = animation._inlineStyles[tweenProperty];
1781
+ const originalInlinedValue = tween._inlineValue;
1782
+ const tweenHadNoInlineValue = isNil(originalInlinedValue) || originalInlinedValue === emptyString;
1752
1783
  if (tween._tweenType === tweenTypes.TRANSFORM) {
1753
1784
  const cachedTransforms = tweenTarget[transformsSymbol];
1754
- if (isUnd(originalInlinedValue) || originalInlinedValue === emptyString) {
1785
+ if (tweenHadNoInlineValue) {
1755
1786
  delete cachedTransforms[tweenProperty];
1756
1787
  } else {
1757
1788
  cachedTransforms[tweenProperty] = originalInlinedValue;
@@ -1768,8 +1799,8 @@
1768
1799
  }
1769
1800
  }
1770
1801
  } else {
1771
- if (isUnd(originalInlinedValue) || originalInlinedValue === emptyString) {
1772
- targetStyle.removeProperty(tweenProperty);
1802
+ if (tweenHadNoInlineValue) {
1803
+ targetStyle.removeProperty(toLowerCase(tweenProperty));
1773
1804
  } else {
1774
1805
  targetStyle[tweenProperty] = originalInlinedValue;
1775
1806
  }
@@ -2458,7 +2489,7 @@
2458
2489
  if (timer._hasChildren) {
2459
2490
  forEachChildren(timer, reviveTimer);
2460
2491
  } else {
2461
- forEachChildren(timer, (/** @type {Tween} tween*/tween) => {
2492
+ forEachChildren(timer, (/** @type {Tween} tween */tween) => {
2462
2493
  if (tween._composition !== compositionTypes.none) {
2463
2494
  composeTween(tween, getTweenSiblings(tween.target, tween.property));
2464
2495
  }
@@ -2515,7 +2546,6 @@
2515
2546
  /** @type {Number} */(timerLoop) < 0 ? Infinity :
2516
2547
  /** @type {Number} */(timerLoop) + 1;
2517
2548
 
2518
-
2519
2549
  let offsetPosition = 0;
2520
2550
 
2521
2551
  if (parent) {
@@ -2605,7 +2635,7 @@
2605
2635
  }
2606
2636
 
2607
2637
  set cancelled(cancelled) {
2608
- cancelled ? this.cancel() : this.reset(1).play();
2638
+ cancelled ? this.cancel() : this.reset(true).play();
2609
2639
  }
2610
2640
 
2611
2641
  get currentTime() {
@@ -2670,10 +2700,10 @@
2670
2700
  }
2671
2701
 
2672
2702
  /**
2673
- * @param {Number} internalRender
2703
+ * @param {Boolean} [softReset]
2674
2704
  * @return {this}
2675
2705
  */
2676
- reset(internalRender = 0) {
2706
+ reset(softReset = false) {
2677
2707
  // If cancelled, revive the timer before rendering in order to have propertly composed tweens siblings
2678
2708
  reviveTimer(this);
2679
2709
  if (this._reversed && !this._reverse) this.reversed = false;
@@ -2682,7 +2712,7 @@
2682
2712
  // NOTE: This is only required for Timelines and might be better to move to the Timeline class?
2683
2713
  this._iterationTime = this.iterationDuration;
2684
2714
  // Set tickMode to tickModes.FORCE to force rendering
2685
- tick(this, 0, 1, internalRender, tickModes.FORCE);
2715
+ tick(this, 0, 1, ~~softReset, tickModes.FORCE);
2686
2716
  // Reset timer properties after revive / render to make sure the props are not updated again
2687
2717
  resetTimerProperties(this);
2688
2718
  // Also reset children properties
@@ -2693,16 +2723,16 @@
2693
2723
  }
2694
2724
 
2695
2725
  /**
2696
- * @param {Number} internalRender
2726
+ * @param {Boolean} internalRender
2697
2727
  * @return {this}
2698
2728
  */
2699
- init(internalRender = 0) {
2729
+ init(internalRender = false) {
2700
2730
  this.fps = this._fps;
2701
2731
  this.speed = this._speed;
2702
2732
  // Manually calling .init() on timelines should render all children intial state
2703
2733
  // Forces all children to render once then render to 0 when reseted
2704
2734
  if (!internalRender && this._hasChildren) {
2705
- tick(this, this.duration, 1, internalRender, tickModes.FORCE);
2735
+ tick(this, this.duration, 1, ~~internalRender, tickModes.FORCE);
2706
2736
  }
2707
2737
  this.reset(internalRender);
2708
2738
  // Make sure to set autoplay to false to child timers so it doesn't attempt to autoplay / link
@@ -2756,7 +2786,7 @@
2756
2786
 
2757
2787
  /** @return {this} */
2758
2788
  restart() {
2759
- return this.reset(0).resume();
2789
+ return this.reset().resume();
2760
2790
  }
2761
2791
 
2762
2792
  /**
@@ -2859,8 +2889,12 @@
2859
2889
  }
2860
2890
 
2861
2891
  /**
2862
- * @param {Callback<this>} [callback]
2863
- * @return {Promise}
2892
+ * @typedef {this & {then: null}} ResolvedTimer
2893
+ */
2894
+
2895
+ /**
2896
+ * @param {Callback<ResolvedTimer>} [callback]
2897
+ * @return Promise<this>
2864
2898
  */
2865
2899
  then(callback = noop) {
2866
2900
  const then = this.then;
@@ -2868,7 +2902,7 @@
2868
2902
  // this.then = null prevents infinite recursion if returned by an async function
2869
2903
  // https://github.com/juliangarnierorg/anime-beta/issues/26
2870
2904
  this.then = null;
2871
- callback(this);
2905
+ callback(/** @type {ResolvedTimer} */(this));
2872
2906
  this.then = then;
2873
2907
  this._resolve = noop;
2874
2908
  };
@@ -3054,6 +3088,7 @@
3054
3088
 
3055
3089
 
3056
3090
 
3091
+
3057
3092
  /** @type {PowerEasing} */
3058
3093
  const easeInPower = (p = 1.68) => t => pow(t, +p);
3059
3094
 
@@ -3071,154 +3106,6 @@
3071
3106
  outIn: easeIn => t => t < .5 ? (1 - easeIn(1 - t * 2)) / 2 : (easeIn(t * 2 - 1) + 1) / 2,
3072
3107
  };
3073
3108
 
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
3109
  /**
3223
3110
  * Easing functions adapted and simplified from https://robertpenner.com/easing/
3224
3111
  * (c) 2001 Robert Penner
@@ -3247,7 +3134,7 @@
3247
3134
  return 1 / pow(4, 3 - b) - 7.5625 * pow((pow2 * 3 - 2) / 22 - t, 2);
3248
3135
  },
3249
3136
  /** @type {BackEasing} */
3250
- Back: (overshoot = 1.70158) => t => (+overshoot + 1) * t * t * t - +overshoot * t * t,
3137
+ Back: (overshoot = 1.7) => t => (+overshoot + 1) * t * t * t - +overshoot * t * t,
3251
3138
  /** @type {ElasticEasing} */
3252
3139
  Elastic: (amplitude = 1, period = .3) => {
3253
3140
  const a = clamp$1(+amplitude, 1, 10);
@@ -3260,10 +3147,8 @@
3260
3147
 
3261
3148
  /**
3262
3149
  * @typedef {Object} EasesFunctions
3263
- * @property {typeof linear} linear
3264
- * @property {typeof irregular} irregular
3265
- * @property {typeof steps} steps
3266
- * @property {typeof cubicBezier} cubicBezier
3150
+ * @property {typeof none} linear
3151
+ * @property {typeof none} none
3267
3152
  * @property {PowerEasing} in
3268
3153
  * @property {PowerEasing} out
3269
3154
  * @property {PowerEasing} inOut
@@ -3311,7 +3196,7 @@
3311
3196
  */
3312
3197
 
3313
3198
  const eases = (/*#__PURE__ */ (() => {
3314
- const list = { linear, irregular, steps, cubicBezier };
3199
+ const list = { linear: none, none: none };
3315
3200
  for (let type in easeTypes) {
3316
3201
  for (let name in easeInFunctions) {
3317
3202
  const easeIn = easeInFunctions[name];
@@ -3327,15 +3212,43 @@
3327
3212
  })());
3328
3213
 
3329
3214
  /** @type {Record<String, EasingFunction>} */
3330
- const JSEasesLookups = { linear: none };
3215
+ const easesLookups = { linear: none, none: none };
3216
+
3217
+ /**
3218
+ * @param {String} string
3219
+ * @return {EasingFunction}
3220
+ */
3221
+ const parseEaseString = (string) => {
3222
+ if (easesLookups[string]) return easesLookups[string];
3223
+ if (string.indexOf('(') <= -1) {
3224
+ const hasParams = easeTypes[string] || string.includes('Back') || string.includes('Elastic');
3225
+ const parsedFn = /** @type {EasingFunction} */(hasParams ? /** @type {EasingFunctionWithParams} */(eases[string])() : eases[string]);
3226
+ return parsedFn ? easesLookups[string] = parsedFn : none;
3227
+ } else {
3228
+ const split = string.slice(0, -1).split('(');
3229
+ const parsedFn = /** @type {EasingFunctionWithParams} */(eases[split[0]]);
3230
+ return parsedFn ? easesLookups[string] = parsedFn(...split[1].split(',')) : none;
3231
+ }
3232
+ };
3233
+
3234
+ const deprecated = ['steps(', 'irregular(', 'linear(', 'cubicBezier('];
3331
3235
 
3332
3236
  /**
3333
3237
  * @param {EasingParam} ease
3334
3238
  * @return {EasingFunction}
3335
3239
  */
3336
- const parseEase = ease => isFnc(ease) ? ease :
3337
- isStr(ease) ? parseEaseString(/** @type {String} */(ease), eases, JSEasesLookups) :
3338
- none;
3240
+ const parseEase = ease => {
3241
+ if (isStr(ease)) {
3242
+ for (let i = 0, l = deprecated.length; i < l; i++) {
3243
+ if (stringStartsWith(ease, deprecated[i])) {
3244
+ 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}\``);
3245
+ return none;
3246
+ }
3247
+ }
3248
+ }
3249
+ const easeFunc = isFnc(ease) ? ease : isStr(ease) ? parseEaseString(/** @type {String} */(ease)) : none;
3250
+ return easeFunc;
3251
+ };
3339
3252
 
3340
3253
 
3341
3254
 
@@ -3343,6 +3256,7 @@
3343
3256
  // TODO: Maybe move the objects creation to values.js and use the decompose function to create the base object
3344
3257
  const fromTargetObject = createDecomposedValueTargetObject();
3345
3258
  const toTargetObject = createDecomposedValueTargetObject();
3259
+ const inlineStylesStore = {};
3346
3260
  const toFunctionStore = { func: null };
3347
3261
  const keyframesTargetArray = [null];
3348
3262
  const fastSetValuesArray = [null, null];
@@ -3487,15 +3401,15 @@
3487
3401
  const animEase = animaPlaybackEase ? parseEase(animaPlaybackEase) : null;
3488
3402
  const hasSpring = !isUnd(ease) && !isUnd(/** @type {Spring} */(ease).ease);
3489
3403
  const tEasing = hasSpring ? /** @type {Spring} */(ease).ease : setValue(ease, animEase ? 'linear' : animDefaults.ease);
3490
- const tDuration = hasSpring ? /** @type {Spring} */(ease).duration : setValue(duration, animDefaults.duration);
3404
+ const tDuration = hasSpring ? /** @type {Spring} */(ease).settlingDuration : setValue(duration, animDefaults.duration);
3491
3405
  const tDelay = setValue(delay, animDefaults.delay);
3492
3406
  const tModifier = modifier || animDefaults.modifier;
3493
3407
  // If no composition is defined and the targets length is high (>= 1000) set the composition to 'none' (0) for faster tween creation
3494
3408
  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
3409
  // const absoluteOffsetTime = this._offset;
3498
3410
  const absoluteOffsetTime = this._offset + (parent ? parent._offset : 0);
3411
+ // This allows targeting the current animation in the spring onComplete callback
3412
+ if (hasSpring) /** @type {Spring} */(ease).parent = this;
3499
3413
 
3500
3414
  let iterationDuration = NaN;
3501
3415
  let iterationDelay = NaN;
@@ -3597,7 +3511,7 @@
3597
3511
  // 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
3512
  const tweenEasing = hasSpring ? /** @type {Spring} */(keyEasing).ease : keyEasing || tEasing;
3599
3513
  // Calculate default individual keyframe duration by dividing the tl of keyframes
3600
- const tweenDuration = hasSpring ? /** @type {Spring} */(keyEasing).duration : getFunctionValue(setValue(key.duration, (l > 1 ? getFunctionValue(tDuration, target, ti, tl) / l : tDuration)), target, ti, tl);
3514
+ const tweenDuration = hasSpring ? /** @type {Spring} */(keyEasing).settlingDuration : getFunctionValue(setValue(key.duration, (l > 1 ? getFunctionValue(tDuration, target, ti, tl) / l : tDuration)), target, ti, tl);
3601
3515
  // Default delay value should only be applied to the first tween
3602
3516
  const tweenDelay = getFunctionValue(setValue(key.delay, (!tweenIndex ? tDelay : 0)), target, ti, tl);
3603
3517
  const computedComposition = getFunctionValue(setValue(key.composition, tComposition), target, ti, tl);
@@ -3647,7 +3561,7 @@
3647
3561
  }
3648
3562
  } else {
3649
3563
  decomposeRawValue(
3650
- getOriginalAnimatableValue(target, propName, tweenType, animInlineStyles),
3564
+ getOriginalAnimatableValue(target, propName, tweenType, inlineStylesStore),
3651
3565
  decomposedOriginalValue
3652
3566
  );
3653
3567
  if (decomposedOriginalValue.t === valueTypes.UNIT) {
@@ -3665,7 +3579,7 @@
3665
3579
  } else {
3666
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
3667
3581
  decomposeRawValue(parent && prevSibling && prevSibling.parent.parent === parent ? prevSibling._value :
3668
- getOriginalAnimatableValue(target, propName, tweenType, animInlineStyles), toTargetObject);
3582
+ getOriginalAnimatableValue(target, propName, tweenType, inlineStylesStore), toTargetObject);
3669
3583
  }
3670
3584
  }
3671
3585
  if (hasFromvalue) {
@@ -3676,7 +3590,7 @@
3676
3590
  } else {
3677
3591
  decomposeRawValue(parent && prevSibling && prevSibling.parent.parent === parent ? prevSibling._value :
3678
3592
  // 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, animInlineStyles), fromTargetObject);
3593
+ getOriginalAnimatableValue(target, propName, tweenType, inlineStylesStore), fromTargetObject);
3680
3594
  }
3681
3595
  }
3682
3596
  }
@@ -3685,7 +3599,7 @@
3685
3599
  if (fromTargetObject.o) {
3686
3600
  fromTargetObject.n = getRelativeValue(
3687
3601
  !prevSibling ? decomposeRawValue(
3688
- getOriginalAnimatableValue(target, propName, tweenType, animInlineStyles),
3602
+ getOriginalAnimatableValue(target, propName, tweenType, inlineStylesStore),
3689
3603
  decomposedOriginalValue
3690
3604
  ).n : prevSibling._toNumber,
3691
3605
  fromTargetObject.n,
@@ -3741,6 +3655,10 @@
3741
3655
  // Rounding is necessary here to minimize floating point errors when working in seconds
3742
3656
  const tweenUpdateDuration = round$1(+tweenDuration || minValue, 12);
3743
3657
 
3658
+ // Copy the value of the iniline style if it exist and imediatly nullify it to prevents false positive on other targets
3659
+ let inlineValue = inlineStylesStore[propName];
3660
+ if (!isNil(inlineValue)) inlineStylesStore[propName] = null;
3661
+
3744
3662
  /** @type {Tween} */
3745
3663
  const tween = {
3746
3664
  parent: this,
@@ -3772,6 +3690,7 @@
3772
3690
  _isOverlapped: 0,
3773
3691
  _isOverridden: 0,
3774
3692
  _renderTransforms: 0,
3693
+ _inlineValue: inlineValue,
3775
3694
  _prevRep: null, // For replaced tween
3776
3695
  _nextRep: null, // For replaced tween
3777
3696
  _prevAdd: null, // For additive tween
@@ -3874,8 +3793,6 @@
3874
3793
  // this._offset += parent ? iterationDelay : 0;
3875
3794
  /** @type {Number} */
3876
3795
  this.iterationDuration = iterationDuration;
3877
- /** @type {{}} */
3878
- this._inlineStyles = animInlineStyles;
3879
3796
 
3880
3797
  if (!this._autoplay && shouldTriggerRender) this.onRender(this);
3881
3798
  }
@@ -3909,6 +3826,7 @@
3909
3826
  if (tweenFunc) {
3910
3827
  const ogValue = getOriginalAnimatableValue(tween.target, tween.property, tween._tweenType);
3911
3828
  decomposeRawValue(ogValue, decomposedOriginalValue);
3829
+ // TODO: Check for from / to Array based values here,
3912
3830
  decomposeRawValue(tweenFunc(), toTargetObject);
3913
3831
  tween._fromNumbers = cloneArray(decomposedOriginalValue.d);
3914
3832
  tween._fromNumber = decomposedOriginalValue.n;
@@ -3918,6 +3836,8 @@
3918
3836
  tween._toNumber = toTargetObject.o ? getRelativeValue(decomposedOriginalValue.n, toTargetObject.n, toTargetObject.o) : toTargetObject.n;
3919
3837
  }
3920
3838
  });
3839
+ // This forces setter animations to render once
3840
+ if (this.duration === minValue) this.restart();
3921
3841
  return this;
3922
3842
  }
3923
3843
 
@@ -3931,8 +3851,12 @@
3931
3851
  }
3932
3852
 
3933
3853
  /**
3934
- * @param {Callback<this>} [callback]
3935
- * @return {Promise}
3854
+ * @typedef {this & {then: null}} ResolvedJSAnimation
3855
+ */
3856
+
3857
+ /**
3858
+ * @param {Callback<ResolvedJSAnimation>} [callback]
3859
+ * @return Promise<this>
3936
3860
  */
3937
3861
  then(callback) {
3938
3862
  return super.then(callback);
@@ -3960,16 +3884,18 @@
3960
3884
  * @param {DOMTarget} $el
3961
3885
  * @param {String} [property]
3962
3886
  * @param {WAAPIAnimation} [parent]
3887
+ * @return {globalThis.Animation}
3963
3888
  */
3964
3889
  const removeWAAPIAnimation = ($el, property, parent) => {
3965
3890
  let nextLookup = WAAPIAnimationsLookups._head;
3891
+ let anim;
3966
3892
  while (nextLookup) {
3967
3893
  const next = nextLookup._next;
3968
3894
  const matchTarget = nextLookup.$el === $el;
3969
3895
  const matchProperty = !property || nextLookup.property === property;
3970
3896
  const matchParent = !parent || nextLookup.parent === parent;
3971
3897
  if (matchTarget && matchProperty && matchParent) {
3972
- const anim = nextLookup.animation;
3898
+ anim = nextLookup.animation;
3973
3899
  try { anim.commitStyles(); } catch {} anim.cancel();
3974
3900
  removeChild(WAAPIAnimationsLookups, nextLookup);
3975
3901
  const lookupParent = nextLookup.parent;
@@ -3977,8 +3903,8 @@
3977
3903
  lookupParent._completed++;
3978
3904
  if (lookupParent.animations.length === lookupParent._completed) {
3979
3905
  lookupParent.completed = true;
3906
+ lookupParent.paused = true;
3980
3907
  if (!lookupParent.muteCallbacks) {
3981
- lookupParent.paused = true;
3982
3908
  lookupParent.onComplete(lookupParent);
3983
3909
  lookupParent._resolve(lookupParent);
3984
3910
  }
@@ -3987,6 +3913,7 @@
3987
3913
  }
3988
3914
  nextLookup = next;
3989
3915
  }
3916
+ return anim;
3990
3917
  };
3991
3918
 
3992
3919
  /**
@@ -3995,7 +3922,7 @@
3995
3922
  * @param {String} property
3996
3923
  * @param {PropertyIndexedKeyframes} keyframes
3997
3924
  * @param {KeyframeAnimationOptions} params
3998
- * @retun {Animation}
3925
+ * @retun {globalThis.Animation}
3999
3926
  */
4000
3927
  const addWAAPIAnimation = (parent, $el, property, keyframes, params) => {
4001
3928
  const animation = $el.animate(keyframes, params);
@@ -4010,8 +3937,11 @@
4010
3937
  removeWAAPIAnimation($el, property);
4011
3938
  addChild(WAAPIAnimationsLookups, { parent, animation, $el, property, _next: null, _prev: null });
4012
3939
  const handleRemove = () => { removeWAAPIAnimation($el, property, parent); };
3940
+ animation.oncancel = handleRemove;
4013
3941
  animation.onremove = handleRemove;
4014
- animation.onfinish = handleRemove;
3942
+ if (!parent.persist) {
3943
+ animation.onfinish = handleRemove;
3944
+ }
4015
3945
  return animation;
4016
3946
  };
4017
3947
 
@@ -4197,7 +4127,7 @@
4197
4127
  const tlChild = targets ?
4198
4128
  new JSAnimation(targets,/** @type {AnimationParams} */(childParams), tl, adjustedPosition, false, index, length) :
4199
4129
  new Timer(/** @type {TimerParams} */(childParams), tl, adjustedPosition);
4200
- tlChild.init(1);
4130
+ tlChild.init(true);
4201
4131
  // TODO: Might be better to insert at a position relative to startTime?
4202
4132
  addChild(tl, tlChild);
4203
4133
  forEachChildren(tl, (/** @type {Renderable} */child) => {
@@ -4301,7 +4231,7 @@
4301
4231
  parseTimelinePosition(this,a2),
4302
4232
  );
4303
4233
  }
4304
- return this.init(1); // 1 = internalRender
4234
+ return this.init(true);
4305
4235
  }
4306
4236
  }
4307
4237
 
@@ -4410,8 +4340,12 @@
4410
4340
  }
4411
4341
 
4412
4342
  /**
4413
- * @param {Callback<this>} [callback]
4414
- * @return {Promise}
4343
+ * @typedef {this & {then: null}} ResolvedTimeline
4344
+ */
4345
+
4346
+ /**
4347
+ * @param {Callback<ResolvedTimeline>} [callback]
4348
+ * @return Promise<this>
4415
4349
  */
4416
4350
  then(callback) {
4417
4351
  return super.then(callback);
@@ -4521,7 +4455,7 @@
4521
4455
  tween._currentTime = 0;
4522
4456
  });
4523
4457
  if (!isUnd(duration)) animation.stretch(duration);
4524
- animation.reset(1).resume();
4458
+ animation.reset(true).resume();
4525
4459
  return this;
4526
4460
  }
4527
4461
  };
@@ -4639,8 +4573,10 @@
4639
4573
 
4640
4574
 
4641
4575
 
4576
+
4577
+
4642
4578
  /*
4643
- * Spring ease solver adapted from https://webkit.org/demos/spring/spring.js
4579
+ * Spring easing solver adapted from https://webkit.org/demos/spring/spring.js
4644
4580
  * (c) 2016 Webkit - Apple Inc
4645
4581
  */
4646
4582
 
@@ -4651,25 +4587,46 @@
4651
4587
  * @param {SpringParams} [parameters]
4652
4588
  */
4653
4589
  constructor(parameters = {}) {
4590
+ const hasBounceOrDuration = !isUnd(parameters.bounce) || !isUnd(parameters.duration);
4654
4591
  this.timeStep = .02; // Interval fed to the solver to calculate duration
4655
4592
  this.restThreshold = .0005; // Values below this threshold are considered resting position
4656
4593
  this.restDuration = 200; // Duration in ms used to check if the spring is resting after reaching restThreshold
4657
4594
  this.maxDuration = 60000; // The maximum allowed spring duration in ms (default 1 min)
4658
4595
  this.maxRestSteps = this.restDuration / this.timeStep / K; // How many steps allowed after reaching restThreshold before stopping the duration calculation
4659
4596
  this.maxIterations = this.maxDuration / this.timeStep / K; // Calculate the maximum iterations allowed based on maxDuration
4660
- this.m = clamp$1(setValue(parameters.mass, 1), 0, maxSpringParamValue);
4661
- this.s = clamp$1(setValue(parameters.stiffness, 100), 1, maxSpringParamValue);
4662
- this.d = clamp$1(setValue(parameters.damping, 10), .1, maxSpringParamValue);
4597
+ this.bn = clamp$1(setValue(parameters.bounce, .5), -1, 1); // The bounce percentage between -1 and 1.
4598
+ this.pd = clamp$1(setValue(parameters.duration, 628), 10 * globals.timeScale, maxSpringParamValue * globals.timeScale); // The perceived duration
4599
+ this.m = clamp$1(setValue(parameters.mass, 1), 1, maxSpringParamValue);
4600
+ this.s = clamp$1(setValue(parameters.stiffness, 100), minValue, maxSpringParamValue);
4601
+ this.d = clamp$1(setValue(parameters.damping, 10), minValue, maxSpringParamValue);
4663
4602
  this.v = clamp$1(setValue(parameters.velocity, 0), -maxSpringParamValue, maxSpringParamValue);
4664
4603
  this.w0 = 0;
4665
4604
  this.zeta = 0;
4666
4605
  this.wd = 0;
4667
4606
  this.b = 0;
4607
+ this.completed = false;
4668
4608
  this.solverDuration = 0;
4669
- this.duration = 0;
4609
+ this.settlingDuration = 0;
4610
+ /** @type {JSAnimation} */
4611
+ this.parent = null;
4612
+ /** @type {Callback<JSAnimation>} */
4613
+ this.onComplete = parameters.onComplete || noop;
4614
+ if (hasBounceOrDuration) this.calculateSDFromBD();
4670
4615
  this.compute();
4671
4616
  /** @type {EasingFunction} */
4672
- this.ease = t => t === 0 || t === 1 ? t : this.solve(t * this.solverDuration);
4617
+ this.ease = t => {
4618
+ const currentTime = t * this.settlingDuration;
4619
+ const completed = this.completed;
4620
+ const perceivedTime = this.pd;
4621
+ if (currentTime >= perceivedTime && !completed) {
4622
+ this.completed = true;
4623
+ this.onComplete(this.parent);
4624
+ }
4625
+ if (currentTime < perceivedTime && completed) {
4626
+ this.completed = false;
4627
+ }
4628
+ return t === 0 || t === 1 ? t : this.solve(t * this.solverDuration);
4629
+ };
4673
4630
  }
4674
4631
 
4675
4632
  /** @type {EasingFunction} */
@@ -4677,23 +4634,83 @@
4677
4634
  const { zeta, w0, wd, b } = this;
4678
4635
  let t = time;
4679
4636
  if (zeta < 1) {
4637
+ // Underdamped
4680
4638
  t = exp(-t * zeta * w0) * (1 * cos(wd * t) + b * sin(wd * t));
4681
- } else {
4639
+ } else if (zeta === 1) {
4640
+ // Critically damped
4682
4641
  t = (1 + b * t) * exp(-t * w0);
4642
+ } else {
4643
+ // Overdamped
4644
+ // Using exponential instead of cosh and sinh functions to prevent Infinity
4645
+ // Original exp(-zeta * w0 * t) * (cosh(wd * t) + b * sinh(wd * t))
4646
+ t = ((1 + b) * exp((-zeta * w0 + wd) * t) + (1 - b) * exp((-zeta * w0 - wd) * t)) / 2;
4683
4647
  }
4684
4648
  return 1 - t;
4685
4649
  }
4686
4650
 
4651
+ calculateSDFromBD() {
4652
+ // Apple's SwiftUI perceived spring duration implementation https://developer.apple.com/videos/play/wwdc2023/10158/?time=1010
4653
+ // Equations taken from Kevin Grajeda's article https://www.kvin.me/posts/effortless-ui-spring-animations
4654
+ const pds = globals.timeScale === 1 ? this.pd / K : this.pd;
4655
+ // Mass and velocity should be set to their default values
4656
+ this.m = 1;
4657
+ this.v = 0;
4658
+ // Stiffness = (2π ÷ perceptualDuration)²
4659
+ this.s = pow((2 * PI) / pds, 2);
4660
+ if (this.bn >= 0) {
4661
+ // For bounce ≥ 0 (critically damped to underdamped)
4662
+ // damping = ((1 - bounce) × 4π) ÷ perceptualDuration
4663
+ this.d = ((1 - this.bn) * 4 * PI) / pds;
4664
+ } else {
4665
+ // For bounce < 0 (overdamped)
4666
+ // damping = 4π ÷ (perceptualDuration × (1 + bounce))
4667
+ // Note: (1 + bounce) is positive since bounce is negative
4668
+ this.d = (4 * PI) / (pds * (1 + this.bn));
4669
+ }
4670
+ this.s = round$1(clamp$1(this.s, minValue, maxSpringParamValue), 3);
4671
+ this.d = round$1(clamp$1(this.d, minValue, 300), 3); // Clamping to 300 is needed to prevent insane values in the solver
4672
+ }
4673
+
4674
+ calculateBDFromSD() {
4675
+ // Calculate perceived duration and bounce from stiffness and damping
4676
+ // Note: We assumes m = 1 and v = 0 for these calculations
4677
+ const pds = (2 * PI) / sqrt(this.s);
4678
+ this.pd = pds * (globals.timeScale === 1 ? K : 1);
4679
+ const zeta = this.d / (2 * sqrt(this.s));
4680
+ if (zeta <= 1) {
4681
+ // Critically damped to underdamped
4682
+ this.bn = 1 - (this.d * pds) / (4 * PI);
4683
+ } else {
4684
+ // Overdamped
4685
+ this.bn = (4 * PI) / (this.d * pds) - 1;
4686
+ }
4687
+ this.bn = round$1(clamp$1(this.bn, -1, 1), 3);
4688
+ this.pd = round$1(clamp$1(this.pd, 10 * globals.timeScale, maxSpringParamValue * globals.timeScale), 3);
4689
+ }
4690
+
4687
4691
  compute() {
4688
4692
  const { maxRestSteps, maxIterations, restThreshold, timeStep, m, d, s, v } = this;
4689
4693
  const w0 = this.w0 = clamp$1(sqrt(s / m), minValue, K);
4690
- const zeta = this.zeta = d / (2 * sqrt(s * m));
4691
- const wd = this.wd = zeta < 1 ? w0 * sqrt(1 - zeta * zeta) : 0;
4692
- this.b = zeta < 1 ? (zeta * w0 + -v) / wd : -v + w0;
4694
+ const bouncedZeta = this.zeta = d / (2 * sqrt(s * m));
4695
+ // Calculate wd based on damping type
4696
+ if (bouncedZeta < 1) {
4697
+ // Underdamped
4698
+ this.wd = w0 * sqrt(1 - bouncedZeta * bouncedZeta);
4699
+ this.b = (bouncedZeta * w0 + -v) / this.wd;
4700
+ } else if (bouncedZeta === 1) {
4701
+ // Critically damped
4702
+ this.wd = 0;
4703
+ this.b = -v + w0;
4704
+ } else {
4705
+ // Overdamped
4706
+ this.wd = w0 * sqrt(bouncedZeta * bouncedZeta - 1);
4707
+ this.b = (bouncedZeta * w0 + -v) / this.wd;
4708
+ }
4709
+
4693
4710
  let solverTime = 0;
4694
4711
  let restSteps = 0;
4695
4712
  let iterations = 0;
4696
- while (restSteps < maxRestSteps && iterations < maxIterations) {
4713
+ while (restSteps <= maxRestSteps && iterations <= maxIterations) {
4697
4714
  if (abs(1 - this.solve(solverTime)) < restThreshold) {
4698
4715
  restSteps++;
4699
4716
  } else {
@@ -4703,15 +4720,26 @@
4703
4720
  solverTime += timeStep;
4704
4721
  iterations++;
4705
4722
  }
4706
- this.duration = round$1(this.solverDuration * K, 0) * globals.timeScale;
4723
+ this.settlingDuration = round$1(this.solverDuration * K, 0) * globals.timeScale;
4707
4724
  }
4708
4725
 
4709
- get mass() {
4710
- return this.m;
4726
+ get bounce() {
4727
+ return this.bn;
4711
4728
  }
4712
4729
 
4713
- set mass(v) {
4714
- this.m = clamp$1(setValue(v, 1), 0, maxSpringParamValue);
4730
+ set bounce(v) {
4731
+ this.bn = clamp$1(setValue(v, 1), -1, 1);
4732
+ this.calculateSDFromBD();
4733
+ this.compute();
4734
+ }
4735
+
4736
+ get duration() {
4737
+ return this.pd;
4738
+ }
4739
+
4740
+ set duration(v) {
4741
+ this.pd = clamp$1(setValue(v, 1), 10 * globals.timeScale, maxSpringParamValue * globals.timeScale);
4742
+ this.calculateSDFromBD();
4715
4743
  this.compute();
4716
4744
  }
4717
4745
 
@@ -4720,7 +4748,8 @@
4720
4748
  }
4721
4749
 
4722
4750
  set stiffness(v) {
4723
- this.s = clamp$1(setValue(v, 100), 1, maxSpringParamValue);
4751
+ this.s = clamp$1(setValue(v, 100), minValue, maxSpringParamValue);
4752
+ this.calculateBDFromSD();
4724
4753
  this.compute();
4725
4754
  }
4726
4755
 
@@ -4729,7 +4758,17 @@
4729
4758
  }
4730
4759
 
4731
4760
  set damping(v) {
4732
- this.d = clamp$1(setValue(v, 10), .1, maxSpringParamValue);
4761
+ this.d = clamp$1(setValue(v, 10), minValue, maxSpringParamValue);
4762
+ this.calculateBDFromSD();
4763
+ this.compute();
4764
+ }
4765
+
4766
+ get mass() {
4767
+ return this.m;
4768
+ }
4769
+
4770
+ set mass(v) {
4771
+ this.m = clamp$1(setValue(v, 1), 1, maxSpringParamValue);
4733
4772
  this.compute();
4734
4773
  }
4735
4774
 
@@ -4747,7 +4786,18 @@
4747
4786
  * @param {SpringParams} [parameters]
4748
4787
  * @returns {Spring}
4749
4788
  */
4750
- const createSpring = (parameters) => new Spring(parameters);
4789
+ const spring = (parameters) => new Spring(parameters);
4790
+
4791
+ /**
4792
+ * @deprecated createSpring() is deprecated use spring() instead
4793
+ *
4794
+ * @param {SpringParams} [parameters]
4795
+ * @returns {Spring}
4796
+ */
4797
+ const createSpring = (parameters) => {
4798
+ console.warn('createSpring() is deprecated use spring() instead');
4799
+ return new Spring(parameters);
4800
+ };
4751
4801
 
4752
4802
 
4753
4803
 
@@ -4866,7 +4916,7 @@
4866
4916
  }
4867
4917
 
4868
4918
  /**
4869
- * @template {Array<Number>|DOMTargetSelector|String|Number|Boolean|Function|DraggableCursorParams} T
4919
+ * @template {Array<Number>|DOMTargetSelector|String|Number|Boolean|Function|DraggableCursorParams|DraggableDragThresholdParams} T
4870
4920
  * @param {T | ((draggable: Draggable) => T)} value
4871
4921
  * @param {Draggable} draggable
4872
4922
  * @return {T}
@@ -4920,6 +4970,8 @@
4920
4970
  /** @type {Number} */
4921
4971
  this.dragSpeed = 0;
4922
4972
  /** @type {Number} */
4973
+ this.dragThreshold = 3;
4974
+ /** @type {Number} */
4923
4975
  this.maxVelocity = 0;
4924
4976
  /** @type {Number} */
4925
4977
  this.minVelocity = 0;
@@ -4928,13 +4980,13 @@
4928
4980
  /** @type {Boolean|DraggableCursorParams} */
4929
4981
  this.cursor = false;
4930
4982
  /** @type {Spring} */
4931
- this.releaseXSpring = hasSpring ? /** @type {Spring} */(ease) : createSpring({
4983
+ this.releaseXSpring = hasSpring ? /** @type {Spring} */(ease) : spring({
4932
4984
  mass: setValue(parameters.releaseMass, 1),
4933
4985
  stiffness: setValue(parameters.releaseStiffness, 80),
4934
4986
  damping: setValue(parameters.releaseDamping, 20),
4935
4987
  });
4936
4988
  /** @type {Spring} */
4937
- this.releaseYSpring = hasSpring ? /** @type {Spring} */(ease) : createSpring({
4989
+ this.releaseYSpring = hasSpring ? /** @type {Spring} */(ease) : spring({
4938
4990
  mass: setValue(parameters.releaseMass, 1),
4939
4991
  stiffness: setValue(parameters.releaseStiffness, 80),
4940
4992
  damping: setValue(parameters.releaseDamping, 20),
@@ -5337,6 +5389,16 @@
5337
5389
  if (onHover) cursorStyles.onHover = onHover;
5338
5390
  if (onGrab) cursorStyles.onGrab = onGrab;
5339
5391
  }
5392
+ const parsedDragThreshold = parseDraggableFunctionParameter(params.dragThreshold, this);
5393
+ const dragThreshold = { mouse: 3, touch: 7 };
5394
+ if (isNum(parsedDragThreshold)) {
5395
+ dragThreshold.mouse = parsedDragThreshold;
5396
+ dragThreshold.touch = parsedDragThreshold;
5397
+ } else if (parsedDragThreshold) {
5398
+ const { mouse, touch } = parsedDragThreshold;
5399
+ if (!isUnd(mouse)) dragThreshold.mouse = mouse;
5400
+ if (!isUnd(touch)) dragThreshold.touch = touch;
5401
+ }
5340
5402
  this.containerArray = isArr(container) ? container : null;
5341
5403
  this.$container = /** @type {HTMLElement} */(container && !this.containerArray ? parseTargets(/** @type {DOMTarget} */(container))[0] : doc.body);
5342
5404
  this.useWin = this.$container === doc.body;
@@ -5351,6 +5413,7 @@
5351
5413
  this.scrollSpeed = setValue(parseDraggableFunctionParameter(params.scrollSpeed, this), 1.5);
5352
5414
  this.scrollThreshold = setValue(parseDraggableFunctionParameter(params.scrollThreshold, this), 20);
5353
5415
  this.dragSpeed = setValue(parseDraggableFunctionParameter(params.dragSpeed, this), 1);
5416
+ this.dragThreshold = this.isFinePointer ? dragThreshold.mouse : dragThreshold.touch;
5354
5417
  this.minVelocity = setValue(parseDraggableFunctionParameter(params.minVelocity, this), 0);
5355
5418
  this.maxVelocity = setValue(parseDraggableFunctionParameter(params.maxVelocity, this), 50);
5356
5419
  this.velocityMultiplier = setValue(parseDraggableFunctionParameter(params.velocityMultiplier, this), 1);
@@ -5651,9 +5714,8 @@
5651
5714
  this.$trigger.addEventListener('touchmove', preventDefault, { passive: false });
5652
5715
  this.$trigger.addEventListener('touchend', preventDefault);
5653
5716
 
5654
-
5655
- if ((!this.disabled[0] && abs(movedX) > 3) || (!this.disabled[1] && abs(movedY) > 3)) {
5656
-
5717
+ // Don't check for a miminim distance move if already dragging
5718
+ if (this.dragged || (!this.disabled[0] && abs(movedX) > this.dragThreshold) || (!this.disabled[1] && abs(movedY) > this.dragThreshold)) {
5657
5719
  this.updateTicker.resume();
5658
5720
  this.pointer[2] = this.pointer[0];
5659
5721
  this.pointer[3] = this.pointer[1];
@@ -5718,8 +5780,8 @@
5718
5780
  const directionX = dx === cr ? cx > cr ? -1 : 1 : cx < cl ? -1 : 1;
5719
5781
  const distanceX = round$1(cx - dx, 0);
5720
5782
  springX.velocity = disabledY && hasReleaseSpring ? distanceX ? (ds * directionX) / abs(distanceX) : 0 : pv;
5721
- const { ease, duration, restDuration } = springX;
5722
- durationX = cx === dx ? 0 : hasReleaseSpring ? duration : duration - (restDuration * globals.timeScale);
5783
+ const { ease, settlingDuration, restDuration } = springX;
5784
+ durationX = cx === dx ? 0 : hasReleaseSpring ? settlingDuration : settlingDuration - (restDuration * globals.timeScale);
5723
5785
  if (hasReleaseSpring) easeX = ease;
5724
5786
  if (durationX > longestReleaseDuration) longestReleaseDuration = durationX;
5725
5787
  }
@@ -5728,8 +5790,8 @@
5728
5790
  const directionY = dy === cb ? cy > cb ? -1 : 1 : cy < ct ? -1 : 1;
5729
5791
  const distanceY = round$1(cy - dy, 0);
5730
5792
  springY.velocity = disabledX && hasReleaseSpring ? distanceY ? (ds * directionY) / abs(distanceY) : 0 : pv;
5731
- const { ease, duration, restDuration } = springY;
5732
- durationY = cy === dy ? 0 : hasReleaseSpring ? duration : duration - (restDuration * globals.timeScale);
5793
+ const { ease, settlingDuration, restDuration } = springY;
5794
+ durationY = cy === dy ? 0 : hasReleaseSpring ? settlingDuration : settlingDuration - (restDuration * globals.timeScale);
5733
5795
  if (hasReleaseSpring) easeY = ease;
5734
5796
  if (durationY > longestReleaseDuration) longestReleaseDuration = durationY;
5735
5797
  }
@@ -6242,6 +6304,8 @@
6242
6304
  /** @type {Number} */
6243
6305
  this.top = 0;
6244
6306
  /** @type {Number} */
6307
+ this.scale = 1;
6308
+ /** @type {Number} */
6245
6309
  this.zIndex = 0;
6246
6310
  /** @type {Number} */
6247
6311
  this.scrollX = 0;
@@ -6353,6 +6417,7 @@
6353
6417
  height = $el.clientHeight;
6354
6418
  this.top = elRect.top;
6355
6419
  this.left = elRect.left;
6420
+ this.scale = elRect.width ? width / elRect.width : (elRect.height ? height / elRect.height : 1);
6356
6421
  }
6357
6422
  this.width = width;
6358
6423
  this.height = height;
@@ -6582,6 +6647,8 @@
6582
6647
  /** @type {Boolean} */
6583
6648
  this.reverted = false;
6584
6649
  /** @type {Boolean} */
6650
+ this.ready = false;
6651
+ /** @type {Boolean} */
6585
6652
  this.completed = false;
6586
6653
  /** @type {Boolean} */
6587
6654
  this.began = false;
@@ -6591,8 +6658,6 @@
6591
6658
  this.forceEnter = false;
6592
6659
  /** @type {Boolean} */
6593
6660
  this.hasEntered = false;
6594
- // /** @type {Array.<Number>} */
6595
- // this.offsets = [];
6596
6661
  /** @type {Number} */
6597
6662
  this.offset = 0;
6598
6663
  /** @type {Number} */
@@ -6640,6 +6705,8 @@
6640
6705
  // Make sure to pause the linked object in case it's added later
6641
6706
  linked.pause();
6642
6707
  this.linked = linked;
6708
+ // Forces WAAPI Animation to persist; otherwise, they will stop syncing on finish.
6709
+ if (!isUnd(/** @type {WAAPIAnimation} */(linked))) /** @type {WAAPIAnimation} */(linked).persist = true;
6643
6710
  // Try to use a target of the linked object if no target parameters specified
6644
6711
  if (!this._params.target) {
6645
6712
  /** @type {HTMLElement} */
@@ -6679,6 +6746,8 @@
6679
6746
  }
6680
6747
 
6681
6748
  refresh() {
6749
+ // This flag is used to prevent running handleScroll() outside of this.refresh() with values not yet calculated
6750
+ this.ready = true;
6682
6751
  this.reverted = false;
6683
6752
  const params = this._params;
6684
6753
  this.repeat = setValue(parseScrollObserverFunctionParameter(params.repeat, this), true);
@@ -6874,8 +6943,9 @@
6874
6943
  }
6875
6944
  }
6876
6945
  const rect = $target.getBoundingClientRect();
6877
- const offset = isHori ? rect.left + container.scrollX - container.left : rect.top + container.scrollY - container.top;
6878
- const targetSize = isHori ? rect.width : rect.height;
6946
+ const scale = container.scale;
6947
+ const offset = (isHori ? rect.left + container.scrollX - container.left : rect.top + container.scrollY - container.top) * scale;
6948
+ const targetSize = (isHori ? rect.width : rect.height) * scale;
6879
6949
  const containerSize = isHori ? container.width : container.height;
6880
6950
  const scrollSize = isHori ? container.scrollWidth : container.scrollHeight;
6881
6951
  const maxScroll = scrollSize - containerSize;
@@ -6924,8 +6994,6 @@
6924
6994
  const offsetStart = parsedEnterTarget + offset - parsedEnterContainer;
6925
6995
  const offsetEnd = parsedLeaveTarget + offset - parsedLeaveContainer;
6926
6996
  const scrollDelta = offsetEnd - offsetStart;
6927
- // this.offsets[0] = offsetX;
6928
- // this.offsets[1] = offsetY;
6929
6997
  this.offset = offset;
6930
6998
  this.offsetStart = offsetStart;
6931
6999
  this.offsetEnd = offsetEnd;
@@ -6944,6 +7012,7 @@
6944
7012
  }
6945
7013
 
6946
7014
  handleScroll() {
7015
+ if (!this.ready) return;
6947
7016
  const linked = this.linked;
6948
7017
  const sync = this.sync;
6949
7018
  const syncEase = this.syncEase;
@@ -7067,6 +7136,7 @@
7067
7136
  this.removeDebug();
7068
7137
  }
7069
7138
  this.reverted = true;
7139
+ this.ready = false;
7070
7140
  return this;
7071
7141
  }
7072
7142
 
@@ -7078,13 +7148,142 @@
7078
7148
  */
7079
7149
  const onScroll = (parameters = {}) => new ScrollObserver(parameters);
7080
7150
 
7151
+
7152
+
7153
+ /**
7154
+ * Cubic Bezier solver adapted from https://github.com/gre/bezier-easing
7155
+ * (c) 2014 Gaëtan Renaudeau
7156
+ */
7157
+
7158
+ /**
7159
+ * @param {Number} aT
7160
+ * @param {Number} aA1
7161
+ * @param {Number} aA2
7162
+ * @return {Number}
7163
+ */
7164
+ const calcBezier = (aT, aA1, aA2) => (((1 - 3 * aA2 + 3 * aA1) * aT + (3 * aA2 - 6 * aA1)) * aT + (3 * aA1)) * aT;
7165
+
7166
+ /**
7167
+ * @param {Number} aX
7168
+ * @param {Number} mX1
7169
+ * @param {Number} mX2
7170
+ * @return {Number}
7171
+ */
7172
+ const binarySubdivide = (aX, mX1, mX2) => {
7173
+ let aA = 0, aB = 1, currentX, currentT, i = 0;
7174
+ do {
7175
+ currentT = aA + (aB - aA) / 2;
7176
+ currentX = calcBezier(currentT, mX1, mX2) - aX;
7177
+ if (currentX > 0) {
7178
+ aB = currentT;
7179
+ } else {
7180
+ aA = currentT;
7181
+ }
7182
+ } while (abs(currentX) > .0000001 && ++i < 100);
7183
+ return currentT;
7184
+ };
7185
+
7186
+ /**
7187
+ * @param {Number} [mX1] The x coordinate of the first point
7188
+ * @param {Number} [mY1] The y coordinate of the first point
7189
+ * @param {Number} [mX2] The x coordinate of the second point
7190
+ * @param {Number} [mY2] The y coordinate of the second point
7191
+ * @return {EasingFunction}
7192
+ */
7193
+
7194
+ const cubicBezier = (mX1 = 0.5, mY1 = 0.0, mX2 = 0.5, mY2 = 1.0) => (mX1 === mY1 && mX2 === mY2) ? none :
7195
+ t => t === 0 || t === 1 ? t :
7196
+ calcBezier(binarySubdivide(t, mX1, mX2), mY1, mY2);
7197
+
7198
+
7199
+
7200
+ /**
7201
+ * Steps ease implementation https://developer.mozilla.org/fr/docs/Web/CSS/transition-timing-function
7202
+ * Only covers 'end' and 'start' jumpterms
7203
+ * @param {Number} steps
7204
+ * @param {Boolean} [fromStart]
7205
+ * @return {EasingFunction}
7206
+ */
7207
+ const steps = (steps = 10, fromStart) => {
7208
+ const roundMethod = fromStart ? ceil : floor;
7209
+ return t => roundMethod(clamp$1(t, 0, 1) * steps) * (1 / steps);
7210
+ };
7211
+
7212
+
7213
+
7214
+ /**
7215
+ * Without parameters, the linear function creates a non-eased transition.
7216
+ * Parameters, if used, creates a piecewise linear easing by interpolating linearly between the specified points.
7217
+ *
7218
+ * @param {...(String|Number)} args - Points
7219
+ * @return {EasingFunction}
7220
+ */
7221
+ const linear = (...args) => {
7222
+ const argsLength = args.length;
7223
+ if (!argsLength) return none;
7224
+ const totalPoints = argsLength - 1;
7225
+ const firstArg = args[0];
7226
+ const lastArg = args[totalPoints];
7227
+ const xPoints = [0];
7228
+ const yPoints = [parseNumber(firstArg)];
7229
+ for (let i = 1; i < totalPoints; i++) {
7230
+ const arg = args[i];
7231
+ const splitValue = isStr(arg) ?
7232
+ /** @type {String} */(arg).trim().split(' ') :
7233
+ [arg];
7234
+ const value = splitValue[0];
7235
+ const percent = splitValue[1];
7236
+ xPoints.push(!isUnd(percent) ? parseNumber(percent) / 100 : i / totalPoints);
7237
+ yPoints.push(parseNumber(value));
7238
+ }
7239
+ yPoints.push(parseNumber(lastArg));
7240
+ xPoints.push(1);
7241
+ return function easeLinear(t) {
7242
+ for (let i = 1, l = xPoints.length; i < l; i++) {
7243
+ const currentX = xPoints[i];
7244
+ if (t <= currentX) {
7245
+ const prevX = xPoints[i - 1];
7246
+ const prevY = yPoints[i - 1];
7247
+ return prevY + (yPoints[i] - prevY) * (t - prevX) / (currentX - prevX);
7248
+ }
7249
+ }
7250
+ return yPoints[yPoints.length - 1];
7251
+ }
7252
+ };
7253
+
7254
+
7255
+
7256
+ /**
7257
+ * Generate random steps
7258
+ * @param {Number} [length] - The number of steps
7259
+ * @param {Number} [randomness] - How strong the randomness is
7260
+ * @return {EasingFunction}
7261
+ */
7262
+ const irregular = (length = 10, randomness = 1) => {
7263
+ const values = [0];
7264
+ const total = length - 1;
7265
+ for (let i = 1; i < total; i++) {
7266
+ const previousValue = values[i - 1];
7267
+ const spacing = i / total;
7268
+ const segmentEnd = (i + 1) / total;
7269
+ const randomVariation = spacing + (segmentEnd - spacing) * Math.random();
7270
+ // Mix the even spacing and random variation based on the randomness parameter
7271
+ const randomValue = spacing * (1 - randomness) + randomVariation * randomness;
7272
+ values.push(clamp$1(randomValue, previousValue, 1));
7273
+ }
7274
+ values.push(1);
7275
+ return linear(...values);
7276
+ };
7277
+
7081
7278
  var index$3 = /*#__PURE__*/Object.freeze({
7082
7279
  __proto__: null,
7280
+ Spring: Spring,
7281
+ createSpring: createSpring,
7083
7282
  cubicBezier: cubicBezier,
7084
7283
  eases: eases,
7085
7284
  irregular: irregular,
7086
7285
  linear: linear,
7087
- none: none,
7286
+ spring: spring,
7088
7287
  steps: steps
7089
7288
  });
7090
7289
 
@@ -7460,20 +7659,24 @@
7460
7659
 
7461
7660
  /**
7462
7661
  * @param {SVGGeometryElement} $path
7662
+ * @param {Number} totalLength
7463
7663
  * @param {Number} progress
7464
7664
  * @param {Number}lookup
7465
7665
  * @return {DOMPoint}
7466
7666
  */
7467
- const getPathPoint = ($path, progress, lookup = 0) => {
7468
- return $path.getPointAtLength(progress + lookup >= 1 ? progress + lookup : 0);
7667
+ const getPathPoint = ($path, totalLength, progress, lookup = 0) => {
7668
+ const point = progress + lookup;
7669
+ const pointOnPath = (point % totalLength + totalLength) % totalLength;
7670
+ return $path.getPointAtLength(pointOnPath);
7469
7671
  };
7470
7672
 
7471
7673
  /**
7472
7674
  * @param {SVGGeometryElement} $path
7473
7675
  * @param {String} pathProperty
7676
+ * @param {Number} [offset=0]
7474
7677
  * @return {FunctionValue}
7475
7678
  */
7476
- const getPathProgess = ($path, pathProperty) => {
7679
+ const getPathProgess = ($path, pathProperty, offset = 0) => {
7477
7680
  return $el => {
7478
7681
  const totalLength = +($path.getTotalLength());
7479
7682
  const inSvg = $el[isSvgSymbol];
@@ -7484,12 +7687,14 @@
7484
7687
  to: totalLength,
7485
7688
  /** @type {TweenModifier} */
7486
7689
  modifier: progress => {
7690
+ const offsetLength = offset * totalLength;
7691
+ const newProgress = progress + offsetLength;
7487
7692
  if (pathProperty === 'a') {
7488
- const p0 = getPathPoint($path, progress, -1);
7489
- const p1 = getPathPoint($path, progress, 1);
7693
+ const p0 = getPathPoint($path, totalLength, newProgress, -1);
7694
+ const p1 = getPathPoint($path, totalLength, newProgress, 1);
7490
7695
  return atan2(p1.y - p0.y, p1.x - p0.x) * 180 / PI;
7491
7696
  } else {
7492
- const p = getPathPoint($path, progress, 0);
7697
+ const p = getPathPoint($path, totalLength, newProgress, 0);
7493
7698
  return pathProperty === 'x' ?
7494
7699
  inSvg || !ctm ? p.x : p.x * ctm.a + p.y * ctm.c + ctm.e :
7495
7700
  inSvg || !ctm ? p.y : p.x * ctm.b + p.y * ctm.d + ctm.f
@@ -7501,14 +7706,15 @@
7501
7706
 
7502
7707
  /**
7503
7708
  * @param {TargetsParam} path
7709
+ * @param {Number} [offset=0]
7504
7710
  */
7505
- const createMotionPath = path => {
7711
+ const createMotionPath = (path, offset = 0) => {
7506
7712
  const $path = getPath(path);
7507
7713
  if (!$path) return;
7508
7714
  return {
7509
- translateX: getPathProgess($path, 'x'),
7510
- translateY: getPathProgess($path, 'y'),
7511
- rotate: getPathProgess($path, 'a'),
7715
+ translateX: getPathProgess($path, 'x', offset),
7716
+ translateY: getPathProgess($path, 'y', offset),
7717
+ rotate: getPathProgess($path, 'a', offset),
7512
7718
  }
7513
7719
  };
7514
7720
 
@@ -7620,8 +7826,18 @@
7620
7826
  * @return {FunctionValue}
7621
7827
  */
7622
7828
  const morphTo = (path2, precision = .33) => ($path1) => {
7829
+ const tagName1 = ($path1.tagName || '').toLowerCase();
7830
+ if (!tagName1.match(/^(path|polygon|polyline)$/)) {
7831
+ throw new Error(`Can't morph a <${$path1.tagName}> SVG element. Use <path>, <polygon> or <polyline>.`);
7832
+ }
7623
7833
  const $path2 = /** @type {SVGGeometryElement} */(getPath(path2));
7624
- if (!$path2) return;
7834
+ if (!$path2) {
7835
+ throw new Error("Can't morph to an invalid target. 'path2' must resolve to an existing <path>, <polygon> or <polyline> SVG element.");
7836
+ }
7837
+ const tagName2 = ($path2.tagName || '').toLowerCase();
7838
+ if (!tagName2.match(/^(path|polygon|polyline)$/)) {
7839
+ throw new Error(`Can't morph a <${$path2.tagName}> SVG element. Use <path>, <polygon> or <polyline>.`);
7840
+ }
7625
7841
  const isPath = $path1.tagName === 'path';
7626
7842
  const separator = isPath ? ' ' : ',';
7627
7843
  const previousPoints = $path1[morphPointsSymbol];
@@ -8140,21 +8356,11 @@
8140
8356
  */
8141
8357
  const easingToLinear = (fn, samples = 100) => {
8142
8358
  const points = [];
8143
- for (let i = 0; i <= samples; i++) points.push(fn(i / samples));
8359
+ for (let i = 0; i <= samples; i++) points.push(round$1(fn(i / samples), 4));
8144
8360
  return `linear(${points.join(', ')})`;
8145
8361
  };
8146
8362
 
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
- })();
8363
+ const WAAPIEasesLookups = {};
8158
8364
 
8159
8365
  /**
8160
8366
  * @param {EasingParam} ease
@@ -8175,9 +8381,10 @@
8175
8381
  } else if (stringStartsWith(ease, 'cubicB')) {
8176
8382
  parsedEase = toLowerCase(ease);
8177
8383
  } else {
8178
- const parsed = parseEaseString(ease, WAAPIeases, WAAPIEasesLookups);
8384
+ const parsed = parseEaseString(ease);
8179
8385
  if (isFnc(parsed)) parsedEase = parsed === none ? 'linear' : easingToLinear(parsed);
8180
8386
  }
8387
+ // Only cache string based easing name, otherwise function arguments get lost
8181
8388
  WAAPIEasesLookups[ease] = parsedEase;
8182
8389
  } else if (isFnc(ease)) {
8183
8390
  const easing = easingToLinear(ease);
@@ -8218,7 +8425,8 @@
8218
8425
  * @return {String}
8219
8426
  */
8220
8427
  const normalizeTweenValue = (propName, value, $el, i, targetsLength) => {
8221
- let v = getFunctionValue(/** @type {any} */(value), $el, i, targetsLength);
8428
+ // Do not try to compute strings with getFunctionValue otherwise it will convert CSS variables
8429
+ let v = isStr(value) ? value : getFunctionValue(/** @type {any} */(value), $el, i, targetsLength);
8222
8430
  if (!isNum(v)) return v;
8223
8431
  if (commonDefaultPXProperties.includes(propName) || stringStartsWith(propName, 'translate')) return `${v}px`;
8224
8432
  if (stringStartsWith(propName, 'rotate') || stringStartsWith(propName, 'skew')) return `${v}deg`;
@@ -8298,7 +8506,7 @@
8298
8506
  /** @type {PlaybackDirection} */
8299
8507
  const direction = alternate ? reversed ? 'alternate-reverse' : 'alternate' : reversed ? 'reverse' : 'normal';
8300
8508
  /** @type {FillMode} */
8301
- const fill = 'forwards';
8509
+ const fill = 'both'; // We use 'both' here because the animation can be reversed during playback
8302
8510
  /** @type {String} */
8303
8511
  const easing = parseWAAPIEasing(ease);
8304
8512
  const timeScale = (globals.timeScale === 1 ? 1 : K);
@@ -8310,7 +8518,7 @@
8310
8518
  /** @type {globalThis.Animation}] */
8311
8519
  this.controlAnimation = null;
8312
8520
  /** @type {Callback<this>} */
8313
- this.onComplete = params.onComplete || noop;
8521
+ this.onComplete = params.onComplete || /** @type {Callback<WAAPIAnimation>} */(/** @type {unknown} */(globals.defaults.onComplete));
8314
8522
  /** @type {Number} */
8315
8523
  this.duration = 0;
8316
8524
  /** @type {Boolean} */
@@ -8321,6 +8529,8 @@
8321
8529
  this.paused = !autoplay || scroll !== false;
8322
8530
  /** @type {Boolean} */
8323
8531
  this.reversed = reversed;
8532
+ /** @type {Boolean} */
8533
+ this.persist = setValue(params.persist, globals.defaults.persist);
8324
8534
  /** @type {Boolean|ScrollObserver} */
8325
8535
  this.autoplay = autoplay;
8326
8536
  /** @type {Number} */
@@ -8329,17 +8539,18 @@
8329
8539
  this._resolve = noop; // Used by .then()
8330
8540
  /** @type {Number} */
8331
8541
  this._completed = 0;
8332
- /** @type {Array<Object>}] */
8333
- this._inlineStyles = parsedTargets.map($el => $el.getAttribute('style'));
8542
+ /** @type {Array.<Object>} */
8543
+ this._inlineStyles = [];
8334
8544
 
8335
8545
  parsedTargets.forEach(($el, i) => {
8336
8546
 
8337
8547
  const cachedTransforms = $el[transformsSymbol];
8338
-
8339
8548
  const hasIndividualTransforms = validIndividualTransforms.some(t => params.hasOwnProperty(t));
8549
+ const elStyle = $el.style;
8550
+ const inlineStyles = this._inlineStyles[i] = {};
8340
8551
 
8341
8552
  /** @type {Number} */
8342
- const duration = (spring ? /** @type {Spring} */(spring).duration : getFunctionValue(setValue(params.duration, globals.defaults.duration), $el, i, targetsLength)) * timeScale;
8553
+ const duration = (spring ? /** @type {Spring} */(spring).settlingDuration : getFunctionValue(setValue(params.duration, globals.defaults.duration), $el, i, targetsLength)) * timeScale;
8343
8554
  /** @type {Number} */
8344
8555
  const delay = getFunctionValue(setValue(params.delay, globals.defaults.delay), $el, i, targetsLength) * timeScale;
8345
8556
  /** @type {CompositeOperation} */
@@ -8353,6 +8564,12 @@
8353
8564
  const tweenParams = { iterations, direction, fill, easing, duration, delay, composite };
8354
8565
  const propertyValue = params[name];
8355
8566
  const individualTransformProperty = hasIndividualTransforms ? validTransforms.includes(name) ? name : shortTransforms.get(name) : false;
8567
+
8568
+ const styleName = individualTransformProperty ? 'transform' : name;
8569
+ if (!inlineStyles[styleName]) {
8570
+ inlineStyles[styleName] = elStyle[styleName];
8571
+ }
8572
+
8356
8573
  let parsedPropertyValue;
8357
8574
  if (isObj(propertyValue)) {
8358
8575
  const tweenOptions = /** @type {WAAPITweenOptions} */(propertyValue);
@@ -8361,7 +8578,7 @@
8361
8578
  const to = /** @type {WAAPITweenOptions} */(tweenOptions).to;
8362
8579
  const from = /** @type {WAAPITweenOptions} */(tweenOptions).from;
8363
8580
  /** @type {Number} */
8364
- tweenParams.duration = (tweenOptionsSpring ? /** @type {Spring} */(tweenOptionsSpring).duration : getFunctionValue(setValue(tweenOptions.duration, duration), $el, i, targetsLength)) * timeScale;
8581
+ tweenParams.duration = (tweenOptionsSpring ? /** @type {Spring} */(tweenOptionsSpring).settlingDuration : getFunctionValue(setValue(tweenOptions.duration, duration), $el, i, targetsLength)) * timeScale;
8365
8582
  /** @type {Number} */
8366
8583
  tweenParams.delay = getFunctionValue(setValue(tweenOptions.delay, delay), $el, i, targetsLength) * timeScale;
8367
8584
  /** @type {CompositeOperation} */
@@ -8378,10 +8595,10 @@
8378
8595
  addWAAPIAnimation(this, $el, name, keyframes, tweenParams);
8379
8596
  if (!isUnd(from)) {
8380
8597
  if (!individualTransformProperty) {
8381
- $el.style[name] = keyframes[name][0];
8598
+ elStyle[name] = keyframes[name][0];
8382
8599
  } else {
8383
8600
  const key = `--${individualTransformProperty}`;
8384
- $el.style.setProperty(key, keyframes[key][0]);
8601
+ elStyle.setProperty(key, keyframes[key][0]);
8385
8602
  }
8386
8603
  }
8387
8604
  } else {
@@ -8402,7 +8619,7 @@
8402
8619
  for (let t in cachedTransforms) {
8403
8620
  transforms += `${transformsFragmentStrings[t]}var(--${t})) `;
8404
8621
  }
8405
- $el.style.transform = transforms;
8622
+ elStyle.transform = transforms;
8406
8623
  }
8407
8624
  });
8408
8625
 
@@ -8447,7 +8664,8 @@
8447
8664
  // Make sure the animation playState is not 'paused' in order to properly trigger an onfinish callback.
8448
8665
  // 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
8666
  // https://developer.mozilla.org/en-US/docs/Web/API/Animation/finish_event
8450
- if (t >= this.duration) anim.play();
8667
+ // This is not needed for persisting animations since they never finish.
8668
+ if (!this.persist && t >= this.duration) anim.play();
8451
8669
  anim.currentTime = t;
8452
8670
  });
8453
8671
  }
@@ -8517,25 +8735,46 @@
8517
8735
  }
8518
8736
 
8519
8737
  cancel() {
8520
- this.forEach('cancel');
8521
- return this.pause();
8738
+ this.muteCallbacks = true; // This prevents triggering the onComplete callback and resolving the Promise
8739
+ return this.commitStyles().forEach('cancel');
8522
8740
  }
8523
8741
 
8524
8742
  revert() {
8525
- this.cancel();
8526
- this.targets.forEach(($el, i) => $el.setAttribute('style', this._inlineStyles[i]) );
8743
+ // NOTE: We need a better way to revert the transforms, since right now the entire transform property value is reverted,
8744
+ // This means if you have multiple animations animating different transforms on the same target,
8745
+ // reverting one of them will also override the transform property of the other animations.
8746
+ // A better approach would be to store the original custom property values is they exist instead of the entire transform value,
8747
+ // and update the CSS variables with the orignal value
8748
+ this.cancel().targets.forEach(($el, i) => {
8749
+ const targetStyle = $el.style;
8750
+ const targetInlineStyles = this._inlineStyles[i];
8751
+ for (let name in targetInlineStyles) {
8752
+ const originalInlinedValue = targetInlineStyles[name];
8753
+ if (isUnd(originalInlinedValue) || originalInlinedValue === emptyString) {
8754
+ targetStyle.removeProperty(toLowerCase(name));
8755
+ } else {
8756
+ targetStyle[name] = originalInlinedValue;
8757
+ }
8758
+ }
8759
+ // Remove style attribute if empty
8760
+ if ($el.getAttribute('style') === emptyString) $el.removeAttribute('style');
8761
+ });
8527
8762
  return this;
8528
8763
  }
8529
8764
 
8530
8765
  /**
8531
- * @param {WAAPICallback} [callback]
8532
- * @return {Promise}
8766
+ * @typedef {this & {then: null}} ResolvedWAAPIAnimation
8767
+ */
8768
+
8769
+ /**
8770
+ * @param {Callback<ResolvedWAAPIAnimation>} [callback]
8771
+ * @return Promise<this>
8533
8772
  */
8534
8773
  then(callback = noop) {
8535
8774
  const then = this.then;
8536
8775
  const onResolve = () => {
8537
8776
  this.then = null;
8538
- callback(this);
8777
+ callback(/** @type {ResolvedWAAPIAnimation} */(this));
8539
8778
  this.then = then;
8540
8779
  this._resolve = noop;
8541
8780
  };
@@ -8593,7 +8832,6 @@
8593
8832
  exports.linear = linear;
8594
8833
  exports.mapRange = mapRange;
8595
8834
  exports.morphTo = morphTo;
8596
- exports.none = none;
8597
8835
  exports.onScroll = onScroll;
8598
8836
  exports.padEnd = padEnd;
8599
8837
  exports.padStart = padStart;
@@ -8609,6 +8847,7 @@
8609
8847
  exports.snap = snap;
8610
8848
  exports.split = split;
8611
8849
  exports.splitText = splitText;
8850
+ exports.spring = spring;
8612
8851
  exports.stagger = stagger;
8613
8852
  exports.steps = steps;
8614
8853
  exports.svg = index$1;