animejs 4.4.0 → 4.5.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.
Files changed (165) hide show
  1. package/README.md +4 -5
  2. package/dist/bundles/anime.esm.js +491 -272
  3. package/dist/bundles/anime.esm.min.js +2 -2
  4. package/dist/bundles/anime.umd.js +491 -272
  5. package/dist/bundles/anime.umd.min.js +2 -2
  6. package/dist/modules/adapters/index.cjs +14 -0
  7. package/dist/modules/adapters/index.d.ts +1 -0
  8. package/dist/modules/adapters/index.js +8 -0
  9. package/dist/modules/adapters/registry.cjs +149 -0
  10. package/dist/modules/adapters/registry.d.ts +65 -0
  11. package/dist/modules/adapters/registry.js +146 -0
  12. package/dist/modules/adapters/three/adapter.cjs +26 -0
  13. package/dist/modules/adapters/three/adapter.d.ts +15 -0
  14. package/dist/modules/adapters/three/adapter.js +24 -0
  15. package/dist/modules/adapters/three/helpers.cjs +297 -0
  16. package/dist/modules/adapters/three/helpers.d.ts +89 -0
  17. package/dist/modules/adapters/three/helpers.js +280 -0
  18. package/dist/modules/adapters/three/index.cjs +20 -0
  19. package/dist/modules/adapters/three/index.d.ts +2 -0
  20. package/dist/modules/adapters/three/index.js +12 -0
  21. package/dist/modules/adapters/three/instance.cjs +368 -0
  22. package/dist/modules/adapters/three/instance.d.ts +133 -0
  23. package/dist/modules/adapters/three/instance.js +365 -0
  24. package/dist/modules/adapters/three/object3d.cjs +214 -0
  25. package/dist/modules/adapters/three/object3d.d.ts +1 -0
  26. package/dist/modules/adapters/three/object3d.js +212 -0
  27. package/dist/modules/adapters/three/resolvers.cjs +105 -0
  28. package/dist/modules/adapters/three/resolvers.d.ts +1 -0
  29. package/dist/modules/adapters/three/resolvers.js +103 -0
  30. package/dist/modules/adapters/three/uniform.cjs +41 -0
  31. package/dist/modules/adapters/three/uniform.d.ts +1 -0
  32. package/dist/modules/adapters/three/uniform.js +39 -0
  33. package/dist/modules/animatable/animatable.cjs +2 -1
  34. package/dist/modules/animatable/animatable.d.ts +2 -1
  35. package/dist/modules/animatable/animatable.js +2 -1
  36. package/dist/modules/animatable/index.cjs +1 -1
  37. package/dist/modules/animatable/index.js +1 -1
  38. package/dist/modules/animation/additive.cjs +1 -1
  39. package/dist/modules/animation/additive.js +1 -1
  40. package/dist/modules/animation/animation.cjs +43 -16
  41. package/dist/modules/animation/animation.d.ts +5 -0
  42. package/dist/modules/animation/animation.js +45 -18
  43. package/dist/modules/animation/composition.cjs +38 -35
  44. package/dist/modules/animation/composition.js +38 -35
  45. package/dist/modules/animation/index.cjs +1 -1
  46. package/dist/modules/animation/index.js +1 -1
  47. package/dist/modules/core/clock.cjs +11 -15
  48. package/dist/modules/core/clock.d.ts +0 -2
  49. package/dist/modules/core/clock.js +11 -15
  50. package/dist/modules/core/colors.cjs +1 -1
  51. package/dist/modules/core/colors.js +1 -1
  52. package/dist/modules/core/consts.cjs +15 -1
  53. package/dist/modules/core/consts.d.ts +2 -0
  54. package/dist/modules/core/consts.js +14 -2
  55. package/dist/modules/core/globals.cjs +7 -4
  56. package/dist/modules/core/globals.d.ts +8 -2
  57. package/dist/modules/core/globals.js +8 -5
  58. package/dist/modules/core/helpers.cjs +2 -2
  59. package/dist/modules/core/helpers.js +3 -3
  60. package/dist/modules/core/render.cjs +93 -73
  61. package/dist/modules/core/render.js +96 -76
  62. package/dist/modules/core/styles.cjs +16 -2
  63. package/dist/modules/core/styles.js +16 -2
  64. package/dist/modules/core/targets.cjs +11 -13
  65. package/dist/modules/core/targets.js +11 -13
  66. package/dist/modules/core/transforms.cjs +1 -1
  67. package/dist/modules/core/transforms.js +1 -1
  68. package/dist/modules/core/units.cjs +1 -1
  69. package/dist/modules/core/units.js +1 -1
  70. package/dist/modules/core/values.cjs +73 -82
  71. package/dist/modules/core/values.d.ts +1 -2
  72. package/dist/modules/core/values.js +76 -84
  73. package/dist/modules/draggable/draggable.cjs +1 -1
  74. package/dist/modules/draggable/draggable.js +1 -1
  75. package/dist/modules/draggable/index.cjs +1 -1
  76. package/dist/modules/draggable/index.js +1 -1
  77. package/dist/modules/easings/cubic-bezier/index.cjs +1 -1
  78. package/dist/modules/easings/cubic-bezier/index.js +1 -1
  79. package/dist/modules/easings/eases/index.cjs +1 -1
  80. package/dist/modules/easings/eases/index.js +1 -1
  81. package/dist/modules/easings/eases/parser.cjs +3 -3
  82. package/dist/modules/easings/eases/parser.d.ts +4 -5
  83. package/dist/modules/easings/eases/parser.js +3 -3
  84. package/dist/modules/easings/index.cjs +1 -1
  85. package/dist/modules/easings/index.js +1 -1
  86. package/dist/modules/easings/irregular/index.cjs +1 -1
  87. package/dist/modules/easings/irregular/index.js +1 -1
  88. package/dist/modules/easings/linear/index.cjs +1 -1
  89. package/dist/modules/easings/linear/index.js +1 -1
  90. package/dist/modules/easings/none.cjs +1 -1
  91. package/dist/modules/easings/none.js +1 -1
  92. package/dist/modules/easings/spring/index.cjs +1 -1
  93. package/dist/modules/easings/spring/index.js +1 -1
  94. package/dist/modules/easings/steps/index.cjs +1 -1
  95. package/dist/modules/easings/steps/index.js +1 -1
  96. package/dist/modules/engine/engine.cjs +4 -2
  97. package/dist/modules/engine/engine.js +4 -2
  98. package/dist/modules/engine/index.cjs +1 -1
  99. package/dist/modules/engine/index.js +1 -1
  100. package/dist/modules/events/index.cjs +1 -1
  101. package/dist/modules/events/index.js +1 -1
  102. package/dist/modules/events/scroll.cjs +3 -1
  103. package/dist/modules/events/scroll.js +3 -1
  104. package/dist/modules/index.cjs +1 -1
  105. package/dist/modules/index.js +1 -1
  106. package/dist/modules/layout/index.cjs +1 -1
  107. package/dist/modules/layout/index.js +1 -1
  108. package/dist/modules/layout/layout.cjs +1 -1
  109. package/dist/modules/layout/layout.js +1 -1
  110. package/dist/modules/scope/index.cjs +1 -1
  111. package/dist/modules/scope/index.js +1 -1
  112. package/dist/modules/scope/scope.cjs +1 -1
  113. package/dist/modules/scope/scope.js +1 -1
  114. package/dist/modules/svg/drawable.cjs +1 -1
  115. package/dist/modules/svg/drawable.js +1 -1
  116. package/dist/modules/svg/helpers.cjs +1 -1
  117. package/dist/modules/svg/helpers.js +1 -1
  118. package/dist/modules/svg/index.cjs +1 -1
  119. package/dist/modules/svg/index.js +1 -1
  120. package/dist/modules/svg/morphto.cjs +1 -1
  121. package/dist/modules/svg/morphto.js +1 -1
  122. package/dist/modules/svg/motionpath.cjs +1 -1
  123. package/dist/modules/svg/motionpath.js +1 -1
  124. package/dist/modules/text/index.cjs +1 -1
  125. package/dist/modules/text/index.js +1 -1
  126. package/dist/modules/text/scramble.cjs +12 -2
  127. package/dist/modules/text/scramble.d.ts +9 -1
  128. package/dist/modules/text/scramble.js +12 -2
  129. package/dist/modules/text/split.cjs +2 -1
  130. package/dist/modules/text/split.js +2 -1
  131. package/dist/modules/timeline/index.cjs +1 -1
  132. package/dist/modules/timeline/index.js +1 -1
  133. package/dist/modules/timeline/position.cjs +1 -1
  134. package/dist/modules/timeline/position.js +1 -1
  135. package/dist/modules/timeline/timeline.cjs +14 -5
  136. package/dist/modules/timeline/timeline.d.ts +3 -3
  137. package/dist/modules/timeline/timeline.js +14 -5
  138. package/dist/modules/timer/index.cjs +1 -1
  139. package/dist/modules/timer/index.js +1 -1
  140. package/dist/modules/timer/timer.cjs +1 -1
  141. package/dist/modules/timer/timer.js +1 -1
  142. package/dist/modules/types/index.d.ts +36 -11
  143. package/dist/modules/utils/chainable.cjs +1 -1
  144. package/dist/modules/utils/chainable.js +1 -1
  145. package/dist/modules/utils/index.cjs +1 -1
  146. package/dist/modules/utils/index.js +1 -1
  147. package/dist/modules/utils/number.cjs +1 -1
  148. package/dist/modules/utils/number.js +1 -1
  149. package/dist/modules/utils/random.cjs +4 -3
  150. package/dist/modules/utils/random.d.ts +1 -1
  151. package/dist/modules/utils/random.js +4 -3
  152. package/dist/modules/utils/stagger.cjs +67 -13
  153. package/dist/modules/utils/stagger.js +69 -15
  154. package/dist/modules/utils/target.cjs +4 -1
  155. package/dist/modules/utils/target.js +4 -1
  156. package/dist/modules/utils/time.cjs +6 -5
  157. package/dist/modules/utils/time.d.ts +1 -1
  158. package/dist/modules/utils/time.js +6 -5
  159. package/dist/modules/waapi/composition.cjs +1 -1
  160. package/dist/modules/waapi/composition.js +1 -1
  161. package/dist/modules/waapi/index.cjs +1 -1
  162. package/dist/modules/waapi/index.js +1 -1
  163. package/dist/modules/waapi/waapi.cjs +1 -1
  164. package/dist/modules/waapi/waapi.js +1 -1
  165. package/package.json +38 -5
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - core - CJS
3
- * @version v4.4.0
3
+ * @version v4.5.0
4
4
  * @license MIT
