animejs 4.3.6 → 4.4.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 (142) hide show
  1. package/README.md +6 -9
  2. package/dist/bundles/anime.esm.js +973 -391
  3. package/dist/bundles/anime.esm.min.js +2 -2
  4. package/dist/bundles/anime.umd.js +977 -390
  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 +2 -2
  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 +38 -16
  13. package/dist/modules/animation/animation.d.ts +2 -2
  14. package/dist/modules/animation/animation.js +42 -20
  15. package/dist/modules/animation/composition.cjs +1 -1
  16. package/dist/modules/animation/composition.js +3 -3
  17. package/dist/modules/animation/index.cjs +1 -1
  18. package/dist/modules/animation/index.js +1 -1
  19. package/dist/modules/core/clock.cjs +1 -1
  20. package/dist/modules/core/clock.js +1 -1
  21. package/dist/modules/core/colors.cjs +1 -1
  22. package/dist/modules/core/colors.js +1 -1
  23. package/dist/modules/core/consts.cjs +3 -9
  24. package/dist/modules/core/consts.d.ts +1 -5
  25. package/dist/modules/core/consts.js +4 -8
  26. package/dist/modules/core/globals.cjs +16 -5
  27. package/dist/modules/core/globals.d.ts +22 -1
  28. package/dist/modules/core/globals.js +18 -6
  29. package/dist/modules/core/helpers.cjs +7 -10
  30. package/dist/modules/core/helpers.js +8 -11
  31. package/dist/modules/core/render.cjs +7 -34
  32. package/dist/modules/core/render.js +8 -35
  33. package/dist/modules/core/styles.cjs +53 -32
  34. package/dist/modules/core/styles.d.ts +1 -0
  35. package/dist/modules/core/styles.js +55 -35
  36. package/dist/modules/core/targets.cjs +1 -1
  37. package/dist/modules/core/targets.js +1 -1
  38. package/dist/modules/core/transforms.cjs +129 -13
  39. package/dist/modules/core/transforms.d.ts +1 -0
  40. package/dist/modules/core/transforms.js +130 -15
  41. package/dist/modules/core/units.cjs +1 -1
  42. package/dist/modules/core/units.js +1 -1
  43. package/dist/modules/core/values.cjs +68 -8
  44. package/dist/modules/core/values.d.ts +5 -2
  45. package/dist/modules/core/values.js +69 -11
  46. package/dist/modules/draggable/draggable.cjs +1 -1
  47. package/dist/modules/draggable/draggable.js +1 -1
  48. package/dist/modules/draggable/index.cjs +1 -1
  49. package/dist/modules/draggable/index.js +1 -1
  50. package/dist/modules/easings/cubic-bezier/index.cjs +1 -1
  51. package/dist/modules/easings/cubic-bezier/index.js +1 -1
  52. package/dist/modules/easings/eases/index.cjs +1 -1
  53. package/dist/modules/easings/eases/index.js +1 -1
  54. package/dist/modules/easings/eases/parser.cjs +1 -1
  55. package/dist/modules/easings/eases/parser.js +1 -1
  56. package/dist/modules/easings/index.cjs +1 -1
  57. package/dist/modules/easings/index.js +1 -1
  58. package/dist/modules/easings/irregular/index.cjs +1 -1
  59. package/dist/modules/easings/irregular/index.js +1 -1
  60. package/dist/modules/easings/linear/index.cjs +1 -1
  61. package/dist/modules/easings/linear/index.js +1 -1
  62. package/dist/modules/easings/none.cjs +1 -1
  63. package/dist/modules/easings/none.js +1 -1
  64. package/dist/modules/easings/spring/index.cjs +1 -1
  65. package/dist/modules/easings/spring/index.js +1 -1
  66. package/dist/modules/easings/steps/index.cjs +1 -1
  67. package/dist/modules/easings/steps/index.js +1 -1
  68. package/dist/modules/engine/engine.cjs +1 -1
  69. package/dist/modules/engine/engine.js +1 -1
  70. package/dist/modules/engine/index.cjs +1 -1
  71. package/dist/modules/engine/index.js +1 -1
  72. package/dist/modules/events/index.cjs +1 -1
  73. package/dist/modules/events/index.js +1 -1
  74. package/dist/modules/events/scroll.cjs +1 -1
  75. package/dist/modules/events/scroll.js +1 -1
  76. package/dist/modules/index.cjs +9 -1
  77. package/dist/modules/index.d.ts +1 -0
  78. package/dist/modules/index.js +4 -1
  79. package/dist/modules/layout/index.cjs +1 -1
  80. package/dist/modules/layout/index.js +1 -1
  81. package/dist/modules/layout/layout.cjs +29 -25
  82. package/dist/modules/layout/layout.d.ts +4 -3
  83. package/dist/modules/layout/layout.js +30 -26
  84. package/dist/modules/scope/index.cjs +1 -1
  85. package/dist/modules/scope/index.js +1 -1
  86. package/dist/modules/scope/scope.cjs +1 -1
  87. package/dist/modules/scope/scope.js +1 -1
  88. package/dist/modules/svg/drawable.cjs +1 -1
  89. package/dist/modules/svg/drawable.js +1 -1
  90. package/dist/modules/svg/helpers.cjs +1 -1
  91. package/dist/modules/svg/helpers.js +1 -1
  92. package/dist/modules/svg/index.cjs +1 -1
  93. package/dist/modules/svg/index.js +1 -1
  94. package/dist/modules/svg/morphto.cjs +3 -6
  95. package/dist/modules/svg/morphto.js +3 -6
  96. package/dist/modules/svg/motionpath.cjs +1 -1
  97. package/dist/modules/svg/motionpath.js +1 -1
  98. package/dist/modules/text/index.cjs +3 -1
  99. package/dist/modules/text/index.d.ts +1 -0
  100. package/dist/modules/text/index.js +2 -1
  101. package/dist/modules/text/scramble.cjs +272 -0
  102. package/dist/modules/text/scramble.d.ts +3 -0
  103. package/dist/modules/text/scramble.js +270 -0
  104. package/dist/modules/text/split.cjs +5 -5
  105. package/dist/modules/text/split.d.ts +5 -5
  106. package/dist/modules/text/split.js +5 -5
  107. package/dist/modules/timeline/index.cjs +1 -1
  108. package/dist/modules/timeline/index.js +1 -1
  109. package/dist/modules/timeline/position.cjs +1 -1
  110. package/dist/modules/timeline/position.js +1 -1
  111. package/dist/modules/timeline/timeline.cjs +36 -18
  112. package/dist/modules/timeline/timeline.d.ts +6 -5
  113. package/dist/modules/timeline/timeline.js +37 -19
  114. package/dist/modules/timer/index.cjs +1 -1
  115. package/dist/modules/timer/index.js +1 -1
  116. package/dist/modules/timer/timer.cjs +8 -12
  117. package/dist/modules/timer/timer.d.ts +2 -0
  118. package/dist/modules/timer/timer.js +9 -13
  119. package/dist/modules/types/index.d.ts +76 -8
  120. package/dist/modules/utils/chainable.cjs +8 -5
  121. package/dist/modules/utils/chainable.js +8 -5
  122. package/dist/modules/utils/index.cjs +5 -1
  123. package/dist/modules/utils/index.d.ts +1 -0
  124. package/dist/modules/utils/index.js +2 -1
  125. package/dist/modules/utils/number.cjs +1 -1
  126. package/dist/modules/utils/number.js +1 -1
  127. package/dist/modules/utils/random.cjs +1 -1
  128. package/dist/modules/utils/random.js +1 -1
  129. package/dist/modules/utils/stagger.cjs +117 -20
  130. package/dist/modules/utils/stagger.js +118 -21
  131. package/dist/modules/utils/target.cjs +1 -1
  132. package/dist/modules/utils/target.js +1 -1
  133. package/dist/modules/utils/time.cjs +5 -3
  134. package/dist/modules/utils/time.d.ts +1 -1
  135. package/dist/modules/utils/time.js +5 -3
  136. package/dist/modules/waapi/composition.cjs +1 -1
  137. package/dist/modules/waapi/composition.js +1 -1
  138. package/dist/modules/waapi/index.cjs +1 -1
  139. package/dist/modules/waapi/index.js +1 -1
  140. package/dist/modules/waapi/waapi.cjs +19 -20
  141. package/dist/modules/waapi/waapi.js +20 -21
  142. package/package.json +2 -1
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - layout - ESM
3
- * @version v4.3.6
3
+ * @version v4.4.1
4
4
  * @license MIT
