animejs 4.2.2 → 4.3.0-beta.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 (133) hide show
  1. package/README.md +82 -28
  2. package/dist/bundles/anime.esm.js +2705 -1303
  3. package/dist/bundles/anime.esm.min.js +2 -2
  4. package/dist/bundles/anime.umd.js +2710 -1306
  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 +1 -1
  95. package/dist/modules/svg/motionpath.js +1 -1
  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.2
3
+ * @version v4.3.0-beta.1
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.2
3
+ * @version v4.3.0-beta.1
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.2
3
+ * @version v4.3.0-beta.1
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.2
3
+ * @version v4.3.0-beta.1
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.2
3
+ * @version v4.3.0-beta.1
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.2
3
+ * @version v4.3.0-beta.1
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.2
3
+ * @version v4.3.0-beta.1
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.2
3
+ * @version v4.3.0-beta.1
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.2
3
+ * @version v4.3.0-beta.1
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.2
3
+ * @version v4.3.0-beta.1
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.2
3
+ * @version v4.3.0-beta.1
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.2
3
+ * @version v4.3.0-beta.1
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.2
3
+ * @version v4.3.0-beta.1
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.2
3
+ * @version v4.3.0-beta.1
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.2
3
+ * @version v4.3.0-beta.1
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.2
3
+ * @version v4.3.0-beta.1
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.2
3
+ * @version v4.3.0-beta.1
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.2
3
+ * @version v4.3.0-beta.1
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.2
3
+ * @version v4.3.0-beta.1
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.2
3
+ * @version v4.3.0-beta.1
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.2
3
+ * @version v4.3.0-beta.1
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.2
3
+ * @version v4.3.0-beta.1
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.2
3
+ * @version v4.3.0-beta.1
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.2
3
+ * @version v4.3.0-beta.1
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.2
3
+ * @version v4.3.0-beta.1
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.2
3
+ * @version v4.3.0-beta.1
4
4
  * @license MIT
5
5
  * @copyright 2025 - Julian Garnier
6
6
  */
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - timer - CJS
3
- * @version v4.2.2
3
+ * @version v4.3.0-beta.1
4
4
  * @license MIT
5
5
  * @copyright 2025 - Julian Garnier
6
6
  */
@@ -82,6 +82,8 @@ class Timer extends clock.Clock {
82
82
 
83
83
  super(0);
84
84
 
85
+ ++timerId;
86
+
85
87
  const {
86
88
  id,
87
89
  delay,
@@ -103,31 +105,42 @@ class Timer extends clock.Clock {
103
105
 
104
106
  if (globals.scope.current) globals.scope.current.register(this);
105
107
 
106
- const timerInitTime = parent ? 0 : engine.engine._elapsedTime;
108
+ const timerInitTime = parent ? 0 : engine.engine._lastTickTime;
107
109
  const timerDefaults = parent ? parent.defaults : globals.globals.defaults;
108
110
  const timerDelay = /** @type {Number} */(helpers.isFnc(delay) || helpers.isUnd(delay) ? timerDefaults.delay : +delay);
109
111
  const timerDuration = helpers.isFnc(duration) || helpers.isUnd(duration) ? Infinity : +duration;
110
112
  const timerLoop = values.setValue(loop, timerDefaults.loop);
111
113
  const timerLoopDelay = values.setValue(loopDelay, timerDefaults.loopDelay);
112
- const timerIterationCount = timerLoop === true ||
113
- timerLoop === Infinity ||
114
- /** @type {Number} */(timerLoop) < 0 ? Infinity :
115
- /** @type {Number} */(timerLoop) + 1;
114
+ let timerIterationCount = timerLoop === true ||
115
+ timerLoop === Infinity ||
116
+ /** @type {Number} */(timerLoop) < 0 ? Infinity :
117
+ /** @type {Number} */(timerLoop) + 1;
118
+
119
+ if (globals.devTools) {
120
+ const isInfinite = timerIterationCount === Infinity;
121
+ const registered = globals.devTools.register(this, parameters, isInfinite);
122
+ if (registered && isInfinite) {
123
+ const minIterations = alternate ? 2 : 1;
124
+ const iterations = parent ? globals.devTools.maxNestedInfiniteLoops : globals.devTools.maxInfiniteLoops;
125
+ timerIterationCount = Math.max(iterations, minIterations);
126
+ }
127
+ }
116
128
 
117
129
  let offsetPosition = 0;
118
130
 
119
131
  if (parent) {
120
132
  offsetPosition = parentPosition;
121
133
  } else {
122
- // Make sure to tick the engine once if not currently running to get up to date engine._elapsedTime
134
+ // Make sure to tick the engine once if not currently running to get up to date engine._lastTickTime
123
135
  // to avoid big gaps with the following offsetPosition calculation
124
136
  if (!engine.engine.reqId) engine.engine.requestTick(helpers.now());
125
137
  // Make sure to scale the offset position with globals.timeScale to properly handle seconds unit
126
- offsetPosition = (engine.engine._elapsedTime - engine.engine._startTime) * globals.globals.timeScale;
138
+ offsetPosition = (engine.engine._lastTickTime - engine.engine._startTime) * globals.globals.timeScale;
127
139
  }
128
140
 
129
141
  // Timer's parameters
130
- this.id = !helpers.isUnd(id) ? id : ++timerId;
142
+ /** @type {String|Number} */
143
+ this.id = !helpers.isUnd(id) ? id : timerId;
131
144
  /** @type {Timeline} */
132
145
  this.parent = parent;
133
146
  // Total duration of the timer
@@ -187,7 +200,7 @@ class Timer extends clock.Clock {
187
200
 
188
201
  // Clock's parameters
189
202
  /** @type {Number} */
190
- this._elapsedTime = timerInitTime;
203
+ this._lastTickTime = timerInitTime;
191
204
  /** @type {Number} */
192
205
  this._startTime = timerInitTime;
193
206
  /** @type {Number} */
@@ -218,7 +231,7 @@ class Timer extends clock.Clock {
218
231
  }
219
232
 
220
233
  get iterationCurrentTime() {
221
- return helpers.round(this._iterationTime, globals.globals.precision);
234
+ return helpers.clamp(helpers.round(this._iterationTime, globals.globals.precision), 0, this.iterationDuration);
222
235
  }
223
236
 
224
237
  set iterationCurrentTime(time) {
@@ -316,9 +329,9 @@ class Timer extends clock.Clock {
316
329
  /** @return {this} */
317
330
  resetTime() {
318
331
  const timeScale = 1 / (this._speed * engine.engine._speed);
319
- // TODO: See if we can safely use engine._elapsedTime here
332
+ // TODO: See if we can safely use engine._lastTickTime here
320
333
  // if (!engine.reqId) engine.requestTick(now())
321
- // this._startTime = engine._elapsedTime - (this._currentTime + this._delay) * timeScale;
334
+ // this._startTime = engine._lastTickTime - (this._currentTime + this._delay) * timeScale;
322
335
  this._startTime = helpers.now() - (this._currentTime + this._delay) * timeScale;
323
336
  return this;
324
337
  }
@@ -8,6 +8,7 @@ export class Timer extends Clock {
8
8
  * @param {Number} [parentPosition]
9
9
  */
10
10
  constructor(parameters?: TimerParams, parent?: Timeline, parentPosition?: number);
11
+ /** @type {String|Number} */
11
12
  id: string | number;
12
13
  /** @type {Timeline} */
13
14
  parent: Timeline;