animejs 4.2.1 → 4.3.0-beta.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 (133) hide show
  1. package/README.md +82 -28
  2. package/dist/bundles/anime.esm.js +2707 -1301
  3. package/dist/bundles/anime.esm.min.js +2 -2
  4. package/dist/bundles/anime.umd.js +2717 -1309
  5. package/dist/bundles/anime.umd.min.js +2 -2
  6. package/dist/modules/animatable/animatable.cjs +1 -1
  7. package/dist/modules/animatable/animatable.js +1 -1
  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 +18 -9
  13. package/dist/modules/animation/animation.js +19 -10
  14. package/dist/modules/animation/composition.cjs +1 -1
  15. package/dist/modules/animation/composition.js +1 -1
  16. package/dist/modules/animation/index.cjs +1 -1
  17. package/dist/modules/animation/index.js +1 -1
  18. package/dist/modules/core/clock.cjs +10 -10
  19. package/dist/modules/core/clock.d.ts +1 -1
  20. package/dist/modules/core/clock.js +10 -10
  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 +6 -4
  24. package/dist/modules/core/consts.d.ts +13 -5
  25. package/dist/modules/core/consts.js +6 -4
  26. package/dist/modules/core/globals.cjs +5 -2
  27. package/dist/modules/core/globals.d.ts +1 -0
  28. package/dist/modules/core/globals.js +5 -3
  29. package/dist/modules/core/helpers.cjs +1 -1
  30. package/dist/modules/core/helpers.js +1 -1
  31. package/dist/modules/core/render.cjs +1 -1
  32. package/dist/modules/core/render.js +1 -1
  33. package/dist/modules/core/styles.cjs +1 -1
  34. package/dist/modules/core/styles.js +1 -1
  35. package/dist/modules/core/targets.cjs +1 -1
  36. package/dist/modules/core/targets.js +1 -1
  37. package/dist/modules/core/transforms.cjs +1 -1
  38. package/dist/modules/core/transforms.js +1 -1
  39. package/dist/modules/core/units.cjs +1 -1
  40. package/dist/modules/core/units.js +1 -1
  41. package/dist/modules/core/values.cjs +1 -1
  42. package/dist/modules/core/values.js +1 -1
  43. package/dist/modules/draggable/draggable.cjs +1 -1
  44. package/dist/modules/draggable/draggable.js +1 -1
  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/index.cjs +1 -1
  48. package/dist/modules/easings/cubic-bezier/index.js +1 -1
  49. package/dist/modules/easings/eases/index.cjs +1 -1
  50. package/dist/modules/easings/eases/index.js +1 -1
  51. package/dist/modules/easings/eases/parser.cjs +1 -1
  52. package/dist/modules/easings/eases/parser.js +1 -1
  53. package/dist/modules/easings/index.cjs +1 -1
  54. package/dist/modules/easings/index.js +1 -1
  55. package/dist/modules/easings/irregular/index.cjs +1 -1
  56. package/dist/modules/easings/irregular/index.js +1 -1
  57. package/dist/modules/easings/linear/index.cjs +1 -1
  58. package/dist/modules/easings/linear/index.js +1 -1
  59. package/dist/modules/easings/none.cjs +1 -1
  60. package/dist/modules/easings/none.js +1 -1
  61. package/dist/modules/easings/spring/index.cjs +1 -1
  62. package/dist/modules/easings/spring/index.js +1 -1
  63. package/dist/modules/easings/steps/index.cjs +1 -1
  64. package/dist/modules/easings/steps/index.js +1 -1
  65. package/dist/modules/engine/engine.cjs +2 -2
  66. package/dist/modules/engine/engine.js +2 -2
  67. package/dist/modules/engine/index.cjs +1 -1
  68. package/dist/modules/engine/index.js +1 -1
  69. package/dist/modules/events/index.cjs +1 -1
  70. package/dist/modules/events/index.js +1 -1
  71. package/dist/modules/events/scroll.cjs +1 -1
  72. package/dist/modules/events/scroll.js +1 -1
  73. package/dist/modules/index.cjs +4 -1
  74. package/dist/modules/index.d.ts +1 -0
  75. package/dist/modules/index.js +2 -1
  76. package/dist/modules/layout/index.cjs +15 -0
  77. package/dist/modules/layout/index.d.ts +1 -0
  78. package/dist/modules/layout/index.js +8 -0
  79. package/dist/modules/layout/layout.cjs +1384 -0
  80. package/dist/modules/layout/layout.d.ts +211 -0
  81. package/dist/modules/layout/layout.js +1381 -0
  82. package/dist/modules/scope/index.cjs +1 -1
  83. package/dist/modules/scope/index.js +1 -1
  84. package/dist/modules/scope/scope.cjs +1 -1
  85. package/dist/modules/scope/scope.js +1 -1
  86. package/dist/modules/svg/drawable.cjs +1 -1
  87. package/dist/modules/svg/drawable.js +1 -1
  88. package/dist/modules/svg/helpers.cjs +1 -1
  89. package/dist/modules/svg/helpers.js +1 -1
  90. package/dist/modules/svg/index.cjs +1 -1
  91. package/dist/modules/svg/index.js +1 -1
  92. package/dist/modules/svg/morphto.cjs +1 -1
  93. package/dist/modules/svg/morphto.js +1 -1
  94. package/dist/modules/svg/motionpath.cjs +11 -7
  95. package/dist/modules/svg/motionpath.js +11 -7
  96. package/dist/modules/text/index.cjs +1 -1
  97. package/dist/modules/text/index.js +1 -1
  98. package/dist/modules/text/split.cjs +23 -9
  99. package/dist/modules/text/split.js +23 -9
  100. package/dist/modules/timeline/index.cjs +1 -1
  101. package/dist/modules/timeline/index.js +1 -1
  102. package/dist/modules/timeline/position.cjs +1 -1
  103. package/dist/modules/timeline/position.js +1 -1
  104. package/dist/modules/timeline/timeline.cjs +14 -6
  105. package/dist/modules/timeline/timeline.d.ts +2 -0
  106. package/dist/modules/timeline/timeline.js +15 -7
  107. package/dist/modules/timer/index.cjs +1 -1
  108. package/dist/modules/timer/index.js +1 -1
  109. package/dist/modules/timer/timer.cjs +26 -13
  110. package/dist/modules/timer/timer.d.ts +1 -0
  111. package/dist/modules/timer/timer.js +27 -14
  112. package/dist/modules/types/index.d.ts +3 -1
  113. package/dist/modules/utils/chainable.cjs +1 -1
  114. package/dist/modules/utils/chainable.js +1 -1
  115. package/dist/modules/utils/index.cjs +1 -1
  116. package/dist/modules/utils/index.js +1 -1
  117. package/dist/modules/utils/number.cjs +1 -1
  118. package/dist/modules/utils/number.js +1 -1
  119. package/dist/modules/utils/random.cjs +1 -1
  120. package/dist/modules/utils/random.js +1 -1
  121. package/dist/modules/utils/stagger.cjs +1 -1
  122. package/dist/modules/utils/stagger.js +1 -1
  123. package/dist/modules/utils/target.cjs +1 -1
  124. package/dist/modules/utils/target.js +1 -1
  125. package/dist/modules/utils/time.cjs +1 -1
  126. package/dist/modules/utils/time.js +1 -1
  127. package/dist/modules/waapi/composition.cjs +1 -1
  128. package/dist/modules/waapi/composition.js +1 -1
  129. package/dist/modules/waapi/index.cjs +1 -1
  130. package/dist/modules/waapi/index.js +1 -1
  131. package/dist/modules/waapi/waapi.cjs +15 -7
  132. package/dist/modules/waapi/waapi.js +16 -8
  133. package/package.json +8 -2
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - scope - CJS
3
- * @version v4.2.1
3
+ * @version v4.3.0-beta.0
4
4
  * @license MIT