5
5
  * @copyright 2026 - Julian Garnier
6
6
  */
@@ -11,7 +11,7 @@ import { parseEase } from '../easings/eases/parser.js';
11
11
  import { setValue, getFunctionValue } from '../core/values.js';
12
12
  import { createTimeline } from '../timeline/timeline.js';
13
13
  import { waapi } from '../waapi/waapi.js';
14
- import { scope, defaults } from '../core/globals.js';
14
+ import { scope, defaults, globals } from '../core/globals.js';
15
15
 
16
16
  /**
17
17
  * @import {
@@ -77,6 +77,7 @@ import { scope, defaults } from '../core/globals.js';
77
77
 
78
78
  /**
79
79
  * @typedef {Object} LayoutSpecificAnimationParams
80
+ * @property {Number|String} [id]
80
81
  * @property {Number|FunctionValue} [delay]
81
82
  * @property {Number|FunctionValue} [duration]
82
83
  * @property {EasingParam|FunctionValue} [ease]
@@ -119,7 +120,7 @@ import { scope, defaults } from '../core/globals.js';
119
120
  * @property {String} id
120
121
  * @property {DOMTarget} $el
121
122
  * @property {Number} index
122
- * @property {Number} total
123
+ * @property {Array<DOMTarget>} targets
123
124
  * @property {Number} delay
124
125
  * @property {Number} duration
125
126
  * @property {EasingParam} ease
@@ -263,7 +264,7 @@ const createNode = ($el, parentNode, state, recycledNode) => {
263
264
  node.$measure = $el;
264
265
  node.id = dataId;
265
266
  node.index = 0;
266
- node.total = 1;
267
+ node.targets = null;
267
268
  node.delay = 0;
268
269
  node.duration = 0;
269
270
  node.ease = null;
@@ -449,12 +450,12 @@ const updateNodeProperties = (node, props) => {
449
450
  * @param {LayoutAnimationTimingsParams} params
450
451
  */