5
5
  * @copyright 2026 - Julian Garnier
6
6
  */
@@ -113,18 +113,16 @@ function parseTargets(targets) {
113
113
  function registerTargets(targets) {
114
114
  const parsedTargetsArray = parseTargets(targets);
115
115
  const parsedTargetsLength = parsedTargetsArray.length;
116
- if (parsedTargetsLength) {
117
- for (let i = 0; i < parsedTargetsLength; i++) {
118
- const target = parsedTargetsArray[i];
119
- if (!target[consts.isRegisteredTargetSymbol]) {
120
- target[consts.isRegisteredTargetSymbol] = true;
121
- const isSvgType = helpers.isSvg(target);
122
- const isDom = /** @type {DOMTarget} */(target).nodeType || isSvgType;
123
- if (isDom) {
124
- target[consts.isDomSymbol] = true;
125
- target[consts.isSvgSymbol] = isSvgType;
126
- target[consts.transformsSymbol] = {};
127
- }
116
+ for (let i = 0; i < parsedTargetsLength; i++) {
117
+ const target = parsedTargetsArray[i];
118
+ if (!target[consts.isRegisteredTargetSymbol]) {
119
+ target[consts.isRegisteredTargetSymbol] = true;
120
+ const isSvgType = helpers.isSvg(target);
121
+ const isDom = /** @type {DOMTarget} */(target).nodeType || isSvgType;
122
+ if (isDom) {
123
+ target[consts.isDomSymbol] = true;
124
+ target[consts.isSvgSymbol] = isSvgType;
125
+ target[consts.transformsSymbol] = {};
128
126
  }
129
127
  }
130
128
  }
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - core - ESM
3
- * @version v4.4.0
3
+ * @version v4.5.0
4
4
  * @license MIT
5
5
  * @copyright 2026 - Julian Garnier
6
6
  */
@@ -111,18 +111,16 @@ function parseTargets(targets) {
111
111
  function registerTargets(targets) {
112
112
  const parsedTargetsArray = parseTargets(targets);
113
113
  const parsedTargetsLength = parsedTargetsArray.length;
114
- if (parsedTargetsLength) {
115
- for (let i = 0; i < parsedTargetsLength; i++) {
116
- const target = parsedTargetsArray[i];
117
- if (!target[isRegisteredTargetSymbol]) {
118
- target[isRegisteredTargetSymbol] = true;
119
- const isSvgType = isSvg(target);
120
- const isDom = /** @type {DOMTarget} */(target).nodeType || isSvgType;
121
- if (isDom) {
122
- target[isDomSymbol] = true;
123
- target[isSvgSymbol] = isSvgType;
124
- target[transformsSymbol] = {};
125
- }
114
+ for (let i = 0; i < parsedTargetsLength; i++) {
115
+ const target = parsedTargetsArray[i];
116
+ if (!target[isRegisteredTargetSymbol]) {
117
+ target[isRegisteredTargetSymbol] = true;
118
+ const isSvgType = isSvg(target);
119
+ const isDom = /** @type {DOMTarget} */(target).nodeType || isSvgType;
120
+ if (isDom) {
121
+ target[isDomSymbol] = true;
122
+ target[isSvgSymbol] = isSvgType;
123
+ target[transformsSymbol] = {};
126
124
  }
127
125
  }
128
126
  }
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - core - CJS
3
- * @version v4.4.0
3
+ * @version v4.5.0
4
4
  * @license MIT
5
5
  * @copyright 2026 - Julian Garnier
6
6
  */
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - core - ESM
3
- * @version v4.4.0
3
+ * @version v4.5.0
4
4
  * @license MIT
5
5
  * @copyright 2026 - Julian Garnier
6
6
  */
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - core - CJS
3
- * @version v4.4.0
3
+ * @version v4.5.0
4
4
  * @license MIT
5
5
  * @copyright 2026 - Julian Garnier
6
6
  */
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - core - ESM
3
- * @version v4.4.0
3
+ * @version v4.5.0
4
4
  * @license MIT
5
5
  * @copyright 2026 - Julian Garnier
6
6
  */
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - core - CJS
3
- * @version v4.4.0
3
+ * @version v4.5.0
4
4
  * @license MIT
5
5
  * @copyright 2026 - Julian Garnier
6
6
  */
@@ -10,6 +10,7 @@
10
10
  var consts = require('./consts.cjs');
11
11
  var helpers = require('./helpers.cjs');
12
12
  var transforms = require('./transforms.cjs');
13
+ var registry = require('../adapters/registry.cjs');
13
14
  var colors = require('./colors.cjs');
14
15
 
15
16
  /**
@@ -33,6 +34,21 @@ const setValue = (targetValue, defaultValue) => {
33
34
  return helpers.isUnd(targetValue) ? defaultValue : targetValue;
34
35
  };
35
36
 
37
+ /**
38
+ * Resolve against the target when it's a DOM element, otherwise fall back to :root so non-DOM targets like three.js meshes and custom adapters still pick up CSS variables defined on the document.
39
+ *
40
+ * @param {String} value
41
+ * @param {Target} target
42
+ * @return {String|Number}
43
+ */
44
+ const resolveCssVar = (value, target) => {
45
+ const match = value.match(consts.cssVariableMatchRgx);
46
+ const el = target[consts.isDomSymbol] ? target : document.documentElement;
47
+ let computed = getComputedStyle(/** @type {HTMLElement} */(el))?.getPropertyValue(match[1]);
48
+ if ((!computed || computed.trim() === consts.emptyString) && match[2]) computed = match[2].trim();
49
+ return computed || 0;
50
+ };
51
+
36
52
  /**
37
53
  * @param {TweenPropValue} value
38
54
  * @param {Target} target
@@ -43,30 +59,26 @@ const setValue = (targetValue, defaultValue) => {
43
59
  * @return {any}
44
60
  */
45
61
  const getFunctionValue = (value, target, index, targets, store, prevTween) => {
46
- let func;
47
62
  if (helpers.isFnc(value)) {
48
- func = () => {
63
+ if (!store) {
64
+ const computed = /** @type {Function} */(value)(target, index, targets, prevTween);
65
+ // Fallback to 0 if the function returns undefined, NaN, null, false or 0
66
+ return !isNaN(+computed) ? +computed : computed || 0;
67
+ }
68
+ const func = () => {
49
69
  const computed = /** @type {Function} */(value)(target, index, targets, prevTween);
50
- // Fallback to 0 if the function returns undefined / NaN / null / false / 0
51
70
  return !isNaN(+computed) ? +computed : computed || 0;
52
71
  };
53
- } else if (helpers.isStr(value) && helpers.stringStartsWith(value, consts.cssVarPrefix)) {
54
- func = () => {
55
- const match = value.match(consts.cssVariableMatchRgx);
56
- const cssVarName = match[1];
57
- const fallbackValue = match[2];
58
- let computed = getComputedStyle(/** @type {HTMLElement} */(target))?.getPropertyValue(cssVarName);
59
- // Use fallback if CSS variable is not set or empty
60
- if ((!computed || computed.trim() === consts.emptyString) && fallbackValue) {
61
- computed = fallbackValue.trim();
62
- }
63
- return computed || 0;
64
- };
65
- } else {
66
- return value;
72
+ store.func = func;
73
+ return func();
67
74
  }
68
- if (store) store.func = func;
69
- return func();
75
+ if (helpers.isStr(value) && helpers.stringStartsWith(value, consts.cssVarPrefix)) {
76
+ if (!store) return resolveCssVar(/** @type {String} */(value), target);
77
+ const func = () => resolveCssVar(/** @type {String} */(value), target);
78
+ store.func = func;
79
+ return func();
80
+ }
81
+ return value;
70
82
  };
71
83
 
72
84
  /**
@@ -113,6 +125,12 @@ const getCSSValue = (target, propName, animationInlineStyles) => {
113
125
  */
114
126
  const getOriginalAnimatableValue = (target, propName, tweenType, animationInlineStyles) => {
115
127
  const type = !helpers.isUnd(tweenType) ? tweenType : getTweenType(target, propName);
128
+ const adapterProp = registry.resolveAdapterEntry(target, propName);
129
+ if (adapterProp) {
130
+ const value = adapterProp.get(target);
131
+ if (value && animationInlineStyles) animationInlineStyles[propName] = value;
132
+ return value == null ? 0 : value;
133
+ }
116
134
  if (type === consts.tweenTypes.OBJECT) {
117
135
  const value = target[propName];
118
136
  if (value && animationInlineStyles) animationInlineStyles[propName] = value;
@@ -154,7 +172,7 @@ const createDecomposedValueTargetObject = () => {
154
172
  };
155
173
 
156
174
  /**
157
- * @param {String|Number} rawValue
175
+ * @param {String|Number|Object} rawValue
158
176
  * @param {TweenDecomposedValue} targetObject
159
177
  * @return {TweenDecomposedValue}
160
178
  */
@@ -172,39 +190,38 @@ const decomposeRawValue = (rawValue, targetObject) => {
172
190
  // It's a number
173
191
  targetObject.n = num;
174
192
  return targetObject;
193
+ }
194
+ // let str = /** @type {String} */(rawValue).trim();
195
+ let str = /** @type {String} */(rawValue);
196
+ // Parsing operators (+=, -=, *=) manually is much faster than using regex here
197
+ if (str[1] === '=') {
198
+ targetObject.o = str[0];
199
+ str = str.slice(2);
200
+ }
201
+ // Skip exec regex if the value type is complex or color to avoid long regex backtracking
202
+ const unitMatch = str.includes(' ') ? false : consts.unitsExecRgx.exec(str);
203
+ if (unitMatch) {
204
+ // Has a number and a unit
205
+ targetObject.t = consts.valueTypes.UNIT;
206
+ targetObject.n = +unitMatch[1];
207
+ targetObject.u = unitMatch[2];
208
+ return targetObject;
209
+ } else if (targetObject.o) {
210
+ // Has an operator (+=, -=, *=)
211
+ targetObject.n = +str;
212
+ return targetObject;
213
+ } else if (helpers.isCol(str)) {
214
+ // Color string
215
+ targetObject.t = consts.valueTypes.COLOR;
216
+ targetObject.d = colors.convertColorStringValuesToRgbaArray(str);
217
+ return targetObject;
175
218
  } else {
176
- // let str = /** @type {String} */(rawValue).trim();
177
- let str = /** @type {String} */(rawValue);
178
- // Parsing operators (+=, -=, *=) manually is much faster than using regex here
179
- if (str[1] === '=') {
180
- targetObject.o = str[0];
181
- str = str.slice(2);
182
- }
183
- // Skip exec regex if the value type is complex or color to avoid long regex backtracking
184
- const unitMatch = str.includes(' ') ? false : consts.unitsExecRgx.exec(str);
185
- if (unitMatch) {
186
- // Has a number and a unit
187
- targetObject.t = consts.valueTypes.UNIT;
188
- targetObject.n = +unitMatch[1];
189
- targetObject.u = unitMatch[2];
190
- return targetObject;
191
- } else if (targetObject.o) {
192
- // Has an operator (+=, -=, *=)
193
- targetObject.n = +str;
194
- return targetObject;
195
- } else if (helpers.isCol(str)) {
196
- // Is a color
197
- targetObject.t = consts.valueTypes.COLOR;
198
- targetObject.d = colors.convertColorStringValuesToRgbaArray(str);
199
- return targetObject;
200
- } else {
201
- // Is a more complex string (generally svg coords, calc() or filters CSS values)
202
- const matchedNumbers = str.match(consts.digitWithExponentRgx);
203
- targetObject.t = consts.valueTypes.COMPLEX;
204
- targetObject.d = matchedNumbers ? matchedNumbers.map(Number) : [];
205
- targetObject.s = str.split(consts.digitWithExponentRgx) || [];
206
- return targetObject;
207
- }
219
+ // Is a more complex string (generally svg coords, calc() or filters CSS values)
220
+ const matchedNumbers = str.match(consts.digitWithExponentRgx);
221
+ targetObject.t = consts.valueTypes.COMPLEX;
222
+ targetObject.d = matchedNumbers ? matchedNumbers.map(Number) : [];
223
+ targetObject.s = str.split(consts.digitWithExponentRgx) || [];
224
+ return targetObject;
208
225
  }
209
226
  };
210
227
 
@@ -225,30 +242,6 @@ const decomposeTweenValue = (tween, targetObject) => {
225
242
 
226
243
  const decomposedOriginalValue = createDecomposedValueTargetObject();
227
244
 
228
- /**
229
- * @param {Tween} tween
230
- * @param {Number} progress
231
- * @param {Number} precision
232
- * @return {String}
233
- */
234
- const composeColorValue = (tween, progress, precision) => {
235
- const mod = tween._modifier;
236
- const fn = tween._fromNumbers;
237
- const tn = tween._toNumbers;
238
- const r = helpers.round(helpers.clamp(/** @type {Number} */(mod(helpers.lerp(fn[0], tn[0], progress))), 0, 255), 0);
239
- const g = helpers.round(helpers.clamp(/** @type {Number} */(mod(helpers.lerp(fn[1], tn[1], progress))), 0, 255), 0);
240
- const b = helpers.round(helpers.clamp(/** @type {Number} */(mod(helpers.lerp(fn[2], tn[2], progress))), 0, 255), 0);
241
- const a = helpers.clamp(/** @type {Number} */(mod(helpers.round(helpers.lerp(fn[3], tn[3], progress), precision))), 0, 1);
242
- if (tween._composition !== consts.compositionTypes.none) {
243
- const ns = tween._numbers;
244
- ns[0] = r;
245
- ns[1] = g;
246
- ns[2] = b;
247
- ns[3] = a;
248
- }
249
- return `rgba(${r},${g},${b},${a})`;
250
- };
251
-
252
245
  /**
253
246
  * @param {Tween} tween
254
247
  * @param {Number} progress
@@ -260,20 +253,18 @@ const composeComplexValue = (tween, progress, precision) => {
260
253
  const fn = tween._fromNumbers;
261
254
  const tn = tween._toNumbers;
262
255
  const ts = tween._strings;
263
- const hasComposition = tween._composition !== consts.compositionTypes.none;
264
256
  let v = ts[0];
265
257
  for (let j = 0, l = tn.length; j < l; j++) {
266
258
  const n = /** @type {Number} */(mod(helpers.round(helpers.lerp(fn[j], tn[j], progress), precision)));
267
259
  const s = ts[j + 1];
268
260
  v += `${s ? n + s : n}`;
269
- if (hasComposition) {
270
- tween._numbers[j] = n;
271
- }
261
+ // Keep _numbers fresh for every tween, not only composed ones, so a non-composition setter that reads the lerped triplet such as three transformOrigin still animates.
262
+ // Potential optimization, skip the write when nothing reads it: if (hasComposition || tween._setter) tween._numbers[j] = n;
263
+ tween._numbers[j] = n;
272
264
  }
273
265
  return v;
274
266
  };
275
267
 
276
- exports.composeColorValue = composeColorValue;
277
268
  exports.composeComplexValue = composeComplexValue;
278
269
  exports.createDecomposedValueTargetObject = createDecomposedValueTargetObject;
279
270
  exports.decomposeRawValue = decomposeRawValue;
@@ -4,10 +4,9 @@ export function getTweenType(target: Target, prop: string): tweenTypes;
4
4
  export function getOriginalAnimatableValue(target: Target, propName: string, tweenType?: tweenTypes, animationInlineStyles?: any | void): string | number;
5
5
  export function getRelativeValue(x: number, y: number, operator: string): number;
6
6
  export function createDecomposedValueTargetObject(): TweenDecomposedValue;
7
- export function decomposeRawValue(rawValue: string | number, targetObject: TweenDecomposedValue): TweenDecomposedValue;
7
+ export function decomposeRawValue(rawValue: string | number | any, targetObject: TweenDecomposedValue): TweenDecomposedValue;
8
8
  export function decomposeTweenValue(tween: Tween, targetObject: TweenDecomposedValue): TweenDecomposedValue;
9
9
  export const decomposedOriginalValue: TweenDecomposedValue;
10
- export function composeColorValue(tween: Tween, progress: number, precision: number): string;
11
10
  export function composeComplexValue(tween: Tween, progress: number, precision: number): string;
12
11
  import type { TweenPropValue } from '../types/index.js';
13
12
  import type { Target } from '../types/index.js';
@@ -1,13 +1,14 @@
1
1
  /**
2
2
  * Anime.js - core - ESM
3
- * @version v4.4.0
3
+ * @version v4.5.0
4
4
  * @license MIT
5
5
  * @copyright 2026 - Julian Garnier
6
6
  */
7
7
 
8
- import { tweenTypes, isDomSymbol, isSvgSymbol, validTransforms, shortTransforms, valueTypes, unitsExecRgx, digitWithExponentRgx, compositionTypes, proxyTargetSymbol, cssVarPrefix, cssVariableMatchRgx, emptyString } from './consts.js';
9
- import { isUnd, isValidSVGAttribute, stringStartsWith, isCol, isFnc, isStr, round, lerp, clamp, cloneArray } from './helpers.js';
8
+ import { valueTypes, unitsExecRgx, digitWithExponentRgx, tweenTypes, isDomSymbol, isSvgSymbol, validTransforms, shortTransforms, proxyTargetSymbol, cssVariableMatchRgx, emptyString, cssVarPrefix } from './consts.js';
9
+ import { isUnd, isCol, isValidSVGAttribute, stringStartsWith, isFnc, isStr, round, lerp, cloneArray } from './helpers.js';
10
10
  import { parseInlineTransforms } from './transforms.js';
11
+ import { resolveAdapterEntry } from '../adapters/registry.js';
11
12
  import { convertColorStringValuesToRgbaArray } from './colors.js';
12
13
 
13
14
  /**
@@ -31,6 +32,21 @@ const setValue = (targetValue, defaultValue) => {
31
32
  return isUnd(targetValue) ? defaultValue : targetValue;
32
33
  };
33
34
 
35
+ /**
36
+ * Resolve against the target when it's a DOM element, otherwise fall back to :root so non-DOM targets like three.js meshes and custom adapters still pick up CSS variables defined on the document.
37
+ *
38
+ * @param {String} value
39
+ * @param {Target} target
40
+ * @return {String|Number}
41
+ */
42
+ const resolveCssVar = (value, target) => {
43
+ const match = value.match(cssVariableMatchRgx);
44
+ const el = target[isDomSymbol] ? target : document.documentElement;
45
+ let computed = getComputedStyle(/** @type {HTMLElement} */(el))?.getPropertyValue(match[1]);
46
+ if ((!computed || computed.trim() === emptyString) && match[2]) computed = match[2].trim();
47
+ return computed || 0;
48
+ };
49
+
34
50
  /**
35
51
  * @param {TweenPropValue} value
36
52
  * @param {Target} target
@@ -41,30 +57,26 @@ const setValue = (targetValue, defaultValue) => {
41
57
  * @return {any}
42
58
  */
43
59
  const getFunctionValue = (value, target, index, targets, store, prevTween) => {
44
- let func;
45
60
  if (isFnc(value)) {
46
- func = () => {
61
+ if (!store) {
62
+ const computed = /** @type {Function} */(value)(target, index, targets, prevTween);
63
+ // Fallback to 0 if the function returns undefined, NaN, null, false or 0
64
+ return !isNaN(+computed) ? +computed : computed || 0;
65
+ }
66
+ const func = () => {
47
67
  const computed = /** @type {Function} */(value)(target, index, targets, prevTween);
48
- // Fallback to 0 if the function returns undefined / NaN / null / false / 0
49
68
  return !isNaN(+computed) ? +computed : computed || 0;
50
69
  };
51
- } else if (isStr(value) && stringStartsWith(value, cssVarPrefix)) {
52
- func = () => {
53
- const match = value.match(cssVariableMatchRgx);
54
- const cssVarName = match[1];
55
- const fallbackValue = match[2];
56
- let computed = getComputedStyle(/** @type {HTMLElement} */(target))?.getPropertyValue(cssVarName);
57
- // Use fallback if CSS variable is not set or empty
58
- if ((!computed || computed.trim() === emptyString) && fallbackValue) {
59
- computed = fallbackValue.trim();
60
- }
61
- return computed || 0;
62
- };
63
- } else {
64
- return value;
70
+ store.func = func;
71
+ return func();
65
72
  }
66
- if (store) store.func = func;
67
- return func();
73
+ if (isStr(value) && stringStartsWith(value, cssVarPrefix)) {
74
+ if (!store) return resolveCssVar(/** @type {String} */(value), target);
75
+ const func = () => resolveCssVar(/** @type {String} */(value), target);
76
+ store.func = func;
77
+ return func();
78
+ }
79
+ return value;
68
80
  };
69
81
 
70
82
  /**
@@ -111,6 +123,12 @@ const getCSSValue = (target, propName, animationInlineStyles) => {
111
123
  */
112
124
  const getOriginalAnimatableValue = (target, propName, tweenType, animationInlineStyles) => {
113
125
  const type = !isUnd(tweenType) ? tweenType : getTweenType(target, propName);
126
+ const adapterProp = resolveAdapterEntry(target, propName);
127
+ if (adapterProp) {
128
+ const value = adapterProp.get(target);
129
+ if (value && animationInlineStyles) animationInlineStyles[propName] = value;
130
+ return value == null ? 0 : value;
131
+ }
114
132
  if (type === tweenTypes.OBJECT) {
115
133
  const value = target[propName];
116
134
  if (value && animationInlineStyles) animationInlineStyles[propName] = value;
@@ -152,7 +170,7 @@ const createDecomposedValueTargetObject = () => {
152
170
  };
153
171
 
154
172
  /**
155
- * @param {String|Number} rawValue
173
+ * @param {String|Number|Object} rawValue
156
174
  * @param {TweenDecomposedValue} targetObject
157
175
  * @return {TweenDecomposedValue}
158
176
  */
@@ -170,39 +188,38 @@ const decomposeRawValue = (rawValue, targetObject) => {
170
188
  // It's a number
171
189
  targetObject.n = num;
172
190
  return targetObject;
191
+ }
192
+ // let str = /** @type {String} */(rawValue).trim();
193
+ let str = /** @type {String} */(rawValue);
194
+ // Parsing operators (+=, -=, *=) manually is much faster than using regex here
195
+ if (str[1] === '=') {
196
+ targetObject.o = str[0];
197
+ str = str.slice(2);
198
+ }
199
+ // Skip exec regex if the value type is complex or color to avoid long regex backtracking
200
+ const unitMatch = str.includes(' ') ? false : unitsExecRgx.exec(str);
201
+ if (unitMatch) {
202
+ // Has a number and a unit
203
+ targetObject.t = valueTypes.UNIT;
204
+ targetObject.n = +unitMatch[1];
205
+ targetObject.u = unitMatch[2];
206
+ return targetObject;
207
+ } else if (targetObject.o) {
208
+ // Has an operator (+=, -=, *=)
209
+ targetObject.n = +str;
210
+ return targetObject;
211
+ } else if (isCol(str)) {
212
+ // Color string
213
+ targetObject.t = valueTypes.COLOR;
214
+ targetObject.d = convertColorStringValuesToRgbaArray(str);
215
+ return targetObject;
173
216
  } else {
174
- // let str = /** @type {String} */(rawValue).trim();
175
- let str = /** @type {String} */(rawValue);
176
- // Parsing operators (+=, -=, *=) manually is much faster than using regex here
177
- if (str[1] === '=') {
178
- targetObject.o = str[0];
179
- str = str.slice(2);
180
- }
181
- // Skip exec regex if the value type is complex or color to avoid long regex backtracking
182
- const unitMatch = str.includes(' ') ? false : unitsExecRgx.exec(str);
183
- if (unitMatch) {
184
- // Has a number and a unit
185
- targetObject.t = valueTypes.UNIT;
186
- targetObject.n = +unitMatch[1];
187
- targetObject.u = unitMatch[2];
188
- return targetObject;
189
- } else if (targetObject.o) {
190
- // Has an operator (+=, -=, *=)
191
- targetObject.n = +str;
192
- return targetObject;
193
- } else if (isCol(str)) {
194
- // Is a color
195
- targetObject.t = valueTypes.COLOR;
196
- targetObject.d = convertColorStringValuesToRgbaArray(str);
197
- return targetObject;
198
- } else {
199
- // Is a more complex string (generally svg coords, calc() or filters CSS values)
200
- const matchedNumbers = str.match(digitWithExponentRgx);
201
- targetObject.t = valueTypes.COMPLEX;
202
- targetObject.d = matchedNumbers ? matchedNumbers.map(Number) : [];
203
- targetObject.s = str.split(digitWithExponentRgx) || [];
204
- return targetObject;
205
- }
217
+ // Is a more complex string (generally svg coords, calc() or filters CSS values)
218
+ const matchedNumbers = str.match(digitWithExponentRgx);
219
+ targetObject.t = valueTypes.COMPLEX;
220
+ targetObject.d = matchedNumbers ? matchedNumbers.map(Number) : [];
221
+ targetObject.s = str.split(digitWithExponentRgx) || [];
222
+ return targetObject;
206
223
  }
207
224
  };
208
225
 
@@ -223,30 +240,6 @@ const decomposeTweenValue = (tween, targetObject) => {
223
240
 
224
241
  const decomposedOriginalValue = createDecomposedValueTargetObject();
225
242
 
226
- /**
227
- * @param {Tween} tween
228
- * @param {Number} progress
229
- * @param {Number} precision
230
- * @return {String}
231
- */
232
- const composeColorValue = (tween, progress, precision) => {
233
- const mod = tween._modifier;
234
- const fn = tween._fromNumbers;
235
- const tn = tween._toNumbers;
236
- const r = round(clamp(/** @type {Number} */(mod(lerp(fn[0], tn[0], progress))), 0, 255), 0);
237
- const g = round(clamp(/** @type {Number} */(mod(lerp(fn[1], tn[1], progress))), 0, 255), 0);
238
- const b = round(clamp(/** @type {Number} */(mod(lerp(fn[2], tn[2], progress))), 0, 255), 0);
239
- const a = clamp(/** @type {Number} */(mod(round(lerp(fn[3], tn[3], progress), precision))), 0, 1);
240
- if (tween._composition !== compositionTypes.none) {
241
- const ns = tween._numbers;
242
- ns[0] = r;
243
- ns[1] = g;
244
- ns[2] = b;
245
- ns[3] = a;
246
- }
247
- return `rgba(${r},${g},${b},${a})`;
248
- };
249
-
250
243
  /**
251
244
  * @param {Tween} tween
252
245
  * @param {Number} progress
@@ -258,17 +251,16 @@ const composeComplexValue = (tween, progress, precision) => {
258
251
  const fn = tween._fromNumbers;
259
252
  const tn = tween._toNumbers;
260
253
  const ts = tween._strings;
261
- const hasComposition = tween._composition !== compositionTypes.none;
262
254
  let v = ts[0];
263
255
  for (let j = 0, l = tn.length; j < l; j++) {
264
256
  const n = /** @type {Number} */(mod(round(lerp(fn[j], tn[j], progress), precision)));
265
257
  const s = ts[j + 1];
266
258
  v += `${s ? n + s : n}`;
267
- if (hasComposition) {
268
- tween._numbers[j] = n;
269
- }
259
+ // Keep _numbers fresh for every tween, not only composed ones, so a non-composition setter that reads the lerped triplet such as three transformOrigin still animates.
260
+ // Potential optimization, skip the write when nothing reads it: if (hasComposition || tween._setter) tween._numbers[j] = n;
261
+ tween._numbers[j] = n;
270
262
  }
271
263
  return v;
272
264
  };
273
265
 
274
- export { composeColorValue, composeComplexValue, createDecomposedValueTargetObject, decomposeRawValue, decomposeTweenValue, decomposedOriginalValue, getFunctionValue, getOriginalAnimatableValue, getRelativeValue, getTweenType, setValue };
266
+ export { composeComplexValue, createDecomposedValueTargetObject, decomposeRawValue, decomposeTweenValue, decomposedOriginalValue, getFunctionValue, getOriginalAnimatableValue, getRelativeValue, getTweenType, setValue };
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - draggable - CJS
3
- * @version v4.4.0
3
+ * @version v4.5.0
4
4
  * @license MIT
5
5
  * @copyright 2026 - Julian Garnier
6
6
  */
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - draggable - ESM
3
- * @version v4.4.0
3
+ * @version v4.5.0
4
4
  * @license MIT
5
5
  * @copyright 2026 - Julian Garnier
6
6
  */
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - draggable - CJS
3
- * @version v4.4.0
3
+ * @version v4.5.0
4
4
  * @license MIT
5
5
  * @copyright 2026 - Julian Garnier
6
6
  */
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - draggable - ESM
3
- * @version v4.4.0
3
+ * @version v4.5.0
4
4
  * @license MIT
5
5
  * @copyright 2026 - Julian Garnier
6
6
  */
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - easings - CJS
3
- * @version v4.4.0
3
+ * @version v4.5.0
4
4
  * @license MIT
5
5
  * @copyright 2026 - Julian Garnier
6
6
  */
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - easings - ESM
3
- * @version v4.4.0
3
+ * @version v4.5.0
4
4
  * @license MIT
5
5
  * @copyright 2026 - Julian Garnier
6
6
  */
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - easings - CJS
3
- * @version v4.4.0
3
+ * @version v4.5.0
4
4
  * @license MIT
5
5
  * @copyright 2026 - Julian Garnier
6
6
  */
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - easings - ESM
3
- * @version v4.4.0
3
+ * @version v4.5.0
4
4
  * @license MIT
5
5
  * @copyright 2026 - Julian Garnier
6
6
  */