5
5
  * @copyright 2025 - Julian Garnier
6
6
  */
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - scope - ESM
3
- * @version v4.2.1
3
+ * @version v4.3.0-beta.0
4
4
  * @license MIT
5
5
  * @copyright 2025 - Julian Garnier
6
6
  */
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - scope - CJS
3
- * @version v4.2.1
3
+ * @version v4.3.0-beta.0
4
4
  * @license MIT
5
5
  * @copyright 2025 - Julian Garnier
6
6
  */
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - scope - ESM
3
- * @version v4.2.1
3
+ * @version v4.3.0-beta.0
4
4
  * @license MIT
5
5
  * @copyright 2025 - Julian Garnier
6
6
  */
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - svg - CJS
3
- * @version v4.2.1
3
+ * @version v4.3.0-beta.0
4
4
  * @license MIT
5
5
  * @copyright 2025 - Julian Garnier
6
6
  */
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - svg - ESM
3
- * @version v4.2.1
3
+ * @version v4.3.0-beta.0
4
4
  * @license MIT
5
5
  * @copyright 2025 - Julian Garnier
6
6
  */
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - svg - CJS
3
- * @version v4.2.1
3
+ * @version v4.3.0-beta.0
4
4
  * @license MIT
5
5
  * @copyright 2025 - Julian Garnier