451
452
  const updateNodeTimingParams = (node, params) => {
452
- const easeFunctionResult = getFunctionValue(params.ease, node.$el, node.index, node.total);
453
+ const easeFunctionResult = getFunctionValue(params.ease, node.$el, node.index, node.targets, null, null);
453
454
  const keyEasing = isFnc(easeFunctionResult) ? easeFunctionResult : params.ease;
454
455
  const hasSpring = !isUnd(keyEasing) && !isUnd(/** @type {Spring} */(keyEasing).ease);
455
456
  node.ease = hasSpring ? /** @type {Spring} */(keyEasing).ease : keyEasing;
456
- node.duration = hasSpring ? /** @type {Spring} */(keyEasing).settlingDuration : getFunctionValue(params.duration, node.$el, node.index, node.total);
457
- node.delay = getFunctionValue(params.delay, node.$el, node.index, node.total);
457
+ node.duration = hasSpring ? /** @type {Spring} */(keyEasing).settlingDuration : getFunctionValue(params.duration, node.$el, node.index, node.targets, null, null);
458
+ node.delay = getFunctionValue(params.delay, node.$el, node.index, node.targets, null, null);
458
459
  };
459
460
 
460
461
  /**
@@ -827,10 +828,12 @@ class LayoutSnapshot {
827
828
 
828
829
  const inRootNodeIds = new Set();
829
830
  // Update index and total for inital timing calculation
830
- let index = 0, total = this.nodes.size;
831
+ let index = 0;
832
+ const allNodeTargets = [];
833
+ this.nodes.forEach((node) => { allNodeTargets.push(node.$el); });
831
834
  this.nodes.forEach((node, id) => {
832
835
  node.index = index++;
833
- node.total = total;
836
+ node.targets = allNodeTargets;
834
837
  // Track ids of nodes that belong to the current root to filter detached matches
835
838
  if (node && node.measuredIsInsideRoot) {
836
839
  inRootNodeIds.add(id);
@@ -942,8 +945,8 @@ class AutoLayout {
942
945
  this.params = params;
943
946
  /** @type {DOMTarget} */
944
947
  this.root = /** @type {DOMTarget} */(registerTargets(root)[0]);
945
- /** @type {Number} */
946
- this.id = layoutId++;
948
+ /** @type {Number|String} */
949
+ this.id = params.id || layoutId++;
947
950
  /** @type {LayoutChildrenParam} */
948
951
  this.children = params.children || '*';
949
952
  /** @type {Boolean} */
@@ -1066,7 +1069,9 @@ class AutoLayout {
1066
1069
  duration: setValue(params.duration, this.params.duration),
1067
1070
  };
1068
1071
  /** @type {TimelineParams} */
1069
- const tlParams = {};
1072
+ const tlParams = {
1073
+ id: this.id
1074
+ };
1070
1075
  const onComplete = setValue(params.onComplete, this.params.onComplete);
1071
1076
  const onPause = setValue(params.onPause, this.params.onPause);
1072
1077
  for (let name in defaults) {
@@ -1080,7 +1085,8 @@ class AutoLayout {
1080
1085
  }
1081
1086
  tlParams.onComplete = () => {
1082
1087
  const ap = /** @type {ScrollObserver} */(params.autoplay);
1083
- const isScrollControled = ap && ap.linked;
1088
+ const ed = globals.editor;
1089
+ const isScrollControled = (ap && ap.linked) || (ed && ed.showPanel);
1084
1090
  if (isScrollControled) {
1085
1091
  if (onComplete) onComplete(this.timeline);
1086
1092
  return;
@@ -1279,41 +1285,39 @@ class AutoLayout {
1279
1285
  animatedParent = animatedParent.parentNode;
1280
1286
  }
1281
1287
 
1282
- const animatingTotal = animating.length;
1283
-
1284
1288
  // Root is always animated first in sync with the first child (animating.length is the total of children)
1285
1289
  if (node === rootNode) {
1286
1290
  node.index = 0;
1287
- node.total = animatingTotal;
1291
+ node.targets = animating;
1288
1292
  updateNodeTimingParams(node, animationTimings);
1289
1293
  } else if (node.isEntering) {
1290
1294
  node.index = animatedParent ? animatedParent.index : enteringIndex;
1291
- node.total = animatedParent ? animatingTotal : entering.length;
1295
+ node.targets = animatedParent ? animating : entering;
1292
1296
  updateNodeTimingParams(node, enterFromTimings);
1293
1297
  enteringIndex++;
1294
1298
  } else if (node.isLeaving) {
1295
1299
  node.index = animatedParent ? animatedParent.index : leavingIndex;
1296
- node.total = animatedParent ? animatingTotal : leaving.length;
1300
+ node.targets = animatedParent ? animating : leaving;
1297
1301
  leavingIndex++;
1298
1302
  updateNodeTimingParams(node, leaveToTimings);
1299
1303
  } else if (node.isTarget) {
1300
1304
  node.index = animatingIndex++;
1301
- node.total = animatingTotal;
1305
+ node.targets = animating;
1302
1306
  updateNodeTimingParams(node, animationTimings);
1303
1307
  } else {
1304
1308
  node.index = animatedParent ? animatedParent.index : 0;
1305
- node.total = animatingTotal;
1309
+ node.targets = animating;
1306
1310
  updateNodeTimingParams(node, swapAtTimings);
1307
1311
  }
1308
1312
 
1309
1313
  // Make sure the old state node has its inex and total values up to date for valid "from" function values calculation
1310
1314
  oldStateNode.index = node.index;
1311
- oldStateNode.total = node.total;
1315
+ oldStateNode.targets = node.targets;
1312
1316
 
1313
1317
  // Computes all values up front so we can check for changes and we don't have to re-compute them inside the animation props
1314
1318
  for (let prop in nodeProperties) {
1315
- nodeProperties[prop] = getFunctionValue(nodeProperties[prop], $el, node.index, node.total);
1316
- oldStateNodeProperties[prop] = getFunctionValue(oldStateNodeProperties[prop], $el, oldStateNode.index, oldStateNode.total);
1319
+ nodeProperties[prop] = getFunctionValue(nodeProperties[prop], $el, node.index, node.targets, null, null);
1320
+ oldStateNodeProperties[prop] = getFunctionValue(oldStateNodeProperties[prop], $el, oldStateNode.index, oldStateNode.targets, null, null);
1317
1321
  }
1318
1322
 
1319
1323
  // Use a 1px tolerance to detect dimensions changes to prevent width / height animations on barelly visible elements
@@ -1539,8 +1543,8 @@ class AutoLayout {
1539
1543
  }
1540
1544
  $el.style.transform = oldState.getComputedValue($el, 'transform');
1541
1545
  if (animatedSwap.includes($el)) {
1542
- node.ease = getFunctionValue(swapAtParams.ease, $el, node.index, node.total);
1543
- node.duration = getFunctionValue(swapAtParams.duration, $el, node.index, node.total);
1546
+ node.ease = getFunctionValue(swapAtParams.ease, $el, node.index, node.targets, null, null);
1547
+ node.duration = getFunctionValue(swapAtParams.duration, $el, node.index, node.targets, null, null);
1544
1548
  }
1545
1549
  }
1546
1550
  this.transformAnimation = waapi.animate(transformed, {
@@ -1555,7 +1559,7 @@ class AutoLayout {
1555
1559
  if (!animatedSwap.includes($el)) return newValue;
1556
1560
  const oldValue = oldState.getComputedValue($el, 'transform');
1557
1561
  const node = newState.getNode($el);
1558
- return [oldValue, getFunctionValue(swapAtProps.transform, $el, node.index, node.total), newValue]
1562
+ return [oldValue, getFunctionValue(swapAtProps.transform, $el, node.index, node.targets, null, null), newValue]
1559
1563
  },
1560
1564
  autoplay: false,
1561
1565
  // persist: true,
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - scope - CJS
3
- * @version v4.3.6
3
+ * @version v4.4.1
4
4
  * @license MIT
5
5
  * @copyright 2026 - Julian Garnier
6
6
  */
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - scope - ESM
3
- * @version v4.3.6
3
+ * @version v4.4.1
4
4
  * @license MIT
5
5
  * @copyright 2026 - Julian Garnier
6
6
  */
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - scope - CJS
3
- * @version v4.3.6
3
+ * @version v4.4.1
4
4
  * @license MIT
5
5
  * @copyright 2026 - Julian Garnier
6
6
  */
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - scope - ESM
3
- * @version v4.3.6
3
+ * @version v4.4.1
4
4
  * @license MIT
5
5
  * @copyright 2026 - Julian Garnier
6
6
  */
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - svg - CJS
3
- * @version v4.3.6
3
+ * @version v4.4.1
4
4
  * @license MIT
5
5
  * @copyright 2026 - Julian Garnier
6
6
  */
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - svg - ESM
3
- * @version v4.3.6
3
+ * @version v4.4.1
4
4
  * @license MIT
5
5
  * @copyright 2026 - Julian Garnier
6
6
  */
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - svg - CJS
3
- * @version v4.3.6
3
+ * @version v4.4.1
4
4
  * @license MIT
5
5
  * @copyright 2026 - Julian Garnier
6
6
  */
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - svg - ESM
3
- * @version v4.3.6
3
+ * @version v4.4.1
4
4
  * @license MIT
5
5
  * @copyright 2026 - Julian Garnier
6
6
  */
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - svg - CJS
3
- * @version v4.3.6
3
+ * @version v4.4.1
4
4
  * @license MIT
5
5
  * @copyright 2026 - Julian Garnier
6
6
  */
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - svg - ESM
3
- * @version v4.3.6
3
+ * @version v4.4.1
4
4
  * @license MIT
5
5
  * @copyright 2026 - Julian Garnier
6
6
  */
@@ -1,13 +1,12 @@
1
1
  /**
2
2
  * Anime.js - svg - CJS
3
- * @version v4.3.6
3
+ * @version v4.4.1
4
4
  * @license MIT
5
5
  * @copyright 2026 - Julian Garnier
6
6
  */
7
7
 
8
8
  'use strict';
9
9
 
10
- var consts = require('../core/consts.cjs');
11
10
  var helpers$1 = require('../core/helpers.cjs');
12
11
  var helpers = require('./helpers.cjs');
13
12
 
@@ -23,7 +22,7 @@ var helpers = require('./helpers.cjs');
23
22
  * @param {Number} [precision]
24
23
  * @return {FunctionValue}
25
24
  */
26
- const morphTo = (path2, precision = .33) => ($path1) => {
25
+ const morphTo = (path2, precision = .33) => ($path1, index, total, prevTween) => {
27
26
  const tagName1 = ($path1.tagName || '').toLowerCase();
28
27
  if (!tagName1.match(/^(path|polygon|polyline)$/)) {
29
28
  throw new Error(`Can't morph a <${$path1.tagName}> SVG element. Use <path>, <polygon> or <polyline>.`);
@@ -38,7 +37,7 @@ const morphTo = (path2, precision = .33) => ($path1) => {
38
37
  }
39
38
  const isPath = $path1.tagName === 'path';
40
39
  const separator = isPath ? ' ' : ',';
41
- const previousPoints = $path1[consts.morphPointsSymbol];
40
+ const previousPoints = prevTween ? prevTween._value : null;
42
41
  if (previousPoints) $path1.setAttribute(isPath ? 'd' : 'points', previousPoints);
43
42
 
44
43
  let v1 = '', v2 = '';
@@ -60,8 +59,6 @@ const morphTo = (path2, precision = .33) => ($path1) => {
60
59
  }
61
60
  }
62
61
 
63
- $path1[consts.morphPointsSymbol] = v2;
64
-
65
62
  return [v1, v2];
66
63
  };
67
64
 
@@ -1,11 +1,10 @@
1
1
  /**
2
2
  * Anime.js - svg - ESM
3
- * @version v4.3.6
3
+ * @version v4.4.1
4
4
  * @license MIT
5
5
  * @copyright 2026 - Julian Garnier
6
6
  */
7
7
 
8
- import { morphPointsSymbol } from '../core/consts.js';
9
8
  import { round } from '../core/helpers.js';
10
9
  import { getPath } from './helpers.js';
11
10
 
@@ -21,7 +20,7 @@ import { getPath } from './helpers.js';
21
20
  * @param {Number} [precision]
22
21
  * @return {FunctionValue}
23
22
  */
24
- const morphTo = (path2, precision = .33) => ($path1) => {
23
+ const morphTo = (path2, precision = .33) => ($path1, index, total, prevTween) => {
25
24
  const tagName1 = ($path1.tagName || '').toLowerCase();
26
25
  if (!tagName1.match(/^(path|polygon|polyline)$/)) {
27
26
  throw new Error(`Can't morph a <${$path1.tagName}> SVG element. Use <path>, <polygon> or <polyline>.`);
@@ -36,7 +35,7 @@ const morphTo = (path2, precision = .33) => ($path1) => {
36
35
  }
37
36
  const isPath = $path1.tagName === 'path';
38
37
  const separator = isPath ? ' ' : ',';
39
- const previousPoints = $path1[morphPointsSymbol];
38
+ const previousPoints = prevTween ? prevTween._value : null;
40
39
  if (previousPoints) $path1.setAttribute(isPath ? 'd' : 'points', previousPoints);
41
40
 
42
41
  let v1 = '', v2 = '';
@@ -58,8 +57,6 @@ const morphTo = (path2, precision = .33) => ($path1) => {
58
57
  }
59
58
  }
60
59
 
61
- $path1[morphPointsSymbol] = v2;
62
-
63
60
  return [v1, v2];
64
61
  };
65
62
 
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - svg - CJS
3
- * @version v4.3.6
3
+ * @version v4.4.1
4
4
  * @license MIT
5
5
  * @copyright 2026 - Julian Garnier
6
6
  */
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - svg - ESM
3
- * @version v4.3.6
3
+ * @version v4.4.1
4
4
  * @license MIT
5
5
  * @copyright 2026 - Julian Garnier
6
6
  */
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Anime.js - text - CJS
3
- * @version v4.3.6
3
+ * @version v4.4.1
4
4
  * @license MIT
5
5
  * @copyright 2026 - Julian Garnier
6
6
  */
@@ -8,9 +8,11 @@
8
8
  'use strict';
9
9
 
10
10
  var split = require('./split.cjs');
11
+ var scramble = require('./scramble.cjs');
11
12
 
12
13
 
13
14
 
14
15
  exports.TextSplitter = split.TextSplitter;
15
16
  exports.split = split.split;
16
17
  exports.splitText = split.splitText;
18
+ exports.scrambleText = scramble.scrambleText;
@@ -1 +1,2 @@
1
1
  export * from "./split.js";
2
+ export * from "./scramble.js";
@@ -1,8 +1,9 @@
1
1
  /**
2
2
  * Anime.js - text - ESM
3
- * @version v4.3.6
3
+ * @version v4.4.1
4
4
  * @license MIT
5
5
  * @copyright 2026 - Julian Garnier
6
6
  */
7
7
 
8
8
  export { TextSplitter, split, splitText } from './split.js';
9
+ export { scrambleText } from './scramble.js';
@@ -0,0 +1,272 @@
1
+ /**
2
+ * Anime.js - text - CJS
3
+ * @version v4.4.1
4
+ * @license MIT
5
+ * @copyright 2026 - Julian Garnier
6
+ */
7
+
8
+ 'use strict';
9
+
10
+ var random = require('../utils/random.cjs');
11
+ var globals = require('../core/globals.cjs');
12
+ var helpers = require('../core/helpers.cjs');
13
+ var parser = require('../easings/eases/parser.cjs');
14
+ var consts = require('../core/consts.cjs');
15
+
16
+ /**
17
+ * @import {
18
+ * ScrambleTextParams,
19
+ * FunctionValue,
20
+ * } from '../types/index.js'
21
+ */
22
+
23
+ /**
24
+ * '-' is the range operator; place it at the start or end of the string to use it as a literal (e.g. '-abc' or 'abc-')
25
+ * @param {String} str
26
+ * @return {String}
27
+ */
28
+ const expandCharRanges = (str) => {
29
+ let result = '';
30
+ for (let i = 0, l = str.length; i < l; i++) {
31
+ if (i + 2 < l && str[i + 1] === '-' && str.charCodeAt(i) < str.charCodeAt(i + 2)) {
32
+ const start = str.charCodeAt(i);
33
+ const end = str.charCodeAt(i + 2);
34
+ for (let c = start; c <= end; c++) result += String.fromCharCode(c);
35
+ i += 2;
36
+ } else {
37
+ result += str[i];
38
+ }
39
+ }
40
+ return result;
41
+ };
42
+
43
+ const charSets = {
44
+ lowercase: 'a-z',
45
+ uppercase: 'A-Z',
46
+ numbers: '0-9',
47
+ symbols: '!%#_|*+=',
48
+ braille: '⠀-⣿',
49
+ blocks: '▀-▟',
50
+ shades: '░-▓',
51
+ };
52
+
53
+ const originalTexts = new WeakMap();
54
+
55
+ /**
56
+ * Returns a function-based tween value that scrambles the target's text content,
57
+ * progressively revealing the original text.
58
+ *
59
+ * @param {ScrambleTextParams} [params]
60
+ * @return {FunctionValue}
61
+ */
62
+ const scrambleText = (params = {}) => {
63
+ if (!params) params = {};
64
+ const charsParam = params.chars;
65
+ const easeFn = parser.parseEase(params.ease || 'linear');
66
+ const text = params.text;
67
+ const fromParam = params.from;
68
+ const reversed = params.reversed || false;
69
+ const perturbation = params.perturbation || 0;
70
+ const cursorParam = params.cursor;
71
+ const cursorChars = cursorParam === true ? '_'
72
+ : typeof cursorParam === 'number' ? String.fromCharCode(cursorParam)
73
+ : typeof cursorParam === 'string' ? cursorParam
74
+ : '';
75
+ const cursorLen = cursorChars.length;
76
+ const seed = params.seed || 0;
77
+ const override = params.override !== undefined ? params.override : true;
78
+ const revealRate = params.revealRate || 60;
79
+ const interval = 1000 * globals.globals.timeScale / revealRate;
80
+ const settleDuration = params.settleDuration || 300 * globals.globals.timeScale;
81
+ const settleRate = params.settleRate || 30;
82
+ const durationParam = params.duration;
83
+ const revealDelayParam = params.revealDelay;
84
+ const delayParam = params.delay;
85
+ const onChange = params.onChange || consts.noop;
86
+
87
+ return (target, index, targets, prevTween) => {
88
+ const rawChars = typeof charsParam === 'function' ? charsParam(target, index, targets) : (charsParam || 'a-zA-Z0-9!%#_');
89
+ const characters = expandCharRanges(charSets[rawChars] || rawChars);
90
+ const totalChars = characters.length - 1;
91
+ const duration = typeof durationParam === 'function' ? durationParam(target, index, targets) : durationParam;
92
+ const revealDelay = typeof revealDelayParam === 'function' ? revealDelayParam(target, index, targets) : (revealDelayParam || 0);
93
+ const delay = typeof delayParam === 'function' ? delayParam(target, index, targets) : (delayParam || 0);
94
+ const rng = seed ? random.createSeededRandom(seed) : random.createSeededRandom();
95
+ if (!originalTexts.has(target)) originalTexts.set(target, target.textContent);
96
+ const startingText = prevTween ? prevTween._value : target.textContent;
97
+ const targetText = text !== undefined
98
+ ? (typeof text === 'function' ? text(target, index, targets) : text)
99
+ : prevTween ? prevTween._value
100
+ : originalTexts.get(target);
101
+ const settledText = targetText === ' ' || targetText === '&nbsp;' ? ' ' : targetText;
102
+ const startLength = startingText === ' ' ? 0 : startingText.length;
103
+ const endLength = settledText.length;
104
+ const overrideChars = override === true ? characters
105
+ : typeof override === 'string' && override.length > 0 ? expandCharRanges(charSets[/** @type {String} */(override)] || /** @type {String} */(override))
106
+ : null;
107
+ const totalOverrideChars = overrideChars ? overrideChars.length - 1 : 0;
108
+ // Space override uses &nbsp; so the browser doesn't collapse consecutive spaces in innerHTML
109
+ const overrideChar = override === ' ' ? ' ' : null;
110
+ // When starting from blank, only animate the target text length to avoid padding beyond it
111
+ const animLength = override === '' ? endLength : Math.max(startLength, endLength);
112
+ // Compute total duration from interval spacing and settle time, or use the explicit duration
113
+ const animDuration = duration > 0 ? duration : (animLength - 1) * interval + settleDuration;
114
+ const computedDuration = helpers.round((animDuration + revealDelay) / globals.globals.timeScale, 0) * globals.globals.timeScale;
115
+ const revealDelayRatio = revealDelay > 0 ? helpers.round(revealDelay / computedDuration, 12) : 0;
116
+ // Auto-resolve reveal direction: shrinking text reveals from right, growing from left
117
+ const resolvedFrom = fromParam === undefined || fromParam === 'auto' ? (endLength < startLength ? 'right' : 'left') : fromParam;
118
+ const charOrder = new Int32Array(animLength);
119
+ if (resolvedFrom === 'random') {
120
+ for (let i = 0; i < animLength; i++) charOrder[i] = i;
121
+ for (let i = animLength - 1; i > 0; i--) {
122
+ const j = rng(0, i);
123
+ const t = charOrder[i]; charOrder[i] = charOrder[j]; charOrder[j] = t;
124
+ }
125
+ } else {
126
+ const ref = resolvedFrom === 'right' ? (override === '' || !startLength ? animLength : startLength) - 1
127
+ : resolvedFrom === 'center' ? ((override === '' || !startLength ? animLength : startLength) - 1) / 2
128
+ : typeof resolvedFrom === 'number' ? resolvedFrom
129
+ : 0;
130
+ const abs = Math.abs;
131
+ const indices = new Array(animLength);
132
+ for (let i = 0; i < animLength; i++) indices[i] = i;
133
+ indices.sort((a, b) => abs(a - ref) - abs(b - ref));
134
+ for (let i = 0; i < animLength; i++) charOrder[indices[i]] = i;
135
+ }
136
+ if (reversed) {
137
+ const last = animLength - 1;
138
+ for (let i = 0; i < animLength; i++) charOrder[i] = last - charOrder[i];
139
+ }
140
+ // settleRatio is the fraction of the animation each character spends in the active scrambling zone
141
+ const settleRatio = helpers.round(settleDuration / animDuration, 12);
142
+ // settleSpacing is the time gap between consecutive characters entering the active zone
143
+ const settleSpacing = helpers.round((1 - settleRatio) / animLength, 12);
144
+ const cursorZone = cursorLen * settleSpacing;
145
+ // stepRatio controls how often scramble characters refresh (based on settleRate)
146
+ const stepRatio = helpers.round(1000 * globals.globals.timeScale / (settleRate * computedDuration), 12);
147
+ // Pre-compute per-character start and settle times
148
+ const charStarts = new Float32Array(animLength);
149
+ const charEnds = new Float32Array(animLength);
150
+ const scale = perturbation > 0 ? perturbation * settleRatio : 0;
151
+ for (let c = 0; c < animLength; c++) {
152
+ const so = scale > 0 ? (rng(0, 2000) - 1000) / 1000 * scale : 0;
153
+ const eo = scale > 0 ? (rng(0, 2000) - 1000) / 1000 * scale : 0;
154
+ charStarts[c] = charOrder[c] * settleSpacing + so;
155
+ charEnds[c] = Math.ceil((charStarts[c] + settleRatio + eo) / stepRatio) * stepRatio;
156
+ }
157
+ // When text shrinks with non-sequential from modes, delay target settle times past all extras
158
+ if (endLength < animLength && resolvedFrom !== 'left' && resolvedFrom !== 'right' && resolvedFrom !== 'random') {
159
+ let maxExtraEnd = 0;
160
+ for (let c = endLength; c < animLength; c++) {
161
+ if (charEnds[c] > maxExtraEnd) maxExtraEnd = charEnds[c];
162
+ }
163
+ const targets = new Array(endLength);
164
+ for (let c = 0; c < endLength; c++) targets[c] = c;
165
+ targets.sort((a, b) => charOrder[a] - charOrder[b]);
166
+ const targetSpacing = (1 - maxExtraEnd) / endLength;
167
+ for (let i = 0; i < endLength; i++) {
168
+ const revealTime = maxExtraEnd + i * targetSpacing;
169
+ if (revealTime > charEnds[targets[i]]) {
170
+ charEnds[targets[i]] = revealTime;
171
+ }
172
+ }
173
+ }
174
+ // charCache holds the current scramble character for each position, refreshed at settleRate
175
+ const charCache = new Array(animLength);
176
+ for (let c = 0; c < animLength; c++) {
177
+ charCache[c] = characters[rng(0, totalChars)];
178
+ }
179
+ // overrideCache holds scramble characters for the starting text (override: true or custom string)
180
+ const overrideCache = overrideChars ? (overrideChars === characters ? charCache : new Array(animLength)) : null;
181
+ if (overrideCache && overrideCache !== charCache) {
182
+ for (let c = 0; c < animLength; c++) {
183
+ overrideCache[c] = overrideChar || /** @type {String} */(overrideChars)[rng(0, overrideChars.length - 1)];
184
+ }
185
+ }
186
+ // Build the initial display text based on override mode
187
+ let fillStartText = startingText;
188
+ if (!prevTween) {
189
+ if (override === '') {
190
+ fillStartText = '';
191
+ } else if (overrideChars) {
192
+ fillStartText = '';
193
+ for (let c = 0; c < startLength; c++) {
194
+ fillStartText += startingText[c] === ' ' ? ' ' : /** @type {Array<String>} */(overrideCache)[c];
195
+ }
196
+ }
197
+ }
198
+
199
+ let lastValue = -1;
200
+ let lastStep = -1;
201
+ let scrambled = '';
202
+ const hasOverride = override !== '';
203
+ const hasOverrideChars = !!overrideChars;
204
+ const hasCursor = cursorLen > 0;
205
+
206
+ return {
207
+ from: 0,
208
+ to: 1,
209
+ duration: computedDuration,
210
+ delay: delay,
211
+ ease: 'linear',
212
+ modifier: (v) => {
213
+ if (v === lastValue) return scrambled;
214
+ lastValue = v;
215
+ if (delay > 0 && v <= 0) { scrambled = startingText; return startingText; }
216
+ if (v <= 0) { scrambled = fillStartText; return fillStartText; }
217
+ if (v >= 1) { scrambled = settledText; return settledText; }
218
+ scrambled = '';
219
+ // Only refresh scramble characters when we cross a settleRate step boundary
220
+ const currentStep = (v / stepRatio) | 0;
221
+ const refreshChars = currentStep !== lastStep;
222
+ if (refreshChars) lastStep = currentStep;
223
+ // Subtract delay ratio to get the effective animation progress
224
+ const linear = revealDelayRatio > 0 ? (v - revealDelayRatio) / (1 - revealDelayRatio) : v;
225
+ const t = linear > 0 ? easeFn(linear) : 0;
226
+ for (let c = 0; c < animLength; c++) {
227
+ // Each character has its own start/end window based on its reveal order
228
+ const charStart = charStarts[c];
229
+ const charEnd = charEnds[c];
230
+ // Settled zone: character has finished its transition
231
+ if (t >= charEnd) {
232
+ if (c < endLength) scrambled += settledText[c];
233
+ continue;
234
+ }
235
+ // Pre-transition zone: reveal wave hasn't reached this character yet
236
+ if (t <= 0 || t < charStart) {
237
+ if (hasOverride && c < startLength) {
238
+ if (hasOverrideChars) {
239
+ if (startingText[c] === ' ') {
240
+ scrambled += ' ';
241
+ } else {
242
+ if (refreshChars) /** @type {Array<String>} */(overrideCache)[c] = overrideChar || /** @type {String} */(overrideChars)[rng(0, totalOverrideChars)];
243
+ scrambled += /** @type {Array<String>} */(overrideCache)[c];
244
+ }
245
+ } else {
246
+ // Default (override: false): show the original starting text
247
+ scrambled += startingText[c];
248
+ }
249
+ }
250
+ continue;
251
+ }
252
+ // Active zone: character is between charStart and charEnd
253
+ const isSpace = (c < endLength && settledText[c] === ' ') || (c < startLength && startingText[c] === ' ');
254
+ if (isSpace) {
255
+ scrambled += ' ';
256
+ } else if (hasCursor && t - charStart < cursorZone) {
257
+ // Cursor sub-zone: show cursor character based on position within cursor width
258
+ scrambled += cursorChars[cursorLen - 1 - (((t - charStart) / settleSpacing) | 0)];
259
+ } else {
260
+ // Scramble zone: show cycling random characters
261
+ if (refreshChars) charCache[c] = characters[rng(0, totalChars)];
262
+ scrambled += charCache[c];
263
+ }
264
+ }
265
+ if (refreshChars) onChange(scrambled, t);
266
+ return scrambled;
267
+ }
268
+ }
269
+ }
270
+ };
271
+
272
+ exports.scrambleText = scrambleText;