6
6
  */
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - svg - ESM
3
- * @version v4.2.1
3
+ * @version v4.3.0-beta.0
4
4
  * @license MIT
5
5
  * @copyright 2025 - Julian Garnier
6
6
  */
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - svg - CJS
3
- * @version v4.2.1
3
+ * @version v4.3.0-beta.0
4
4
  * @license MIT
5
5
  * @copyright 2025 - Julian Garnier
6
6
  */
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - svg - ESM
3
- * @version v4.2.1
3
+ * @version v4.3.0-beta.0
4
4
  * @license MIT
5
5
  * @copyright 2025 - Julian Garnier
6
6
  */
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - svg - CJS
3
- * @version v4.2.1
3
+ * @version v4.3.0-beta.0
4
4
  * @license MIT
5
5
  * @copyright 2025 - Julian Garnier
6
6
  */
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - svg - ESM
3
- * @version v4.2.1
3
+ * @version v4.3.0-beta.0
4
4
  * @license MIT
5
5
  * @copyright 2025 - Julian Garnier
6
6
  */
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - svg - CJS
3
- * @version v4.2.1
3
+ * @version v4.3.0-beta.0
4
4
  * @license MIT
5
5
  * @copyright 2025 - Julian Garnier
6
6
  */
@@ -26,12 +26,15 @@ var helpers = require('./helpers.cjs');
26
26
  * @param {SVGGeometryElement} $path
27
27
  * @param {Number} totalLength
28
28
  * @param {Number} progress
29
- * @param {Number}lookup
29
+ * @param {Number} lookup
30
+ * @param {Boolean} shouldClamp
30
31
  * @return {DOMPoint}
31
32
  */
32
- const getPathPoint = ($path, totalLength, progress, lookup = 0) => {
33
+ const getPathPoint = ($path, totalLength, progress, lookup, shouldClamp) => {
33
34
  const point = progress + lookup;
34
- const pointOnPath = (point % totalLength + totalLength) % totalLength;
35
+ const pointOnPath = shouldClamp
36
+ ? Math.max(0, Math.min(point, totalLength)) // Clamp between 0 and totalLength
37
+ : (point % totalLength + totalLength) % totalLength; // Wrap around
35
38
  return $path.getPointAtLength(pointOnPath);
36
39
  };
37
40
 
@@ -46,6 +49,7 @@ const getPathProgess = ($path, pathProperty, offset = 0) => {
46
49
  const totalLength = +($path.getTotalLength());
47
50
  const inSvg = $el[consts.isSvgSymbol];
48
51
  const ctm = $path.getCTM();
52
+ const shouldClamp = offset === 0;
49
53
  /** @type {TweenObjectValue} */
50
54
  return {
51
55
  from: 0,
@@ -55,11 +59,11 @@ const getPathProgess = ($path, pathProperty, offset = 0) => {
55
59
  const offsetLength = offset * totalLength;
56
60
  const newProgress = progress + offsetLength;
57
61
  if (pathProperty === 'a') {
58
- const p0 = getPathPoint($path, totalLength, newProgress, -1);
59
- const p1 = getPathPoint($path, totalLength, newProgress, 1);
62
+ const p0 = getPathPoint($path, totalLength, newProgress, -1, shouldClamp);
63
+ const p1 = getPathPoint($path, totalLength, newProgress, 1, shouldClamp);
60
64
  return helpers$1.atan2(p1.y - p0.y, p1.x - p0.x) * 180 / helpers$1.PI;
61
65
  } else {
62
- const p = getPathPoint($path, totalLength, newProgress, 0);
66
+ const p = getPathPoint($path, totalLength, newProgress, 0, shouldClamp);
63
67
  return pathProperty === 'x' ?
64
68
  inSvg || !ctm ? p.x : p.x * ctm.a + p.y * ctm.c + ctm.e :
65
69
  inSvg || !ctm ? p.y : p.x * ctm.b + p.y * ctm.d + ctm.f
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - svg - ESM
3
- * @version v4.2.1
3
+ * @version v4.3.0-beta.0
4
4
  * @license MIT
5
5
  * @copyright 2025 - Julian Garnier
6
6
  */
@@ -24,12 +24,15 @@ import { getPath } from './helpers.js';
24
24
  * @param {SVGGeometryElement} $path
25
25
  * @param {Number} totalLength
26
26
  * @param {Number} progress
27
- * @param {Number}lookup
27
+ * @param {Number} lookup
28
+ * @param {Boolean} shouldClamp
28
29
  * @return {DOMPoint}
29
30
  */
30
- const getPathPoint = ($path, totalLength, progress, lookup = 0) => {
31
+ const getPathPoint = ($path, totalLength, progress, lookup, shouldClamp) => {
31
32
  const point = progress + lookup;
32
- const pointOnPath = (point % totalLength + totalLength) % totalLength;
33
+ const pointOnPath = shouldClamp
34
+ ? Math.max(0, Math.min(point, totalLength)) // Clamp between 0 and totalLength
35
+ : (point % totalLength + totalLength) % totalLength; // Wrap around
33
36
  return $path.getPointAtLength(pointOnPath);
34
37
  };
35
38
 
@@ -44,6 +47,7 @@ const getPathProgess = ($path, pathProperty, offset = 0) => {
44
47
  const totalLength = +($path.getTotalLength());
45
48
  const inSvg = $el[isSvgSymbol];
46
49
  const ctm = $path.getCTM();
50
+ const shouldClamp = offset === 0;
47
51
  /** @type {TweenObjectValue} */
48
52
  return {
49
53
  from: 0,
@@ -53,11 +57,11 @@ const getPathProgess = ($path, pathProperty, offset = 0) => {
53
57
  const offsetLength = offset * totalLength;
54
58
  const newProgress = progress + offsetLength;
55
59
  if (pathProperty === 'a') {
56
- const p0 = getPathPoint($path, totalLength, newProgress, -1);
57
- const p1 = getPathPoint($path, totalLength, newProgress, 1);
60
+ const p0 = getPathPoint($path, totalLength, newProgress, -1, shouldClamp);
61
+ const p1 = getPathPoint($path, totalLength, newProgress, 1, shouldClamp);
58
62
  return atan2(p1.y - p0.y, p1.x - p0.x) * 180 / PI;
59
63
  } else {
60
- const p = getPathPoint($path, totalLength, newProgress, 0);
64
+ const p = getPathPoint($path, totalLength, newProgress, 0, shouldClamp);
61
65
  return pathProperty === 'x' ?
62
66
  inSvg || !ctm ? p.x : p.x * ctm.a + p.y * ctm.c + ctm.e :
63
67
  inSvg || !ctm ? p.y : p.x * ctm.b + p.y * ctm.d + ctm.f
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - text - CJS
3
- * @version v4.2.1
3
+ * @version v4.3.0-beta.0
4
4
  * @license MIT
5
5
  * @copyright 2025 - Julian Garnier
6
6
  */
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - text - ESM
3
- * @version v4.2.1
3
+ * @version v4.3.0-beta.0
4
4
  * @license MIT
5
5
  * @copyright 2025 - Julian Garnier
6
6
  */
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - text - CJS
3
- * @version v4.2.1
3
+ * @version v4.3.0-beta.0
4
4
  * @license MIT
5
5
  * @copyright 2025 - Julian Garnier
6
6
  */
@@ -89,12 +89,23 @@ const filterEmptyElements = $el => {
89
89
  /**
90
90
  * @param {HTMLElement} $el
91
91
  * @param {Number} lineIndex
92
- * @param {Set<HTMLElement>} bin
93
- * @returns {Set<HTMLElement>}
92
+ * @param {Set<HTMLElement|Node>} bin
93
+ * @returns {Set<HTMLElement|Node>}
94
94
  */
95
95
  const filterLineElements = ($el, lineIndex, bin) => {
96
96
  const dataLineAttr = $el.getAttribute(dataLine);
97
- if (dataLineAttr !== null && +dataLineAttr !== lineIndex || $el.tagName === 'BR') bin.add($el);
97
+ if (dataLineAttr !== null && +dataLineAttr !== lineIndex || $el.tagName === 'BR') {
98
+ bin.add($el);
99
+ // Also remove adjacent whitespace-only text nodes
100
+ const prev = $el.previousSibling;
101
+ const next = $el.nextSibling;
102
+ if (prev && prev.nodeType === 3 && whiteSpaceRgx.test(prev.textContent)) {
103
+ bin.add(prev);
104
+ }
105
+ if (next && next.nodeType === 3 && whiteSpaceRgx.test(next.textContent)) {
106
+ bin.add(next);
107
+ }
108
+ }
98
109
  let i = $el.childElementCount;
99
110
  while (i--) filterLineElements(/** @type {HTMLElement} */($el.children[i]), lineIndex, bin);
100
111
  return bin;
@@ -309,7 +320,7 @@ class TextSplitter {
309
320
  // Only concatenate if both current and previous are non-word-like and don't contain spaces
310
321
  const lastWordIndex = tempWords.length - 1;
311
322
  const lastWord = tempWords[lastWordIndex];
312
- if (!lastWord.includes(' ') && !segment.includes(' ')) {
323
+ if (!whiteSpaceGroupRgx.test(lastWord) && !whiteSpaceGroupRgx.test(segment)) {
313
324
  tempWords[lastWordIndex] += segment;
314
325
  } else {
315
326
  tempWords.push(segment);
@@ -402,7 +413,7 @@ class TextSplitter {
402
413
  for (let i = 0, l = elementsArray.length; i < l; i++) {
403
414
  const $el = elementsArray[i];
404
415
  const { top, height } = $el.getBoundingClientRect();
405
- if (y && top - y > height * .5) linesCount++;
416
+ if (!helpers.isUnd(y) && top - y > height * .5) linesCount++;
406
417
  $el.setAttribute(dataLine, `${linesCount}`);
407
418
  const nested = $el.querySelectorAll(`[${dataLine}]`);
408
419
  let c = nested.length;
@@ -416,9 +427,11 @@ class TextSplitter {
416
427
  for (let lineIndex = 0; lineIndex < linesCount + 1; lineIndex++) {
417
428
  const $clone = /** @type {HTMLElement} */($el.cloneNode(true));
418
429
  filterLineElements($clone, lineIndex, new Set()).forEach($el => {
419
- const $parent = $el.parentElement;
420
- if ($parent) parents.add($parent);
421
- $el.remove();
430
+ const $parent = $el.parentNode;
431
+ if ($parent) {
432
+ if ($el.nodeType === 1) parents.add(/** @type {HTMLElement} */($parent));
433
+ $parent.removeChild($el);
434
+ }
422
435
  });
423
436
  clones.push($clone);
424
437
  }
@@ -431,6 +444,7 @@ class TextSplitter {
431
444
  if (wordTemplate) this.words = getAllTopLevelElements($el, wordType);
432
445
  if (charTemplate) this.chars = getAllTopLevelElements($el, charType);
433
446
  }
447
+
434
448
  // Remove the word wrappers and clear the words array if lines split only
435
449
  if (this.linesOnly) {
436
450
  const words = this.words;
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - text - ESM
3
- * @version v4.2.1
3
+ * @version v4.3.0-beta.0
4
4
  * @license MIT
5
5
  * @copyright 2025 - Julian Garnier
6
6
  */
@@ -87,12 +87,23 @@ const filterEmptyElements = $el => {
87
87
  /**
88
88
  * @param {HTMLElement} $el
89
89
  * @param {Number} lineIndex
90
- * @param {Set<HTMLElement>} bin
91
- * @returns {Set<HTMLElement>}
90
+ * @param {Set<HTMLElement|Node>} bin
91
+ * @returns {Set<HTMLElement|Node>}
92
92
  */
93
93
  const filterLineElements = ($el, lineIndex, bin) => {
94
94
  const dataLineAttr = $el.getAttribute(dataLine);
95
- if (dataLineAttr !== null && +dataLineAttr !== lineIndex || $el.tagName === 'BR') bin.add($el);
95
+ if (dataLineAttr !== null && +dataLineAttr !== lineIndex || $el.tagName === 'BR') {
96
+ bin.add($el);
97
+ // Also remove adjacent whitespace-only text nodes
98
+ const prev = $el.previousSibling;
99
+ const next = $el.nextSibling;
100
+ if (prev && prev.nodeType === 3 && whiteSpaceRgx.test(prev.textContent)) {
101
+ bin.add(prev);
102
+ }
103
+ if (next && next.nodeType === 3 && whiteSpaceRgx.test(next.textContent)) {
104
+ bin.add(next);
105
+ }
106
+ }
96
107
  let i = $el.childElementCount;
97
108
  while (i--) filterLineElements(/** @type {HTMLElement} */($el.children[i]), lineIndex, bin);
98
109
  return bin;
@@ -307,7 +318,7 @@ class TextSplitter {
307
318
  // Only concatenate if both current and previous are non-word-like and don't contain spaces
308
319
  const lastWordIndex = tempWords.length - 1;
309
320
  const lastWord = tempWords[lastWordIndex];
310
- if (!lastWord.includes(' ') && !segment.includes(' ')) {
321
+ if (!whiteSpaceGroupRgx.test(lastWord) && !whiteSpaceGroupRgx.test(segment)) {
311
322
  tempWords[lastWordIndex] += segment;
312
323
  } else {
313
324
  tempWords.push(segment);
@@ -400,7 +411,7 @@ class TextSplitter {
400
411
  for (let i = 0, l = elementsArray.length; i < l; i++) {
401
412
  const $el = elementsArray[i];
402
413
  const { top, height } = $el.getBoundingClientRect();
403
- if (y && top - y > height * .5) linesCount++;
414
+ if (!isUnd(y) && top - y > height * .5) linesCount++;
404
415
  $el.setAttribute(dataLine, `${linesCount}`);
405
416
  const nested = $el.querySelectorAll(`[${dataLine}]`);
406
417
  let c = nested.length;
@@ -414,9 +425,11 @@ class TextSplitter {
414
425
  for (let lineIndex = 0; lineIndex < linesCount + 1; lineIndex++) {
415
426
  const $clone = /** @type {HTMLElement} */($el.cloneNode(true));
416
427
  filterLineElements($clone, lineIndex, new Set()).forEach($el => {
417
- const $parent = $el.parentElement;
418
- if ($parent) parents.add($parent);
419
- $el.remove();
428
+ const $parent = $el.parentNode;
429
+ if ($parent) {
430
+ if ($el.nodeType === 1) parents.add(/** @type {HTMLElement} */($parent));
431
+ $parent.removeChild($el);
432
+ }
420
433
  });
421
434
  clones.push($clone);
422
435
  }
@@ -429,6 +442,7 @@ class TextSplitter {
429
442
  if (wordTemplate) this.words = getAllTopLevelElements($el, wordType);
430
443
  if (charTemplate) this.chars = getAllTopLevelElements($el, charType);
431
444
  }
445
+
432
446
  // Remove the word wrappers and clear the words array if lines split only
433
447
  if (this.linesOnly) {
434
448
  const words = this.words;
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - timeline - CJS
3
- * @version v4.2.1
3
+ * @version v4.3.0-beta.0
4
4
  * @license MIT
5
5
  * @copyright 2025 - Julian Garnier
6
6
  */
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - timeline - ESM
3
- * @version v4.2.1
3
+ * @version v4.3.0-beta.0
4
4
  * @license MIT
5
5
  * @copyright 2025 - Julian Garnier
6
6
  */
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - timeline - CJS
3
- * @version v4.2.1
3
+ * @version v4.3.0-beta.0
4
4
  * @license MIT
5
5
  * @copyright 2025 - Julian Garnier
6
6
  */
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - timeline - ESM
3
- * @version v4.2.1
3
+ * @version v4.3.0-beta.0
4
4
  * @license MIT
5
5
  * @copyright 2025 - Julian Garnier
6
6
  */
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - timeline - CJS
3
- * @version v4.2.1
3
+ * @version v4.3.0-beta.0
4
4
  * @license MIT
5
5
  * @copyright 2025 - Julian Garnier
6
6
  */
@@ -77,11 +77,11 @@ function addTlChild(childParams, tl, timePosition, targets, index, length) {
77
77
  const isSetter = helpers.isNum(childParams.duration) && /** @type {Number} */(childParams.duration) <= consts.minValue;
78
78
  // Offset the tl position with -minValue for 0 duration animations or .set() calls in order to align their end value with the defined position
79
79
  const adjustedPosition = isSetter ? timePosition - consts.minValue : timePosition;
80
- render.tick(tl, adjustedPosition, 1, 1, consts.tickModes.AUTO);
80
+ if (tl.composition) render.tick(tl, adjustedPosition, 1, 1, consts.tickModes.AUTO);
81
81
  const tlChild = targets ?
82
82
  new animation.JSAnimation(targets,/** @type {AnimationParams} */(childParams), tl, adjustedPosition, false, index, length) :
83
83
  new timer.Timer(/** @type {TimerParams} */(childParams), tl, adjustedPosition);
84
- tlChild.init(true);
84
+ if (tl.composition) tlChild.init(true);
85
85
  // TODO: Might be better to insert at a position relative to startTime?
86
86
  helpers.addChild(tl, tlChild);
87
87
  helpers.forEachChildren(tl, (/** @type {Renderable} */child) => {
@@ -93,6 +93,8 @@ function addTlChild(childParams, tl, timePosition, targets, index, length) {
93
93
  return tl;
94
94
  }
95
95
 
96
+ let TLId = 0;
97
+
96
98
  class Timeline extends timer.Timer {
97
99
 
98
100
  /**
@@ -100,6 +102,9 @@ class Timeline extends timer.Timer {
100
102
  */
101
103
  constructor(parameters = {}) {
102
104
  super(/** @type {TimerParams&TimelineParams} */(parameters), null, 0);
105
+ ++TLId;
106
+ /** @type {String|Number} */
107
+ this.id = !helpers.isUnd(parameters.id) ? parameters.id : TLId;
103
108
  /** @type {Number} */
104
109
  this.duration = 0; // TL duration starts at 0 and grows when adding children
105
110
  /** @type {Record<String, Number>} */
@@ -108,6 +113,8 @@ class Timeline extends timer.Timer {
108
113
  const globalDefaults = globals.globals.defaults;
109
114
  /** @type {DefaultsParams} */
110
115
  this.defaults = defaultsParams ? helpers.mergeObjects(defaultsParams, globalDefaults) : globalDefaults;
116
+ /** @type {Boolean} */
117
+ this.composition = values.setValue(parameters.composition, true);
111
118
  /** @type {Callback<this>} */
112
119
  this.onRender = parameters.onRender || globalDefaults.onRender;
113
120
  const tlPlaybackEase = values.setValue(parameters.playbackEase, globalDefaults.playbackEase);
@@ -185,7 +192,8 @@ class Timeline extends timer.Timer {
185
192
  position.parseTimelinePosition(this,a2),
186
193
  );
187
194
  }
188
- return this.init(true);
195
+ if (this.composition) this.init(true);
196
+ return this;
189
197
  }
190
198
  }
191
199
 
@@ -212,7 +220,7 @@ class Timeline extends timer.Timer {
212
220
  if (helpers.isUnd(synced) || synced && helpers.isUnd(synced.pause)) return this;
213
221
  synced.pause();
214
222
  const duration = +(/** @type {globalThis.Animation} */(synced).effect ? /** @type {globalThis.Animation} */(synced).effect.getTiming().duration : /** @type {Tickable} */(synced).duration);
215
- return this.add(synced, { currentTime: [0, duration], duration, ease: 'linear' }, position);
223
+ return this.add(synced, { currentTime: [0, duration], duration, delay: 0, ease: 'linear', playbackEase: 'linear' }, position);
216
224
  }
217
225
 
218
226
  /**
@@ -235,7 +243,7 @@ class Timeline extends timer.Timer {
235
243
  */
236
244
  call(callback, position) {
237
245
  if (helpers.isUnd(callback) || callback && !helpers.isFnc(callback)) return this;
238
- return this.add({ duration: 0, onComplete: () => callback(this) }, position);
246
+ return this.add({ duration: 0, delay: 0, onComplete: () => callback(this) }, position);
239
247
  }
240
248
 
241
249
  /**
@@ -7,6 +7,8 @@ export class Timeline extends Timer {
7
7
  labels: Record<string, number>;
8
8
  /** @type {DefaultsParams} */
9
9
  defaults: DefaultsParams;
10
+ /** @type {Boolean} */
11
+ composition: boolean;
10
12
  /** @type {Callback<this>} */
11
13
  onRender: Callback<this>;
12
14
  _ease: import("../types/index.js").EasingFunction;
@@ -1,13 +1,13 @@
1
1
  /**
2
2
  * Anime.js - timeline - ESM
3
- * @version v4.2.1
3
+ * @version v4.3.0-beta.0
4
4
  * @license MIT
5
5
  * @copyright 2025 - Julian Garnier
6
6
  */
7
7
 
8
8
  import { globals } from '../core/globals.js';
9
9
  import { minValue, compositionTypes, tickModes } from '../core/consts.js';
10
- import { mergeObjects, isObj, isFnc, isUnd, isStr, normalizeTime, forEachChildren, isNum, addChild, clampInfinity } from '../core/helpers.js';
10
+ import { isUnd, mergeObjects, isObj, isFnc, isStr, normalizeTime, forEachChildren, isNum, addChild, clampInfinity } from '../core/helpers.js';
11
11
  import { setValue } from '../core/values.js';
12
12
  import { parseTargets } from '../core/targets.js';
13
13
  import { tick } from '../core/render.js';
@@ -75,11 +75,11 @@ function addTlChild(childParams, tl, timePosition, targets, index, length) {
75
75
  const isSetter = isNum(childParams.duration) && /** @type {Number} */(childParams.duration) <= minValue;
76
76
  // Offset the tl position with -minValue for 0 duration animations or .set() calls in order to align their end value with the defined position
77
77
  const adjustedPosition = isSetter ? timePosition - minValue : timePosition;
78
- tick(tl, adjustedPosition, 1, 1, tickModes.AUTO);
78
+ if (tl.composition) tick(tl, adjustedPosition, 1, 1, tickModes.AUTO);
79
79
  const tlChild = targets ?
80
80
  new JSAnimation(targets,/** @type {AnimationParams} */(childParams), tl, adjustedPosition, false, index, length) :
81
81
  new Timer(/** @type {TimerParams} */(childParams), tl, adjustedPosition);
82
- tlChild.init(true);
82
+ if (tl.composition) tlChild.init(true);
83
83
  // TODO: Might be better to insert at a position relative to startTime?
84
84
  addChild(tl, tlChild);
85
85
  forEachChildren(tl, (/** @type {Renderable} */child) => {
@@ -91,6 +91,8 @@ function addTlChild(childParams, tl, timePosition, targets, index, length) {
91
91
  return tl;
92
92
  }
93
93
 
94
+ let TLId = 0;
95
+
94
96
  class Timeline extends Timer {
95
97
 
96
98
  /**
@@ -98,6 +100,9 @@ class Timeline extends Timer {
98
100
  */
99
101
  constructor(parameters = {}) {
100
102
  super(/** @type {TimerParams&TimelineParams} */(parameters), null, 0);
103
+ ++TLId;
104
+ /** @type {String|Number} */
105
+ this.id = !isUnd(parameters.id) ? parameters.id : TLId;
101
106
  /** @type {Number} */
102
107
  this.duration = 0; // TL duration starts at 0 and grows when adding children
103
108
  /** @type {Record<String, Number>} */
@@ -106,6 +111,8 @@ class Timeline extends Timer {
106
111
  const globalDefaults = globals.defaults;
107
112
  /** @type {DefaultsParams} */
108
113
  this.defaults = defaultsParams ? mergeObjects(defaultsParams, globalDefaults) : globalDefaults;
114
+ /** @type {Boolean} */
115
+ this.composition = setValue(parameters.composition, true);
109
116
  /** @type {Callback<this>} */
110
117
  this.onRender = parameters.onRender || globalDefaults.onRender;
111
118
  const tlPlaybackEase = setValue(parameters.playbackEase, globalDefaults.playbackEase);
@@ -183,7 +190,8 @@ class Timeline extends Timer {
183
190
  parseTimelinePosition(this,a2),
184
191
  );
185
192
  }
186
- return this.init(true);
193
+ if (this.composition) this.init(true);
194
+ return this;
187
195
  }
188
196
  }
189
197
 
@@ -210,7 +218,7 @@ class Timeline extends Timer {
210
218
  if (isUnd(synced) || synced && isUnd(synced.pause)) return this;
211
219
  synced.pause();
212
220
  const duration = +(/** @type {globalThis.Animation} */(synced).effect ? /** @type {globalThis.Animation} */(synced).effect.getTiming().duration : /** @type {Tickable} */(synced).duration);
213
- return this.add(synced, { currentTime: [0, duration], duration, ease: 'linear' }, position);
221
+ return this.add(synced, { currentTime: [0, duration], duration, delay: 0, ease: 'linear', playbackEase: 'linear' }, position);
214
222
  }
215
223
 
216
224
  /**
@@ -233,7 +241,7 @@ class Timeline extends Timer {
233
241
  */
234
242
  call(callback, position) {
235
243
  if (isUnd(callback) || callback && !isFnc(callback)) return this;
236
- return this.add({ duration: 0, onComplete: () => callback(this) }, position);
244
+ return this.add({ duration: 0, delay: 0, onComplete: () => callback(this) }, position);
237
245
  }
238
246
 
239
247
  /**
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - timer - CJS
3
- * @version v4.2.1
3
+ * @version v4.3.0-beta.0
4
4
  * @license MIT
5
5
  * @copyright 2025 - Julian Garnier
6
6
  */
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - timer - ESM
3
- * @version v4.2.1
3
+ * @version v4.3.0-beta.0
4
4
  * @license MIT
5
5
  * @copyright 2025 - Julian Garnier
6
6
  */