animejs 4.3.5 → 4.4.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.
- package/README.md +9 -12
- package/dist/bundles/anime.esm.js +1048 -421
- package/dist/bundles/anime.esm.min.js +2 -2
- package/dist/bundles/anime.umd.js +1053 -421
- package/dist/bundles/anime.umd.min.js +2 -2
- package/dist/modules/animatable/animatable.cjs +1 -1
- package/dist/modules/animatable/animatable.js +2 -2
- package/dist/modules/animatable/index.cjs +1 -1
- package/dist/modules/animatable/index.js +1 -1
- package/dist/modules/animation/additive.cjs +1 -1
- package/dist/modules/animation/additive.js +1 -1
- package/dist/modules/animation/animation.cjs +38 -16
- package/dist/modules/animation/animation.d.ts +2 -2
- package/dist/modules/animation/animation.js +42 -20
- package/dist/modules/animation/composition.cjs +1 -1
- package/dist/modules/animation/composition.js +3 -3
- package/dist/modules/animation/index.cjs +1 -1
- package/dist/modules/animation/index.js +1 -1
- package/dist/modules/core/clock.cjs +1 -1
- package/dist/modules/core/clock.js +1 -1
- package/dist/modules/core/colors.cjs +1 -1
- package/dist/modules/core/colors.js +1 -1
- package/dist/modules/core/consts.cjs +3 -9
- package/dist/modules/core/consts.d.ts +1 -5
- package/dist/modules/core/consts.js +4 -8
- package/dist/modules/core/globals.cjs +16 -5
- package/dist/modules/core/globals.d.ts +22 -1
- package/dist/modules/core/globals.js +18 -6
- package/dist/modules/core/helpers.cjs +7 -10
- package/dist/modules/core/helpers.js +8 -11
- package/dist/modules/core/render.cjs +66 -63
- package/dist/modules/core/render.js +68 -65
- package/dist/modules/core/styles.cjs +53 -32
- package/dist/modules/core/styles.d.ts +1 -0
- package/dist/modules/core/styles.js +55 -35
- package/dist/modules/core/targets.cjs +1 -1
- package/dist/modules/core/targets.js +1 -1
- package/dist/modules/core/transforms.cjs +129 -13
- package/dist/modules/core/transforms.d.ts +1 -0
- package/dist/modules/core/transforms.js +130 -15
- package/dist/modules/core/units.cjs +1 -1
- package/dist/modules/core/units.js +1 -1
- package/dist/modules/core/values.cjs +68 -8
- package/dist/modules/core/values.d.ts +5 -2
- package/dist/modules/core/values.js +69 -11
- package/dist/modules/draggable/draggable.cjs +1 -1
- package/dist/modules/draggable/draggable.js +1 -1
- package/dist/modules/draggable/index.cjs +1 -1
- package/dist/modules/draggable/index.js +1 -1
- package/dist/modules/easings/cubic-bezier/index.cjs +1 -1
- package/dist/modules/easings/cubic-bezier/index.js +1 -1
- package/dist/modules/easings/eases/index.cjs +1 -1
- package/dist/modules/easings/eases/index.js +1 -1
- package/dist/modules/easings/eases/parser.cjs +1 -1
- package/dist/modules/easings/eases/parser.js +1 -1
- package/dist/modules/easings/index.cjs +1 -1
- package/dist/modules/easings/index.js +1 -1
- package/dist/modules/easings/irregular/index.cjs +1 -1
- package/dist/modules/easings/irregular/index.js +1 -1
- package/dist/modules/easings/linear/index.cjs +1 -1
- package/dist/modules/easings/linear/index.js +1 -1
- package/dist/modules/easings/none.cjs +1 -1
- package/dist/modules/easings/none.js +1 -1
- package/dist/modules/easings/spring/index.cjs +1 -1
- package/dist/modules/easings/spring/index.js +1 -1
- package/dist/modules/easings/steps/index.cjs +1 -1
- package/dist/modules/easings/steps/index.js +1 -1
- package/dist/modules/engine/engine.cjs +1 -1
- package/dist/modules/engine/engine.js +1 -1
- package/dist/modules/engine/index.cjs +1 -1
- package/dist/modules/engine/index.js +1 -1
- package/dist/modules/events/index.cjs +1 -1
- package/dist/modules/events/index.js +1 -1
- package/dist/modules/events/scroll.cjs +1 -1
- package/dist/modules/events/scroll.js +1 -1
- package/dist/modules/index.cjs +9 -1
- package/dist/modules/index.d.ts +1 -0
- package/dist/modules/index.js +4 -1
- package/dist/modules/layout/index.cjs +1 -1
- package/dist/modules/layout/index.js +1 -1
- package/dist/modules/layout/layout.cjs +47 -24
- package/dist/modules/layout/layout.d.ts +4 -3
- package/dist/modules/layout/layout.js +48 -25
- package/dist/modules/scope/index.cjs +1 -1
- package/dist/modules/scope/index.js +1 -1
- package/dist/modules/scope/scope.cjs +1 -1
- package/dist/modules/scope/scope.js +1 -1
- package/dist/modules/svg/drawable.cjs +1 -1
- package/dist/modules/svg/drawable.js +1 -1
- package/dist/modules/svg/helpers.cjs +1 -1
- package/dist/modules/svg/helpers.js +1 -1
- package/dist/modules/svg/index.cjs +1 -1
- package/dist/modules/svg/index.js +1 -1
- package/dist/modules/svg/morphto.cjs +3 -6
- package/dist/modules/svg/morphto.js +3 -6
- package/dist/modules/svg/motionpath.cjs +1 -1
- package/dist/modules/svg/motionpath.js +1 -1
- package/dist/modules/text/index.cjs +3 -1
- package/dist/modules/text/index.d.ts +1 -0
- package/dist/modules/text/index.js +2 -1
- package/dist/modules/text/scramble.cjs +272 -0
- package/dist/modules/text/scramble.d.ts +3 -0
- package/dist/modules/text/scramble.js +270 -0
- package/dist/modules/text/split.cjs +5 -5
- package/dist/modules/text/split.d.ts +5 -5
- package/dist/modules/text/split.js +5 -5
- package/dist/modules/timeline/index.cjs +1 -1
- package/dist/modules/timeline/index.js +1 -1
- package/dist/modules/timeline/position.cjs +1 -1
- package/dist/modules/timeline/position.js +1 -1
- package/dist/modules/timeline/timeline.cjs +36 -18
- package/dist/modules/timeline/timeline.d.ts +6 -5
- package/dist/modules/timeline/timeline.js +37 -19
- package/dist/modules/timer/index.cjs +1 -1
- package/dist/modules/timer/index.js +1 -1
- package/dist/modules/timer/timer.cjs +8 -12
- package/dist/modules/timer/timer.d.ts +2 -0
- package/dist/modules/timer/timer.js +9 -13
- package/dist/modules/types/index.d.ts +76 -8
- package/dist/modules/utils/chainable.cjs +8 -5
- package/dist/modules/utils/chainable.js +8 -5
- package/dist/modules/utils/index.cjs +5 -1
- package/dist/modules/utils/index.d.ts +1 -0
- package/dist/modules/utils/index.js +2 -1
- package/dist/modules/utils/number.cjs +1 -1
- package/dist/modules/utils/number.js +1 -1
- package/dist/modules/utils/random.cjs +1 -1
- package/dist/modules/utils/random.js +1 -1
- package/dist/modules/utils/stagger.cjs +117 -20
- package/dist/modules/utils/stagger.js +118 -21
- package/dist/modules/utils/target.cjs +1 -1
- package/dist/modules/utils/target.js +1 -1
- package/dist/modules/utils/time.cjs +5 -3
- package/dist/modules/utils/time.d.ts +1 -1
- package/dist/modules/utils/time.js +5 -3
- package/dist/modules/waapi/composition.cjs +1 -1
- package/dist/modules/waapi/composition.js +1 -1
- package/dist/modules/waapi/index.cjs +1 -1
- package/dist/modules/waapi/index.js +1 -1
- package/dist/modules/waapi/waapi.cjs +19 -20
- package/dist/modules/waapi/waapi.js +20 -21
- package/package.json +2 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Anime.js - ESM bundle
|
|
3
|
-
* @version v4.
|
|
3
|
+
* @version v4.4.0
|
|
4
4
|
* @license MIT
|
|
5
5
|
* @copyright 2026 - Julian Garnier
|
|
6
6
|
*/
|
|
@@ -46,7 +46,8 @@
|
|
|
46
46
|
* @callback StaggerFunction
|
|
47
47
|
* @param {Target} [target]
|
|
48
48
|
* @param {Number} [index]
|
|
49
|
-
* @param {
|
|
49
|
+
* @param {TargetsArray} [targets]
|
|
50
|
+
* @param {Tween|null} [prevTween]
|
|
50
51
|
* @param {Timeline} [tl]
|
|
51
52
|
* @return {T}
|
|
52
53
|
*/
|
|
@@ -54,9 +55,9 @@
|
|
|
54
55
|
/**
|
|
55
56
|
* @typedef {Object} StaggerParams
|
|
56
57
|
* @property {Number|String} [start]
|
|
57
|
-
* @property {Number|'first'|'center'|'last'|'random'} [from]
|
|
58
|
+
* @property {Number|'first'|'center'|'last'|'random'|Array.<Number>} [from]
|
|
58
59
|
* @property {Boolean} [reversed]
|
|
59
|
-
* @property {Array.<Number
|
|
60
|
+
* @property {Array.<Number>|Boolean} [grid]
|
|
60
61
|
* @property {('x'|'y')} [axis]
|
|
61
62
|
* @property {String|((target: Target, i: Number, length: Number) => Number)} [use]
|
|
62
63
|
* @property {Number} [total]
|
|
@@ -117,8 +118,8 @@
|
|
|
117
118
|
|
|
118
119
|
// A hack to get both ease names suggestions AND allow any strings
|
|
119
120
|
// https://github.com/microsoft/TypeScript/issues/29729#issuecomment-460346421
|
|
120
|
-
/** @typedef {(String & {})|EaseStringParamNames|EasingFunction|Spring} EasingParam */
|
|
121
|
-
/** @typedef {(String & {})|EaseStringParamNames|WAAPIEaseStringParamNames|EasingFunction|Spring} WAAPIEasingParam */
|
|
121
|
+
/** @typedef {(String & {})|EaseStringParamNames|EasingFunction|Spring|TweakRegister} EasingParam */
|
|
122
|
+
/** @typedef {(String & {})|EaseStringParamNames|WAAPIEaseStringParamNames|EasingFunction|Spring|TweakRegister} WAAPIEasingParam */
|
|
122
123
|
|
|
123
124
|
// Spring types
|
|
124
125
|
|
|
@@ -174,6 +175,7 @@
|
|
|
174
175
|
* @property {Boolean|ScrollObserver} [autoplay]
|
|
175
176
|
* @property {Number} [frameRate]
|
|
176
177
|
* @property {Number} [playbackRate]
|
|
178
|
+
* @property {Number} [priority]
|
|
177
179
|
*/
|
|
178
180
|
|
|
179
181
|
/**
|
|
@@ -184,9 +186,10 @@
|
|
|
184
186
|
|
|
185
187
|
/**
|
|
186
188
|
* @callback FunctionValue
|
|
187
|
-
* @param {Target} target - The animated target
|
|
188
|
-
* @param {Number} index - The target index
|
|
189
|
-
* @param {
|
|
189
|
+
* @param {Target} [target] - The animated target
|
|
190
|
+
* @param {Number} [index] - The target index
|
|
191
|
+
* @param {TargetsArray} [targets] - The array of all animated targets
|
|
192
|
+
* @param {Tween|null} [prevTween] - The previous sibling tween for the same target and property
|
|
190
193
|
* @return {Number|String|TweenObjectValue|EasingParam|Array.<Number|String|TweenObjectValue>}
|
|
191
194
|
*/
|
|
192
195
|
|
|
@@ -355,7 +358,7 @@
|
|
|
355
358
|
* - `'label'` - Label: Position animation at a named label position (e.g., `'My Label'`)<br>
|
|
356
359
|
* - `stagger(String|Nummber)` - Stagger multi-elements animation positions (e.g., 10, 20, 30...)
|
|
357
360
|
*
|
|
358
|
-
* @typedef {TimelinePosition | StaggerFunction<Number|String>} TimelineAnimationPosition
|
|
361
|
+
* @typedef {TimelinePosition | StaggerFunction<Number|String> | TweakRegister} TimelineAnimationPosition
|
|
359
362
|
*/
|
|
360
363
|
|
|
361
364
|
/**
|
|
@@ -379,7 +382,7 @@
|
|
|
379
382
|
* @callback WAAPIFunctionValue
|
|
380
383
|
* @param {DOMTarget} target - The animated target
|
|
381
384
|
* @param {Number} index - The target index
|
|
382
|
-
* @param {
|
|
385
|
+
* @param {DOMTargetsArray} targets - The array of all animated targets
|
|
383
386
|
* @return {WAAPITweenValue|WAAPIEasingParam}
|
|
384
387
|
*/
|
|
385
388
|
|
|
@@ -626,6 +629,26 @@
|
|
|
626
629
|
* @property {Boolean} [debug]
|
|
627
630
|
*/
|
|
628
631
|
|
|
632
|
+
/**
|
|
633
|
+
* @typedef {Object} ScrambleTextParams
|
|
634
|
+
* @property {String|function(Target, Number, TargetsArray): String} [text] - the text to transition to, otherwise uses the original text
|
|
635
|
+
* @property {String|function(Target, Number, TargetsArray): String} [chars] - the characters used for scramble; named sets: 'lowercase', 'uppercase', 'numbers', 'symbols', 'braille', 'blocks', 'shades'; range syntax: 'A-Z', 'a-z0-9'; defaults to 'a-zA-Z0-9!%#_'
|
|
636
|
+
* @property {EasingParam} [ease] - the easing applied to the scramble animation
|
|
637
|
+
* @property {Number|'left'|'center'|'right'|'random'|'auto'} [from] - where the reveal wave starts from, 'auto' (default) uses 'left' when text grows and 'right' when it shrinks
|
|
638
|
+
* @property {Boolean} [reversed] - reverses the reveal order, so 'center' reveals from edges inward instead of center outward
|
|
639
|
+
* @property {Boolean|Number|String} [cursor] - characters displayed at the leading edge of the reveal wave; true uses '_', a number is a char code, a string is used directly
|
|
640
|
+
* @property {Number} [perturbation] - adds random timing offsets to each character's start and end, creating a more organic reveal
|
|
641
|
+
* @property {Number} [seed] - a seed for the random number generator to produce reproducible scramble sequences
|
|
642
|
+
* @property {Boolean|String} [override] - controls the starting appearance: false shows original text, true scrambles it (default), '' starts from blank, ' ' replaces characters with spaces, a custom string (supports range syntax like 'A-Z') uses its characters as scramble set
|
|
643
|
+
* @property {Number} [revealRate] - characters per second entering the active zone; higher values make the reveal wave move faster (default: 60)
|
|
644
|
+
* @property {Number} [settleDuration] - time in ms each character spends scrambling before settling into its final glyph (default: 300)
|
|
645
|
+
* @property {Number} [settleRate] - how many times per second scramble characters cycle in the active zone (default: 30)
|
|
646
|
+
* @property {Number|function(Target, Number, TargetsArray): Number} [duration] - if set to a value greater than 0, overrides the computed duration from interval and settle; if unset or 0, duration is calculated automatically from text length and timing parameters
|
|
647
|
+
* @property {Number|function(Target, Number, TargetsArray): Number} [revealDelay] - delay in ms before the reveal wave starts within the scramble animation
|
|
648
|
+
* @property {Number|function(Target, Number, TargetsArray): Number} [delay] - delay in ms before the entire scramble animation starts
|
|
649
|
+
* @property {function(String, Number): void} [onChange] - callback fired each time a character changes during scramble; receives the current scrambled text and the eased progress (0-1)
|
|
650
|
+
*/
|
|
651
|
+
|
|
629
652
|
// SVG types
|
|
630
653
|
|
|
631
654
|
/**
|
|
@@ -641,7 +664,7 @@
|
|
|
641
664
|
// TODO: Do we need to check if we're running inside a worker ?
|
|
642
665
|
const isBrowser = typeof window !== 'undefined';
|
|
643
666
|
|
|
644
|
-
/** @typedef {Window & {AnimeJS: Array}
|
|
667
|
+
/** @typedef {Window & {AnimeJS: Array}|null} AnimeJSWindow
|
|
645
668
|
|
|
646
669
|
/** @type {AnimeJSWindow} */
|
|
647
670
|
const win = isBrowser ? /** @type {AnimeJSWindow} */(/** @type {unknown} */(window)) : null;
|
|
@@ -688,7 +711,6 @@ const isRegisteredTargetSymbol = Symbol();
|
|
|
688
711
|
const isDomSymbol = Symbol();
|
|
689
712
|
const isSvgSymbol = Symbol();
|
|
690
713
|
const transformsSymbol = Symbol();
|
|
691
|
-
const morphPointsSymbol = Symbol();
|
|
692
714
|
const proxyTargetSymbol = Symbol();
|
|
693
715
|
|
|
694
716
|
// Numbers
|
|
@@ -712,6 +734,7 @@ const shortTransforms = /*#__PURE__*/ (() => {
|
|
|
712
734
|
})();
|
|
713
735
|
|
|
714
736
|
const validTransforms = [
|
|
737
|
+
'perspective',
|
|
715
738
|
'translateX',
|
|
716
739
|
'translateY',
|
|
717
740
|
'translateZ',
|
|
@@ -726,9 +749,6 @@ const validTransforms = [
|
|
|
726
749
|
'skew',
|
|
727
750
|
'skewX',
|
|
728
751
|
'skewY',
|
|
729
|
-
'matrix',
|
|
730
|
-
'matrix3d',
|
|
731
|
-
'perspective',
|
|
732
752
|
];
|
|
733
753
|
|
|
734
754
|
const transformsFragmentStrings = /*#__PURE__*/ validTransforms.reduce((a, v) => ({...a, [v]: v + '('}), {});
|
|
@@ -751,12 +771,23 @@ const digitWithExponentRgx = /[-+]?\d*\.?\d+(?:e[-+]?\d)?/gi;
|
|
|
751
771
|
// export const unitsExecRgx = /^([-+]?\d*\.?\d+(?:[eE][-+]?\d+)?)+([a-z]+|%)$/i;
|
|
752
772
|
const unitsExecRgx = /^([-+]?\d*\.?\d+(?:e[-+]?\d+)?)([a-z]+|%)$/i;
|
|
753
773
|
const lowerCaseRgx = /([a-z])([A-Z])/g;
|
|
754
|
-
const transformsExecRgx = /(\w+)(\([^)]+\)+)/g; // Match inline transforms with cacl() values, returns the value wrapped in ()
|
|
755
774
|
const relativeValuesExecRgx = /(\*=|\+=|-=)/;
|
|
756
775
|
const cssVariableMatchRgx = /var\(\s*(--[\w-]+)(?:\s*,\s*([^)]+))?\s*\)/;
|
|
757
776
|
|
|
758
777
|
|
|
759
778
|
|
|
779
|
+
/**
|
|
780
|
+
* @typedef {Object} EditorGlobals
|
|
781
|
+
* @property {boolean} showPanel
|
|
782
|
+
* @property {boolean} synced
|
|
783
|
+
* @property {Function} addAnimation
|
|
784
|
+
* @property {Function} addTimeline
|
|
785
|
+
* @property {Function} addTimelineChild
|
|
786
|
+
* @property {Function} resolveStagger
|
|
787
|
+
* @property {Object|null} _head
|
|
788
|
+
* @property {Object|null} _tail
|
|
789
|
+
*/
|
|
790
|
+
|
|
760
791
|
/** @type {DefaultsParams} */
|
|
761
792
|
const defaults = {
|
|
762
793
|
id: null,
|
|
@@ -800,11 +831,11 @@ const globals = {
|
|
|
800
831
|
timeScale: 1,
|
|
801
832
|
/** @type {Number} */
|
|
802
833
|
tickThreshold: 200,
|
|
834
|
+
/** @type {EditorGlobals|null} */
|
|
835
|
+
editor: null,
|
|
803
836
|
};
|
|
804
837
|
|
|
805
|
-
const
|
|
806
|
-
|
|
807
|
-
const globalVersions = { version: '4.3.5', engine: null };
|
|
838
|
+
const globalVersions = { version: '4.4.0', engine: null };
|
|
808
839
|
|
|
809
840
|
if (isBrowser) {
|
|
810
841
|
if (!win.AnimeJS) win.AnimeJS = [];
|
|
@@ -920,8 +951,6 @@ const _round = Math.round;
|
|
|
920
951
|
*/
|
|
921
952
|
const clamp$1 = (v, min, max) => v < min ? min : v > max ? max : v;
|
|
922
953
|
|
|
923
|
-
const powCache = {};
|
|
924
|
-
|
|
925
954
|
/**
|
|
926
955
|
* Rounds a number to specified decimal places
|
|
927
956
|
*
|
|
@@ -929,13 +958,12 @@ const powCache = {};
|
|
|
929
958
|
* @param {Number} decimalLength - Number of decimal places
|
|
930
959
|
* @return {Number}
|
|
931
960
|
*/
|
|
932
|
-
const round$1 = (v, decimalLength) => {
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
};
|
|
961
|
+
const round$1 = (v, decimalLength) => {
|
|
962
|
+
if (decimalLength < 0) return v;
|
|
963
|
+
if (!decimalLength) return _round(v);
|
|
964
|
+
const p = 10 ** decimalLength;
|
|
965
|
+
return _round(v * p) / p;
|
|
966
|
+
};
|
|
939
967
|
|
|
940
968
|
/**
|
|
941
969
|
* Snaps a value to nearest increment or array value
|
|
@@ -1066,28 +1094,143 @@ const addChild = (parent, child, sortMethod, prevProp = '_prev', nextProp = '_ne
|
|
|
1066
1094
|
*/
|
|
1067
1095
|
const parseInlineTransforms = (target, propName, animationInlineStyles) => {
|
|
1068
1096
|
const inlineTransforms = target.style.transform;
|
|
1069
|
-
let inlinedStylesPropertyValue;
|
|
1070
1097
|
if (inlineTransforms) {
|
|
1071
1098
|
const cachedTransforms = target[transformsSymbol];
|
|
1072
|
-
let
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1099
|
+
let pos = 0;
|
|
1100
|
+
const len = inlineTransforms.length;
|
|
1101
|
+
let fullTranslateValue;
|
|
1102
|
+
while (pos < len) {
|
|
1103
|
+
// Skip whitespace
|
|
1104
|
+
while (pos < len && inlineTransforms.charCodeAt(pos) === 32) pos++;
|
|
1105
|
+
if (pos >= len) break;
|
|
1106
|
+
// Read function name
|
|
1107
|
+
const nameStart = pos;
|
|
1108
|
+
while (pos < len && inlineTransforms.charCodeAt(pos) !== 40) pos++;
|
|
1109
|
+
if (pos >= len) break;
|
|
1110
|
+
const name = inlineTransforms.substring(nameStart, pos);
|
|
1111
|
+
// Scan to closing paren, recording top-level comma positions
|
|
1112
|
+
let depth = 1;
|
|
1113
|
+
const valueStart = pos + 1;
|
|
1114
|
+
let c1 = -1, c2 = -1;
|
|
1115
|
+
pos++;
|
|
1116
|
+
while (pos < len && depth > 0) {
|
|
1117
|
+
const c = inlineTransforms.charCodeAt(pos);
|
|
1118
|
+
if (c === 40) depth++;
|
|
1119
|
+
else if (c === 41) depth--;
|
|
1120
|
+
else if (c === 44 && depth === 1) {
|
|
1121
|
+
if (c1 === -1) c1 = pos;
|
|
1122
|
+
else if (c2 === -1) c2 = pos;
|
|
1082
1123
|
}
|
|
1124
|
+
pos++;
|
|
1083
1125
|
}
|
|
1126
|
+
const valueEnd = pos - 1;
|
|
1127
|
+
// Decompose multi-arg functions into individual axis properties
|
|
1128
|
+
if (name === 'translate' || name === 'translate3d') {
|
|
1129
|
+
if (c1 === -1) {
|
|
1130
|
+
cachedTransforms.translateX = inlineTransforms.substring(valueStart, valueEnd).trim();
|
|
1131
|
+
} else {
|
|
1132
|
+
cachedTransforms.translateX = inlineTransforms.substring(valueStart, c1).trim();
|
|
1133
|
+
if (c2 === -1) {
|
|
1134
|
+
cachedTransforms.translateY = inlineTransforms.substring(c1 + 1, valueEnd).trim();
|
|
1135
|
+
} else {
|
|
1136
|
+
cachedTransforms.translateY = inlineTransforms.substring(c1 + 1, c2).trim();
|
|
1137
|
+
cachedTransforms.translateZ = inlineTransforms.substring(c2 + 1, valueEnd).trim();
|
|
1138
|
+
}
|
|
1139
|
+
}
|
|
1140
|
+
fullTranslateValue = inlineTransforms.substring(valueStart, valueEnd);
|
|
1141
|
+
} else if (name === 'scale' || name === 'scale3d') {
|
|
1142
|
+
if (c1 === -1) {
|
|
1143
|
+
cachedTransforms.scale = inlineTransforms.substring(valueStart, valueEnd).trim();
|
|
1144
|
+
} else {
|
|
1145
|
+
cachedTransforms.scaleX = inlineTransforms.substring(valueStart, c1).trim();
|
|
1146
|
+
if (c2 === -1) {
|
|
1147
|
+
cachedTransforms.scaleY = inlineTransforms.substring(c1 + 1, valueEnd).trim();
|
|
1148
|
+
} else {
|
|
1149
|
+
cachedTransforms.scaleY = inlineTransforms.substring(c1 + 1, c2).trim();
|
|
1150
|
+
cachedTransforms.scaleZ = inlineTransforms.substring(c2 + 1, valueEnd).trim();
|
|
1151
|
+
}
|
|
1152
|
+
}
|
|
1153
|
+
} else {
|
|
1154
|
+
cachedTransforms[name] = inlineTransforms.substring(valueStart, valueEnd);
|
|
1155
|
+
}
|
|
1156
|
+
}
|
|
1157
|
+
// Resolve the requested property from the cache
|
|
1158
|
+
if (propName === 'translate3d' && fullTranslateValue) {
|
|
1159
|
+
if (animationInlineStyles) animationInlineStyles[propName] = fullTranslateValue;
|
|
1160
|
+
return fullTranslateValue;
|
|
1161
|
+
}
|
|
1162
|
+
const cached = cachedTransforms[propName];
|
|
1163
|
+
if (!isUnd(cached)) {
|
|
1164
|
+
if (animationInlineStyles) animationInlineStyles[propName] = cached;
|
|
1165
|
+
return cached;
|
|
1084
1166
|
}
|
|
1085
1167
|
}
|
|
1086
|
-
return
|
|
1168
|
+
return propName === 'translate3d' ? '0px, 0px, 0px' :
|
|
1169
|
+
propName === 'rotate3d' ? '0, 0, 0, 0deg' :
|
|
1087
1170
|
stringStartsWith(propName, 'scale') ? '1' :
|
|
1088
1171
|
stringStartsWith(propName, 'rotate') || stringStartsWith(propName, 'skew') ? '0deg' : '0px';
|
|
1089
1172
|
};
|
|
1090
1173
|
|
|
1174
|
+
/**
|
|
1175
|
+
* Builds a CSS transform string from the target's cached transform properties.
|
|
1176
|
+
* Iterates validTransforms in order (perspective > translate > rotate > scale > skew > matrix).
|
|
1177
|
+
* When adjacent axis properties are all present, emits a shorter shorthand (translateX + translateY -> translate(x, y))
|
|
1178
|
+
* The index is advanced past consumed properties so they are not emitted twice.
|
|
1179
|
+
* Properties without a grouping partner (e.g. translateY alone, scaleZ alone) emit individually.
|
|
1180
|
+
*
|
|
1181
|
+
* @param {Record<String, String>} props
|
|
1182
|
+
* @return {String}
|
|
1183
|
+
*/
|
|
1184
|
+
const buildTransformString = (props) => {
|
|
1185
|
+
let str = emptyString;
|
|
1186
|
+
for (let i = 0, l = validTransforms.length; i < l; i++) {
|
|
1187
|
+
const key = validTransforms[i];
|
|
1188
|
+
const val = props[key];
|
|
1189
|
+
if (val !== undefined) {
|
|
1190
|
+
// Group translateX with adjacent translateY / translateZ
|
|
1191
|
+
if (key === 'translateX') {
|
|
1192
|
+
const next = props.translateY;
|
|
1193
|
+
if (next !== undefined) {
|
|
1194
|
+
const next2 = props.translateZ;
|
|
1195
|
+
if (next2 !== undefined) {
|
|
1196
|
+
str += `translate3d(${val},${next},${next2}) `;
|
|
1197
|
+
i += 2;
|
|
1198
|
+
} else {
|
|
1199
|
+
str += `translate(${val},${next}) `;
|
|
1200
|
+
i += 1;
|
|
1201
|
+
}
|
|
1202
|
+
continue;
|
|
1203
|
+
}
|
|
1204
|
+
}
|
|
1205
|
+
// Group scaleX with adjacent scaleY / scaleZ (only when standalone scale is absent)
|
|
1206
|
+
if (key === 'scaleX' && props.scale === undefined) {
|
|
1207
|
+
const next = props.scaleY;
|
|
1208
|
+
if (next !== undefined) {
|
|
1209
|
+
const next2 = props.scaleZ;
|
|
1210
|
+
if (next2 !== undefined) {
|
|
1211
|
+
str += `scale3d(${val},${next},${next2}) `;
|
|
1212
|
+
i += 2;
|
|
1213
|
+
} else {
|
|
1214
|
+
str += `scale(${val},${next}) `;
|
|
1215
|
+
i += 1;
|
|
1216
|
+
}
|
|
1217
|
+
continue;
|
|
1218
|
+
}
|
|
1219
|
+
}
|
|
1220
|
+
// All other properties: emit individually using pre-built fragment string
|
|
1221
|
+
str += `${transformsFragmentStrings[key]}${val}) `;
|
|
1222
|
+
}
|
|
1223
|
+
// Preserve non-animatable rotate3d in correct position (after rotateZ, before scale)
|
|
1224
|
+
if (key === 'rotateZ') {
|
|
1225
|
+
if (props.rotate3d !== undefined) str += `rotate3d(${props.rotate3d}) `;
|
|
1226
|
+
}
|
|
1227
|
+
}
|
|
1228
|
+
// Preserve non-animatable matrix/matrix3d from inline styles
|
|
1229
|
+
if (props.matrix !== undefined) str += `matrix(${props.matrix}) `;
|
|
1230
|
+
if (props.matrix3d !== undefined) str += `matrix3d(${props.matrix3d}) `;
|
|
1231
|
+
return str;
|
|
1232
|
+
};
|
|
1233
|
+
|
|
1091
1234
|
|
|
1092
1235
|
|
|
1093
1236
|
/**
|
|
@@ -1189,15 +1332,16 @@ const setValue = (targetValue, defaultValue) => {
|
|
|
1189
1332
|
* @param {TweenPropValue} value
|
|
1190
1333
|
* @param {Target} target
|
|
1191
1334
|
* @param {Number} index
|
|
1192
|
-
* @param {
|
|
1193
|
-
* @param {Object}
|
|
1335
|
+
* @param {TargetsArray} targets
|
|
1336
|
+
* @param {Object|null} store
|
|
1337
|
+
* @param {Tween|null} prevTween
|
|
1194
1338
|
* @return {any}
|
|
1195
1339
|
*/
|
|
1196
|
-
const getFunctionValue = (value, target, index,
|
|
1340
|
+
const getFunctionValue = (value, target, index, targets, store, prevTween) => {
|
|
1197
1341
|
let func;
|
|
1198
1342
|
if (isFnc(value)) {
|
|
1199
1343
|
func = () => {
|
|
1200
|
-
const computed = /** @type {Function} */(value)(target, index,
|
|
1344
|
+
const computed = /** @type {Function} */(value)(target, index, targets, prevTween);
|
|
1201
1345
|
// Fallback to 0 if the function returns undefined / NaN / null / false / 0
|
|
1202
1346
|
return !isNaN(+computed) ? +computed : computed || 0;
|
|
1203
1347
|
};
|
|
@@ -1264,9 +1408,17 @@ const getCSSValue = (target, propName, animationInlineStyles) => {
|
|
|
1264
1408
|
*/
|
|
1265
1409
|
const getOriginalAnimatableValue = (target, propName, tweenType, animationInlineStyles) => {
|
|
1266
1410
|
const type = !isUnd(tweenType) ? tweenType : getTweenType(target, propName);
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1411
|
+
if (type === tweenTypes.OBJECT) {
|
|
1412
|
+
const value = target[propName];
|
|
1413
|
+
if (value && animationInlineStyles) animationInlineStyles[propName] = value;
|
|
1414
|
+
return value || 0;
|
|
1415
|
+
}
|
|
1416
|
+
if (type === tweenTypes.ATTRIBUTE) {
|
|
1417
|
+
const value = /** @type {DOMTarget} */(target).getAttribute(propName);
|
|
1418
|
+
if (value && animationInlineStyles) animationInlineStyles[propName] = value;
|
|
1419
|
+
return value;
|
|
1420
|
+
}
|
|
1421
|
+
return type === tweenTypes.TRANSFORM ? parseInlineTransforms(/** @type {DOMTarget} */(target), propName, animationInlineStyles) :
|
|
1270
1422
|
type === tweenTypes.CSS_VAR ? getCSSValue(/** @type {DOMTarget} */(target), propName, animationInlineStyles).trimStart() :
|
|
1271
1423
|
getCSSValue(/** @type {DOMTarget} */(target), propName, animationInlineStyles);
|
|
1272
1424
|
};
|
|
@@ -1368,6 +1520,54 @@ const decomposeTweenValue = (tween, targetObject) => {
|
|
|
1368
1520
|
|
|
1369
1521
|
const decomposedOriginalValue = createDecomposedValueTargetObject();
|
|
1370
1522
|
|
|
1523
|
+
/**
|
|
1524
|
+
* @param {Tween} tween
|
|
1525
|
+
* @param {Number} progress
|
|
1526
|
+
* @param {Number} precision
|
|
1527
|
+
* @return {String}
|
|
1528
|
+
*/
|
|
1529
|
+
const composeColorValue = (tween, progress, precision) => {
|
|
1530
|
+
const mod = tween._modifier;
|
|
1531
|
+
const fn = tween._fromNumbers;
|
|
1532
|
+
const tn = tween._toNumbers;
|
|
1533
|
+
const r = round$1(clamp$1(/** @type {Number} */(mod(lerp$1(fn[0], tn[0], progress))), 0, 255), 0);
|
|
1534
|
+
const g = round$1(clamp$1(/** @type {Number} */(mod(lerp$1(fn[1], tn[1], progress))), 0, 255), 0);
|
|
1535
|
+
const b = round$1(clamp$1(/** @type {Number} */(mod(lerp$1(fn[2], tn[2], progress))), 0, 255), 0);
|
|
1536
|
+
const a = clamp$1(/** @type {Number} */(mod(round$1(lerp$1(fn[3], tn[3], progress), precision))), 0, 1);
|
|
1537
|
+
if (tween._composition !== compositionTypes.none) {
|
|
1538
|
+
const ns = tween._numbers;
|
|
1539
|
+
ns[0] = r;
|
|
1540
|
+
ns[1] = g;
|
|
1541
|
+
ns[2] = b;
|
|
1542
|
+
ns[3] = a;
|
|
1543
|
+
}
|
|
1544
|
+
return `rgba(${r},${g},${b},${a})`;
|
|
1545
|
+
};
|
|
1546
|
+
|
|
1547
|
+
/**
|
|
1548
|
+
* @param {Tween} tween
|
|
1549
|
+
* @param {Number} progress
|
|
1550
|
+
* @param {Number} precision
|
|
1551
|
+
* @return {String}
|
|
1552
|
+
*/
|
|
1553
|
+
const composeComplexValue = (tween, progress, precision) => {
|
|
1554
|
+
const mod = tween._modifier;
|
|
1555
|
+
const fn = tween._fromNumbers;
|
|
1556
|
+
const tn = tween._toNumbers;
|
|
1557
|
+
const ts = tween._strings;
|
|
1558
|
+
const hasComposition = tween._composition !== compositionTypes.none;
|
|
1559
|
+
let v = ts[0];
|
|
1560
|
+
for (let j = 0, l = tn.length; j < l; j++) {
|
|
1561
|
+
const n = /** @type {Number} */(mod(round$1(lerp$1(fn[j], tn[j], progress), precision)));
|
|
1562
|
+
const s = ts[j + 1];
|
|
1563
|
+
v += `${s ? n + s : n}`;
|
|
1564
|
+
if (hasComposition) {
|
|
1565
|
+
tween._numbers[j] = n;
|
|
1566
|
+
}
|
|
1567
|
+
}
|
|
1568
|
+
return v;
|
|
1569
|
+
};
|
|
1570
|
+
|
|
1371
1571
|
|
|
1372
1572
|
|
|
1373
1573
|
|
|
@@ -1396,7 +1596,6 @@ const render = (tickable, time, muteCallbacks, internalRender, tickMode) => {
|
|
|
1396
1596
|
const _hasChildren = tickable._hasChildren;
|
|
1397
1597
|
const tickableDelay = tickable._delay;
|
|
1398
1598
|
const tickablePrevAbsoluteTime = tickable._currentTime; // TODO: rename ._currentTime to ._absoluteCurrentTime
|
|
1399
|
-
|
|
1400
1599
|
const tickableEndTime = tickableDelay + iterationDuration;
|
|
1401
1600
|
const tickableAbsoluteTime = time - tickableDelay;
|
|
1402
1601
|
const tickablePrevTime = clamp$1(tickablePrevAbsoluteTime, -tickableDelay, duration);
|
|
@@ -1528,30 +1727,9 @@ const render = (tickable, time, muteCallbacks, internalRender, tickMode) => {
|
|
|
1528
1727
|
number = /** @type {Number} */(tweenModifier(round$1(lerp$1(tween._fromNumber, tween._toNumber, tweenProgress), tweenPrecision)));
|
|
1529
1728
|
value = `${number}${tween._unit}`;
|
|
1530
1729
|
} else if (tweenValueType === valueTypes.COLOR) {
|
|
1531
|
-
|
|
1532
|
-
const tn = tween._toNumbers;
|
|
1533
|
-
const r = round$1(clamp$1(/** @type {Number} */(tweenModifier(lerp$1(fn[0], tn[0], tweenProgress))), 0, 255), 0);
|
|
1534
|
-
const g = round$1(clamp$1(/** @type {Number} */(tweenModifier(lerp$1(fn[1], tn[1], tweenProgress))), 0, 255), 0);
|
|
1535
|
-
const b = round$1(clamp$1(/** @type {Number} */(tweenModifier(lerp$1(fn[2], tn[2], tweenProgress))), 0, 255), 0);
|
|
1536
|
-
const a = clamp$1(/** @type {Number} */(tweenModifier(round$1(lerp$1(fn[3], tn[3], tweenProgress), tweenPrecision))), 0, 1);
|
|
1537
|
-
value = `rgba(${r},${g},${b},${a})`;
|
|
1538
|
-
if (tweenHasComposition) {
|
|
1539
|
-
const ns = tween._numbers;
|
|
1540
|
-
ns[0] = r;
|
|
1541
|
-
ns[1] = g;
|
|
1542
|
-
ns[2] = b;
|
|
1543
|
-
ns[3] = a;
|
|
1544
|
-
}
|
|
1730
|
+
value = composeColorValue(tween, tweenProgress, tweenPrecision);
|
|
1545
1731
|
} else if (tweenValueType === valueTypes.COMPLEX) {
|
|
1546
|
-
value = tween
|
|
1547
|
-
for (let j = 0, l = tween._toNumbers.length; j < l; j++) {
|
|
1548
|
-
const n = /** @type {Number} */(tweenModifier(round$1(lerp$1(tween._fromNumbers[j], tween._toNumbers[j], tweenProgress), tweenPrecision)));
|
|
1549
|
-
const s = tween._strings[j + 1];
|
|
1550
|
-
value += `${s ? n + s : n}`;
|
|
1551
|
-
if (tweenHasComposition) {
|
|
1552
|
-
tween._numbers[j] = n;
|
|
1553
|
-
}
|
|
1554
|
-
}
|
|
1732
|
+
value = composeComplexValue(tween, tweenProgress, tweenPrecision);
|
|
1555
1733
|
}
|
|
1556
1734
|
|
|
1557
1735
|
// For additive tweens and Animatables
|
|
@@ -1594,14 +1772,8 @@ const render = (tickable, time, muteCallbacks, internalRender, tickMode) => {
|
|
|
1594
1772
|
|
|
1595
1773
|
}
|
|
1596
1774
|
|
|
1597
|
-
// NOTE: Possible improvement: Use translate(x,y) / translate3d(x,y,z) syntax
|
|
1598
|
-
// to reduce memory usage on string composition
|
|
1599
1775
|
if (tweenTransformsNeedUpdate && tween._renderTransforms) {
|
|
1600
|
-
|
|
1601
|
-
for (let key in tweenTargetTransformsProperties) {
|
|
1602
|
-
str += `${transformsFragmentStrings[key]}${tweenTargetTransformsProperties[key]}) `;
|
|
1603
|
-
}
|
|
1604
|
-
tweenStyle.transform = str;
|
|
1776
|
+
tweenStyle.transform = buildTransformString(tweenTargetTransformsProperties);
|
|
1605
1777
|
tweenTransformsNeedUpdate = 0;
|
|
1606
1778
|
}
|
|
1607
1779
|
|
|
@@ -1658,6 +1830,50 @@ const render = (tickable, time, muteCallbacks, internalRender, tickMode) => {
|
|
|
1658
1830
|
return hasRendered;
|
|
1659
1831
|
};
|
|
1660
1832
|
|
|
1833
|
+
// Shared context for extracted forEachChildren callbacks in tick()
|
|
1834
|
+
// Avoids closure allocation every frame
|
|
1835
|
+
|
|
1836
|
+
let renderCtxChildrenTime = 0;
|
|
1837
|
+
let renderCtxTlFps = 0;
|
|
1838
|
+
let renderCtxTickTime = 0;
|
|
1839
|
+
let renderCtxTickMode = 0;
|
|
1840
|
+
let renderCtxMuteCallbacks = 0;
|
|
1841
|
+
let renderCtxInternalRender = 0;
|
|
1842
|
+
let renderCtxChildrenHasRendered = 0;
|
|
1843
|
+
let renderCtxChildrenHaveCompleted = true;
|
|
1844
|
+
let loopCtxIsRunningBackwards = false;
|
|
1845
|
+
let loopCtxIterationDuration = 0;
|
|
1846
|
+
let loopCtxMuteCallbacks = 0;
|
|
1847
|
+
|
|
1848
|
+
/** @param {JSAnimation} child */
|
|
1849
|
+
const tickLoopChild = (child) => {
|
|
1850
|
+
if (!loopCtxIsRunningBackwards) {
|
|
1851
|
+
// Force an internal render to trigger the callbacks if the child has not completed on loop
|
|
1852
|
+
if (!child.completed && !child.backwards && child._currentTime < child.iterationDuration) {
|
|
1853
|
+
render(child, loopCtxIterationDuration, loopCtxMuteCallbacks, 1, tickModes.FORCE);
|
|
1854
|
+
}
|
|
1855
|
+
// Reset their began and completed flags to allow retrigering callbacks on the next iteration
|
|
1856
|
+
child.began = false;
|
|
1857
|
+
child.completed = false;
|
|
1858
|
+
} else {
|
|
1859
|
+
const childDuration = child.duration;
|
|
1860
|
+
const childStartTime = child._offset + child._delay;
|
|
1861
|
+
const childEndTime = childStartTime + childDuration;
|
|
1862
|
+
// Triggers the onComplete callback on reverse for children on the edges of the timeline
|
|
1863
|
+
if (!loopCtxMuteCallbacks && childDuration <= minValue && (!childStartTime || childEndTime === loopCtxIterationDuration)) {
|
|
1864
|
+
child.onComplete(child);
|
|
1865
|
+
}
|
|
1866
|
+
}
|
|
1867
|
+
};
|
|
1868
|
+
|
|
1869
|
+
/** @param {JSAnimation} child */
|
|
1870
|
+
const tickRenderChild = (child) => {
|
|
1871
|
+
const childTime = round$1((renderCtxChildrenTime - child._offset) * child._speed, 12); // Rounding is needed when using seconds
|
|
1872
|
+
const childTickMode = child._fps < renderCtxTlFps ? child.requestTick(renderCtxTickTime) : renderCtxTickMode;
|
|
1873
|
+
renderCtxChildrenHasRendered += render(child, childTime, renderCtxMuteCallbacks, renderCtxInternalRender, childTickMode);
|
|
1874
|
+
if (!child.completed && renderCtxChildrenHaveCompleted) renderCtxChildrenHaveCompleted = false;
|
|
1875
|
+
};
|
|
1876
|
+
|
|
1661
1877
|
/**
|
|
1662
1878
|
* @param {Tickable} tickable
|
|
1663
1879
|
* @param {Number} time
|
|
@@ -1674,45 +1890,30 @@ const tick = (tickable, time, muteCallbacks, internalRender, tickMode) => {
|
|
|
1674
1890
|
const tlIsRunningBackwards = tl.backwards;
|
|
1675
1891
|
const tlChildrenTime = internalRender ? time : tl._iterationTime;
|
|
1676
1892
|
const tlCildrenTickTime = now();
|
|
1677
|
-
|
|
1678
1893
|
let tlChildrenHasRendered = 0;
|
|
1679
1894
|
let tlChildrenHaveCompleted = true;
|
|
1680
|
-
|
|
1681
1895
|
// If the timeline has looped forward, we need to manually triggers children skipped callbacks
|
|
1682
1896
|
if (!internalRender && tl._currentIteration !== _currentIteration) {
|
|
1683
1897
|
const tlIterationDuration = tl.iterationDuration;
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
render(child, tlIterationDuration, muteCallbacks, 1, tickModes.FORCE);
|
|
1689
|
-
}
|
|
1690
|
-
// Reset their began and completed flags to allow retrigering callbacks on the next iteration
|
|
1691
|
-
child.began = false;
|
|
1692
|
-
child.completed = false;
|
|
1693
|
-
} else {
|
|
1694
|
-
const childDuration = child.duration;
|
|
1695
|
-
const childStartTime = child._offset + child._delay;
|
|
1696
|
-
const childEndTime = childStartTime + childDuration;
|
|
1697
|
-
// Triggers the onComplete callback on reverse for children on the edges of the timeline
|
|
1698
|
-
if (!muteCallbacks && childDuration <= minValue && (!childStartTime || childEndTime === tlIterationDuration)) {
|
|
1699
|
-
child.onComplete(child);
|
|
1700
|
-
}
|
|
1701
|
-
}
|
|
1702
|
-
});
|
|
1898
|
+
loopCtxIsRunningBackwards = tlIsRunningBackwards;
|
|
1899
|
+
loopCtxIterationDuration = tlIterationDuration;
|
|
1900
|
+
loopCtxMuteCallbacks = muteCallbacks;
|
|
1901
|
+
forEachChildren(tl, tickLoopChild);
|
|
1703
1902
|
if (!muteCallbacks) tl.onLoop(/** @type {CallbackArgument} */(tl));
|
|
1704
1903
|
}
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1904
|
+
renderCtxChildrenTime = tlChildrenTime;
|
|
1905
|
+
renderCtxTlFps = tl._fps;
|
|
1906
|
+
renderCtxTickTime = tlCildrenTickTime;
|
|
1907
|
+
renderCtxTickMode = tickMode;
|
|
1908
|
+
renderCtxMuteCallbacks = muteCallbacks;
|
|
1909
|
+
renderCtxInternalRender = internalRender;
|
|
1910
|
+
renderCtxChildrenHasRendered = 0;
|
|
1911
|
+
renderCtxChildrenHaveCompleted = true;
|
|
1912
|
+
forEachChildren(tl, tickRenderChild, tlIsRunningBackwards);
|
|
1913
|
+
tlChildrenHasRendered = renderCtxChildrenHasRendered;
|
|
1914
|
+
tlChildrenHaveCompleted = renderCtxChildrenHaveCompleted;
|
|
1713
1915
|
// Renders on timeline are triggered by its children so it needs to be set after rendering the children
|
|
1714
1916
|
if (!muteCallbacks && tlChildrenHasRendered) tl.onRender(/** @type {CallbackArgument} */(tl));
|
|
1715
|
-
|
|
1716
1917
|
// Triggers the timeline onComplete() once all chindren all completed and the current time has reached the end
|
|
1717
1918
|
if ((tlChildrenHaveCompleted || tlIsRunningBackwards) && tl._currentTime >= tl.duration) {
|
|
1718
1919
|
// Make sure the paused flag is false in case it has been skipped in the render function
|
|
@@ -1766,59 +1967,78 @@ const sanitizePropertyName = (propertyName, target, tweenType) => {
|
|
|
1766
1967
|
/**
|
|
1767
1968
|
* @template {Renderable} T
|
|
1768
1969
|
* @param {T} renderable
|
|
1970
|
+
* @param {Boolean} [inlineStylesOnly]
|
|
1769
1971
|
* @return {T}
|
|
1770
1972
|
*/
|
|
1771
|
-
const
|
|
1772
|
-
// Allow
|
|
1973
|
+
const revertValues = (renderable, inlineStylesOnly = false) => {
|
|
1974
|
+
// Allow revertValues() to be called on timelines
|
|
1773
1975
|
if (renderable._hasChildren) {
|
|
1774
|
-
forEachChildren(renderable,
|
|
1976
|
+
forEachChildren(renderable, (/** @type {Renderable} */child) => revertValues(child, inlineStylesOnly), true);
|
|
1775
1977
|
} else {
|
|
1776
1978
|
const animation = /** @type {JSAnimation} */(renderable);
|
|
1777
1979
|
animation.pause();
|
|
1778
1980
|
forEachChildren(animation, (/** @type {Tween} */tween) => {
|
|
1779
1981
|
const tweenProperty = tween.property;
|
|
1780
1982
|
const tweenTarget = tween.target;
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
if (
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
if (!Object.keys(cachedTransforms).length) {
|
|
1794
|
-
targetStyle.removeProperty('transform');
|
|
1983
|
+
const tweenType = tween._tweenType;
|
|
1984
|
+
const originalInlinedValue = tween._inlineValue;
|
|
1985
|
+
const tweenHadNoInlineValue = isNil(originalInlinedValue) || originalInlinedValue === emptyString;
|
|
1986
|
+
if (tweenType === tweenTypes.OBJECT) {
|
|
1987
|
+
if (!inlineStylesOnly && !tweenHadNoInlineValue) {
|
|
1988
|
+
tweenTarget[tweenProperty] = originalInlinedValue;
|
|
1989
|
+
}
|
|
1990
|
+
} else if (tweenTarget[isDomSymbol]) {
|
|
1991
|
+
if (tweenType === tweenTypes.ATTRIBUTE) {
|
|
1992
|
+
if (!inlineStylesOnly) {
|
|
1993
|
+
if (tweenHadNoInlineValue) {
|
|
1994
|
+
/** @type {DOMTarget} */(tweenTarget).removeAttribute(tweenProperty);
|
|
1795
1995
|
} else {
|
|
1796
|
-
|
|
1797
|
-
for (let key in cachedTransforms) {
|
|
1798
|
-
str += transformsFragmentStrings[key] + cachedTransforms[key] + ') ';
|
|
1799
|
-
}
|
|
1800
|
-
targetStyle.transform = str;
|
|
1996
|
+
/** @type {DOMTarget} */(tweenTarget).setAttribute(tweenProperty, /** @type {String} */(originalInlinedValue));
|
|
1801
1997
|
}
|
|
1802
1998
|
}
|
|
1803
1999
|
} else {
|
|
1804
|
-
|
|
1805
|
-
|
|
2000
|
+
const targetStyle = /** @type {DOMTarget} */(tweenTarget).style;
|
|
2001
|
+
if (tweenType === tweenTypes.TRANSFORM) {
|
|
2002
|
+
const cachedTransforms = tweenTarget[transformsSymbol];
|
|
2003
|
+
if (tweenHadNoInlineValue) {
|
|
2004
|
+
delete cachedTransforms[tweenProperty];
|
|
2005
|
+
} else {
|
|
2006
|
+
cachedTransforms[tweenProperty] = originalInlinedValue;
|
|
2007
|
+
}
|
|
2008
|
+
if (tween._renderTransforms) {
|
|
2009
|
+
if (!Object.keys(cachedTransforms).length) {
|
|
2010
|
+
targetStyle.removeProperty('transform');
|
|
2011
|
+
} else {
|
|
2012
|
+
targetStyle.transform = buildTransformString(cachedTransforms);
|
|
2013
|
+
}
|
|
2014
|
+
}
|
|
1806
2015
|
} else {
|
|
1807
|
-
|
|
2016
|
+
if (tweenHadNoInlineValue) {
|
|
2017
|
+
targetStyle.removeProperty(toLowerCase(tweenProperty));
|
|
2018
|
+
} else {
|
|
2019
|
+
targetStyle[tweenProperty] = originalInlinedValue;
|
|
2020
|
+
}
|
|
1808
2021
|
}
|
|
1809
2022
|
}
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
}
|
|
2023
|
+
}
|
|
2024
|
+
if (tweenTarget[isDomSymbol] && animation._tail === tween) {
|
|
2025
|
+
animation.targets.forEach(t => {
|
|
2026
|
+
if (t.getAttribute && t.getAttribute('style') === emptyString) {
|
|
2027
|
+
t.removeAttribute('style');
|
|
2028
|
+
} });
|
|
1816
2029
|
}
|
|
1817
2030
|
});
|
|
1818
2031
|
}
|
|
1819
2032
|
return renderable;
|
|
1820
2033
|
};
|
|
1821
2034
|
|
|
2035
|
+
/**
|
|
2036
|
+
* @template {Renderable} T
|
|
2037
|
+
* @param {T} renderable
|
|
2038
|
+
* @return {T}
|
|
2039
|
+
*/
|
|
2040
|
+
const cleanInlineStyles = renderable => revertValues(renderable, true);
|
|
2041
|
+
|
|
1822
2042
|
|
|
1823
2043
|
|
|
1824
2044
|
/*
|
|
@@ -2503,6 +2723,9 @@ const reviveTimer = timer => {
|
|
|
2503
2723
|
|
|
2504
2724
|
let timerId = 0;
|
|
2505
2725
|
|
|
2726
|
+
/** @param {Timer} prev @param {Timer} child */
|
|
2727
|
+
const sortByPriority = (prev, child) => prev._priority > child._priority;
|
|
2728
|
+
|
|
2506
2729
|
/**
|
|
2507
2730
|
* Base class used to create Timers, Animations and Timelines
|
|
2508
2731
|
*/
|
|
@@ -2529,6 +2752,7 @@ class Timer extends Clock {
|
|
|
2529
2752
|
autoplay,
|
|
2530
2753
|
frameRate,
|
|
2531
2754
|
playbackRate,
|
|
2755
|
+
priority,
|
|
2532
2756
|
onComplete,
|
|
2533
2757
|
onLoop,
|
|
2534
2758
|
onPause,
|
|
@@ -2550,16 +2774,6 @@ class Timer extends Clock {
|
|
|
2550
2774
|
/** @type {Number} */(timerLoop) < 0 ? Infinity :
|
|
2551
2775
|
/** @type {Number} */(timerLoop) + 1;
|
|
2552
2776
|
|
|
2553
|
-
if (devTools) {
|
|
2554
|
-
const isInfinite = timerIterationCount === Infinity;
|
|
2555
|
-
const registered = devTools.register(this, parameters, isInfinite);
|
|
2556
|
-
if (registered && isInfinite) {
|
|
2557
|
-
const minIterations = alternate ? 2 : 1;
|
|
2558
|
-
const iterations = parent ? devTools.maxNestedInfiniteLoops : devTools.maxInfiniteLoops;
|
|
2559
|
-
timerIterationCount = Math.max(iterations, minIterations);
|
|
2560
|
-
}
|
|
2561
|
-
}
|
|
2562
|
-
|
|
2563
2777
|
let offsetPosition = 0;
|
|
2564
2778
|
|
|
2565
2779
|
if (parent) {
|
|
@@ -2643,6 +2857,8 @@ class Timer extends Clock {
|
|
|
2643
2857
|
this._fps = setValue(frameRate, timerDefaults.frameRate);
|
|
2644
2858
|
/** @type {Number} */
|
|
2645
2859
|
this._speed = setValue(playbackRate, timerDefaults.playbackRate);
|
|
2860
|
+
/** @type {Number} */
|
|
2861
|
+
this._priority = +setValue(priority, 1);
|
|
2646
2862
|
}
|
|
2647
2863
|
|
|
2648
2864
|
get cancelled() {
|
|
@@ -2787,7 +3003,7 @@ class Timer extends Clock {
|
|
|
2787
3003
|
tick(this, minValue, 0, 0, tickModes.FORCE);
|
|
2788
3004
|
} else {
|
|
2789
3005
|
if (!this._running) {
|
|
2790
|
-
addChild(engine, this);
|
|
3006
|
+
addChild(engine, this, sortByPriority);
|
|
2791
3007
|
engine._hasChildren = true;
|
|
2792
3008
|
this._running = true;
|
|
2793
3009
|
}
|
|
@@ -3382,7 +3598,7 @@ class JSAnimation extends Timer {
|
|
|
3382
3598
|
* @param {Number} [parentPosition]
|
|
3383
3599
|
* @param {Boolean} [fastSet=false]
|
|
3384
3600
|
* @param {Number} [index=0]
|
|
3385
|
-
* @param {
|
|
3601
|
+
* @param {TargetsArray} [allTargets]
|
|
3386
3602
|
*/
|
|
3387
3603
|
constructor(
|
|
3388
3604
|
targets,
|
|
@@ -3391,7 +3607,7 @@ class JSAnimation extends Timer {
|
|
|
3391
3607
|
parentPosition,
|
|
3392
3608
|
fastSet = false,
|
|
3393
3609
|
index = 0,
|
|
3394
|
-
|
|
3610
|
+
allTargets
|
|
3395
3611
|
) {
|
|
3396
3612
|
|
|
3397
3613
|
super(/** @type {TimerParams & AnimationParams} */(parameters), parent, parentPosition);
|
|
@@ -3442,7 +3658,7 @@ class JSAnimation extends Timer {
|
|
|
3442
3658
|
|
|
3443
3659
|
const target = parsedTargets[targetIndex];
|
|
3444
3660
|
const ti = index || targetIndex;
|
|
3445
|
-
const tl =
|
|
3661
|
+
const tl = allTargets || parsedTargets;
|
|
3446
3662
|
|
|
3447
3663
|
let lastTransformGroupIndex = NaN;
|
|
3448
3664
|
let lastTransformGroupLength = NaN;
|
|
@@ -3518,7 +3734,14 @@ class JSAnimation extends Timer {
|
|
|
3518
3734
|
toFunctionStore.func = null;
|
|
3519
3735
|
fromFunctionStore.func = null;
|
|
3520
3736
|
|
|
3521
|
-
const
|
|
3737
|
+
const computedComposition = getFunctionValue(setValue(key.composition, tComposition), target, ti, tl, null, null);
|
|
3738
|
+
const tweenComposition = isNum(computedComposition) ? computedComposition : compositionTypes[computedComposition];
|
|
3739
|
+
if (!siblings && tweenComposition !== compositionTypes.none) siblings = getTweenSiblings(target, propName);
|
|
3740
|
+
// Timelines pass the last sibling tween if it belongs to the same timeline
|
|
3741
|
+
// Standalone animations only pass prevTween when the property has multiple keyframes
|
|
3742
|
+
const tailTween = siblings ? siblings._tail : null;
|
|
3743
|
+
const prevSiblingTween = parent && tailTween && tailTween.parent.parent === parent ? tailTween : prevTween;
|
|
3744
|
+
const computedToValue = getFunctionValue(key.to, target, ti, tl, toFunctionStore, prevSiblingTween);
|
|
3522
3745
|
|
|
3523
3746
|
let tweenToValue;
|
|
3524
3747
|
// Allows function based values to return an object syntax value ({to: v})
|
|
@@ -3528,20 +3751,18 @@ class JSAnimation extends Timer {
|
|
|
3528
3751
|
} else {
|
|
3529
3752
|
tweenToValue = computedToValue;
|
|
3530
3753
|
}
|
|
3531
|
-
const tweenFromValue = getFunctionValue(key.from, target, ti, tl);
|
|
3754
|
+
const tweenFromValue = getFunctionValue(key.from, target, ti, tl, null, prevSiblingTween);
|
|
3532
3755
|
const easeToParse = key.ease || tEasing;
|
|
3533
3756
|
|
|
3534
|
-
const easeFunctionResult = getFunctionValue(easeToParse, target, ti, tl);
|
|
3757
|
+
const easeFunctionResult = getFunctionValue(easeToParse, target, ti, tl, null, prevSiblingTween);
|
|
3535
3758
|
const keyEasing = isFnc(easeFunctionResult) || isStr(easeFunctionResult) ? easeFunctionResult : easeToParse;
|
|
3536
3759
|
|
|
3537
3760
|
const hasSpring = !isUnd(keyEasing) && !isUnd(/** @type {Spring} */(keyEasing).ease);
|
|
3538
3761
|
const tweenEasing = hasSpring ? /** @type {Spring} */(keyEasing).ease : keyEasing;
|
|
3539
3762
|
// Calculate default individual keyframe duration by dividing the tl of keyframes
|
|
3540
|
-
const tweenDuration = hasSpring ? /** @type {Spring} */(keyEasing).settlingDuration : getFunctionValue(setValue(key.duration, (l > 1 ? getFunctionValue(tDuration, target, ti, tl) / l : tDuration)), target, ti, tl);
|
|
3763
|
+
const tweenDuration = hasSpring ? /** @type {Spring} */(keyEasing).settlingDuration : getFunctionValue(setValue(key.duration, (l > 1 ? getFunctionValue(tDuration, target, ti, tl, null, prevSiblingTween) / l : tDuration)), target, ti, tl, null, prevSiblingTween);
|
|
3541
3764
|
// Default delay value should only be applied to the first tween
|
|
3542
|
-
const tweenDelay = getFunctionValue(setValue(key.delay, (!tweenIndex ? tDelay : 0)), target, ti, tl);
|
|
3543
|
-
const computedComposition = getFunctionValue(setValue(key.composition, tComposition), target, ti, tl);
|
|
3544
|
-
const tweenComposition = isNum(computedComposition) ? computedComposition : compositionTypes[computedComposition];
|
|
3765
|
+
const tweenDelay = getFunctionValue(setValue(key.delay, (!tweenIndex ? tDelay : 0)), target, ti, tl, null, prevSiblingTween);
|
|
3545
3766
|
// Modifiers are treated differently and don't accept function based value to prevent having to pass a function wrapper
|
|
3546
3767
|
const tweenModifier = key.modifier || tModifier;
|
|
3547
3768
|
const hasFromvalue = !isUnd(tweenFromValue);
|
|
@@ -3558,7 +3779,6 @@ class JSAnimation extends Timer {
|
|
|
3558
3779
|
let prevSibling = prevTween;
|
|
3559
3780
|
|
|
3560
3781
|
if (tweenComposition !== compositionTypes.none) {
|
|
3561
|
-
if (!siblings) siblings = getTweenSiblings(target, propName);
|
|
3562
3782
|
let nextSibling = siblings._head;
|
|
3563
3783
|
// Iterate trough all the next siblings until we find a sibling with an equal or inferior start time
|
|
3564
3784
|
while (nextSibling && !nextSibling._isOverridden && nextSibling._absoluteStartTime <= absoluteStartTime) {
|
|
@@ -3577,8 +3797,8 @@ class JSAnimation extends Timer {
|
|
|
3577
3797
|
|
|
3578
3798
|
// Decompose values
|
|
3579
3799
|
if (isFromToValue) {
|
|
3580
|
-
decomposeRawValue(isFromToArray ? getFunctionValue(tweenToValue[0], target, ti, tl, fromFunctionStore) : tweenFromValue, fromTargetObject);
|
|
3581
|
-
decomposeRawValue(isFromToArray ? getFunctionValue(tweenToValue[1], target, ti, tl, toFunctionStore) : tweenToValue, toTargetObject);
|
|
3800
|
+
decomposeRawValue(isFromToArray ? getFunctionValue(tweenToValue[0], target, ti, tl, fromFunctionStore, prevSiblingTween) : tweenFromValue, fromTargetObject);
|
|
3801
|
+
decomposeRawValue(isFromToArray ? getFunctionValue(tweenToValue[1], target, ti, tl, toFunctionStore, prevSiblingTween) : tweenToValue, toTargetObject);
|
|
3582
3802
|
// Needed to force an inline style registration
|
|
3583
3803
|
const originalValue = getOriginalAnimatableValue(target, propName, tweenType, inlineStylesStore);
|
|
3584
3804
|
if (fromTargetObject.t === valueTypes.NUMBER) {
|
|
@@ -3732,6 +3952,18 @@ class JSAnimation extends Timer {
|
|
|
3732
3952
|
composeTween(tween, siblings);
|
|
3733
3953
|
}
|
|
3734
3954
|
|
|
3955
|
+
// Pre-compute the tween end value for function-based value chaining (ie morphTo / scrambleText in keyframe arrays and timelines)
|
|
3956
|
+
const vt = tween._valueType;
|
|
3957
|
+
if (vt === valueTypes.COMPLEX) {
|
|
3958
|
+
tween._value = composeComplexValue(tween, 1, -1);
|
|
3959
|
+
} else if (vt === valueTypes.COLOR) {
|
|
3960
|
+
tween._value = composeColorValue(tween, 1, -1);
|
|
3961
|
+
} else if (vt === valueTypes.UNIT) {
|
|
3962
|
+
tween._value = `${tweenModifier(tween._toNumber)}${tween._unit}`;
|
|
3963
|
+
} else {
|
|
3964
|
+
tween._value = tweenModifier(tween._toNumber);
|
|
3965
|
+
}
|
|
3966
|
+
|
|
3735
3967
|
if (isNaN(firstTweenChangeStartTime)) {
|
|
3736
3968
|
firstTweenChangeStartTime = tween._startTime;
|
|
3737
3969
|
}
|
|
@@ -3889,7 +4121,7 @@ class JSAnimation extends Timer {
|
|
|
3889
4121
|
*/
|
|
3890
4122
|
revert() {
|
|
3891
4123
|
super.revert();
|
|
3892
|
-
return
|
|
4124
|
+
return revertValues(this);
|
|
3893
4125
|
}
|
|
3894
4126
|
|
|
3895
4127
|
/**
|
|
@@ -3911,170 +4143,12 @@ class JSAnimation extends Timer {
|
|
|
3911
4143
|
* @param {AnimationParams} parameters
|
|
3912
4144
|
* @return {JSAnimation}
|
|
3913
4145
|
*/
|
|
3914
|
-
const animate = (targets, parameters) =>
|
|
3915
|
-
|
|
3916
|
-
|
|
3917
|
-
|
|
3918
|
-
|
|
3919
|
-
|
|
3920
|
-
const WAAPIAnimationsLookups = {
|
|
3921
|
-
_head: null,
|
|
3922
|
-
_tail: null,
|
|
3923
|
-
};
|
|
3924
|
-
|
|
3925
|
-
/**
|
|
3926
|
-
* @param {DOMTarget} $el
|
|
3927
|
-
* @param {String} [property]
|
|
3928
|
-
* @param {WAAPIAnimation} [parent]
|
|
3929
|
-
* @return {globalThis.Animation}
|
|
3930
|
-
*/
|
|
3931
|
-
const removeWAAPIAnimation = ($el, property, parent) => {
|
|
3932
|
-
let nextLookup = WAAPIAnimationsLookups._head;
|
|
3933
|
-
let anim;
|
|
3934
|
-
while (nextLookup) {
|
|
3935
|
-
const next = nextLookup._next;
|
|
3936
|
-
const matchTarget = nextLookup.$el === $el;
|
|
3937
|
-
const matchProperty = !property || nextLookup.property === property;
|
|
3938
|
-
const matchParent = !parent || nextLookup.parent === parent;
|
|
3939
|
-
if (matchTarget && matchProperty && matchParent) {
|
|
3940
|
-
anim = nextLookup.animation;
|
|
3941
|
-
try { anim.commitStyles(); } catch {} anim.cancel();
|
|
3942
|
-
removeChild(WAAPIAnimationsLookups, nextLookup);
|
|
3943
|
-
const lookupParent = nextLookup.parent;
|
|
3944
|
-
if (lookupParent) {
|
|
3945
|
-
lookupParent._completed++;
|
|
3946
|
-
if (lookupParent.animations.length === lookupParent._completed) {
|
|
3947
|
-
lookupParent.completed = true;
|
|
3948
|
-
lookupParent.paused = true;
|
|
3949
|
-
if (!lookupParent.muteCallbacks) {
|
|
3950
|
-
lookupParent.onComplete(lookupParent);
|
|
3951
|
-
lookupParent._resolve(lookupParent);
|
|
3952
|
-
}
|
|
3953
|
-
}
|
|
3954
|
-
}
|
|
3955
|
-
}
|
|
3956
|
-
nextLookup = next;
|
|
3957
|
-
}
|
|
3958
|
-
return anim;
|
|
3959
|
-
};
|
|
3960
|
-
|
|
3961
|
-
/**
|
|
3962
|
-
* @param {WAAPIAnimation} parent
|
|
3963
|
-
* @param {DOMTarget} $el
|
|
3964
|
-
* @param {String} property
|
|
3965
|
-
* @param {PropertyIndexedKeyframes} keyframes
|
|
3966
|
-
* @param {KeyframeAnimationOptions} params
|
|
3967
|
-
* @retun {globalThis.Animation}
|
|
3968
|
-
*/
|
|
3969
|
-
const addWAAPIAnimation = (parent, $el, property, keyframes, params) => {
|
|
3970
|
-
const animation = $el.animate(keyframes, params);
|
|
3971
|
-
const animTotalDuration = params.delay + (+params.duration * params.iterations);
|
|
3972
|
-
animation.playbackRate = parent._speed;
|
|
3973
|
-
if (parent.paused) animation.pause();
|
|
3974
|
-
if (parent.duration < animTotalDuration) {
|
|
3975
|
-
parent.duration = animTotalDuration;
|
|
3976
|
-
parent.controlAnimation = animation;
|
|
3977
|
-
}
|
|
3978
|
-
parent.animations.push(animation);
|
|
3979
|
-
removeWAAPIAnimation($el, property);
|
|
3980
|
-
addChild(WAAPIAnimationsLookups, { parent, animation, $el, property, _next: null, _prev: null });
|
|
3981
|
-
const handleRemove = () => removeWAAPIAnimation($el, property, parent);
|
|
3982
|
-
animation.oncancel = handleRemove;
|
|
3983
|
-
animation.onremove = handleRemove;
|
|
3984
|
-
if (!parent.persist) {
|
|
3985
|
-
animation.onfinish = handleRemove;
|
|
3986
|
-
}
|
|
3987
|
-
return animation;
|
|
3988
|
-
};
|
|
3989
|
-
|
|
3990
|
-
|
|
3991
|
-
|
|
3992
|
-
|
|
3993
|
-
|
|
3994
|
-
/**
|
|
3995
|
-
* @overload
|
|
3996
|
-
* @param {DOMTargetSelector} targetSelector
|
|
3997
|
-
* @param {String} propName
|
|
3998
|
-
* @return {String}
|
|
3999
|
-
*
|
|
4000
|
-
* @overload
|
|
4001
|
-
* @param {JSTargetsParam} targetSelector
|
|
4002
|
-
* @param {String} propName
|
|
4003
|
-
* @return {Number|String}
|
|
4004
|
-
*
|
|
4005
|
-
* @overload
|
|
4006
|
-
* @param {DOMTargetsParam} targetSelector
|
|
4007
|
-
* @param {String} propName
|
|
4008
|
-
* @param {String} unit
|
|
4009
|
-
* @return {String}
|
|
4010
|
-
*
|
|
4011
|
-
* @overload
|
|
4012
|
-
* @param {TargetsParam} targetSelector
|
|
4013
|
-
* @param {String} propName
|
|
4014
|
-
* @param {Boolean} unit
|
|
4015
|
-
* @return {Number}
|
|
4016
|
-
*
|
|
4017
|
-
* @param {TargetsParam} targetSelector
|
|
4018
|
-
* @param {String} propName
|
|
4019
|
-
* @param {String|Boolean} [unit]
|
|
4020
|
-
*/
|
|
4021
|
-
function get(targetSelector, propName, unit) {
|
|
4022
|
-
const targets = registerTargets(targetSelector);
|
|
4023
|
-
if (!targets.length) return;
|
|
4024
|
-
const [ target ] = targets;
|
|
4025
|
-
const tweenType = getTweenType(target, propName);
|
|
4026
|
-
const normalizePropName = sanitizePropertyName(propName, target, tweenType);
|
|
4027
|
-
let originalValue = getOriginalAnimatableValue(target, normalizePropName);
|
|
4028
|
-
if (isUnd(unit)) {
|
|
4029
|
-
return originalValue;
|
|
4030
|
-
} else {
|
|
4031
|
-
decomposeRawValue(originalValue, decomposedOriginalValue);
|
|
4032
|
-
if (decomposedOriginalValue.t === valueTypes.NUMBER || decomposedOriginalValue.t === valueTypes.UNIT) {
|
|
4033
|
-
if (unit === false) {
|
|
4034
|
-
return decomposedOriginalValue.n;
|
|
4035
|
-
} else {
|
|
4036
|
-
const convertedValue = convertValueUnit(/** @type {DOMTarget} */(target), decomposedOriginalValue, /** @type {String} */(unit), false);
|
|
4037
|
-
return `${round$1(convertedValue.n, globals.precision)}${convertedValue.u}`;
|
|
4038
|
-
}
|
|
4039
|
-
}
|
|
4040
|
-
}
|
|
4041
|
-
}
|
|
4042
|
-
|
|
4043
|
-
/**
|
|
4044
|
-
* @param {TargetsParam} targets
|
|
4045
|
-
* @param {AnimationParams} parameters
|
|
4046
|
-
* @return {JSAnimation}
|
|
4047
|
-
*/
|
|
4048
|
-
const set = (targets, parameters) => {
|
|
4049
|
-
if (isUnd(parameters)) return;
|
|
4050
|
-
parameters.duration = minValue;
|
|
4051
|
-
// Do not overrides currently active tweens by default
|
|
4052
|
-
parameters.composition = setValue(parameters.composition, compositionTypes.none);
|
|
4053
|
-
// Skip init() and force rendering by playing the animation
|
|
4054
|
-
return new JSAnimation(targets, parameters, null, 0, true).resume();
|
|
4055
|
-
};
|
|
4056
|
-
|
|
4057
|
-
/**
|
|
4058
|
-
* @param {TargetsParam} targets
|
|
4059
|
-
* @param {Renderable|WAAPIAnimation} [renderable]
|
|
4060
|
-
* @param {String} [propertyName]
|
|
4061
|
-
* @return {TargetsArray}
|
|
4062
|
-
*/
|
|
4063
|
-
const remove = (targets, renderable, propertyName) => {
|
|
4064
|
-
const targetsArray = parseTargets(targets);
|
|
4065
|
-
for (let i = 0, l = targetsArray.length; i < l; i++) {
|
|
4066
|
-
removeWAAPIAnimation(
|
|
4067
|
-
/** @type {DOMTarget} */(targetsArray[i]),
|
|
4068
|
-
propertyName,
|
|
4069
|
-
renderable && /** @type {WAAPIAnimation} */(renderable).controlAnimation && /** @type {WAAPIAnimation} */(renderable),
|
|
4070
|
-
);
|
|
4071
|
-
}
|
|
4072
|
-
removeTargetsFromRenderable(
|
|
4073
|
-
targetsArray,
|
|
4074
|
-
/** @type {Renderable} */(renderable),
|
|
4075
|
-
propertyName
|
|
4076
|
-
);
|
|
4077
|
-
return targetsArray;
|
|
4146
|
+
const animate = (targets, parameters) => {
|
|
4147
|
+
if (globals.editor) {
|
|
4148
|
+
return globals.editor.addAnimation(targets, parameters);
|
|
4149
|
+
} else {
|
|
4150
|
+
return new JSAnimation(targets, parameters, null, 0, false).init();
|
|
4151
|
+
}
|
|
4078
4152
|
};
|
|
4079
4153
|
|
|
4080
4154
|
|
|
@@ -4130,6 +4204,8 @@ const parseTimelinePosition = (timeline, timePosition) => {
|
|
|
4130
4204
|
|
|
4131
4205
|
|
|
4132
4206
|
|
|
4207
|
+
|
|
4208
|
+
|
|
4133
4209
|
/**
|
|
4134
4210
|
* @param {Timeline} tl
|
|
4135
4211
|
* @return {Number}
|
|
@@ -4151,7 +4227,7 @@ function getTimelineTotalDuration(tl) {
|
|
|
4151
4227
|
* @param {Number} timePosition
|
|
4152
4228
|
* @param {TargetsParam} targets
|
|
4153
4229
|
* @param {Number} [index]
|
|
4154
|
-
* @param {
|
|
4230
|
+
* @param {TargetsArray} [allTargets]
|
|
4155
4231
|
* @return {Timeline}
|
|
4156
4232
|
*
|
|
4157
4233
|
* @param {TimerParams|AnimationParams} childParams
|
|
@@ -4159,15 +4235,15 @@ function getTimelineTotalDuration(tl) {
|
|
|
4159
4235
|
* @param {Number} timePosition
|
|
4160
4236
|
* @param {TargetsParam} [targets]
|
|
4161
4237
|
* @param {Number} [index]
|
|
4162
|
-
* @param {
|
|
4238
|
+
* @param {TargetsArray} [allTargets]
|
|
4163
4239
|
*/
|
|
4164
|
-
function addTlChild(childParams, tl, timePosition, targets, index,
|
|
4240
|
+
function addTlChild(childParams, tl, timePosition, targets, index, allTargets) {
|
|
4165
4241
|
const isSetter = isNum(childParams.duration) && /** @type {Number} */(childParams.duration) <= minValue;
|
|
4166
4242
|
// Offset the tl position with -minValue for 0 duration animations or .set() calls in order to align their end value with the defined position
|
|
4167
4243
|
const adjustedPosition = isSetter ? timePosition - minValue : timePosition;
|
|
4168
4244
|
if (tl.composition) tick(tl, adjustedPosition, 1, 1, tickModes.AUTO);
|
|
4169
4245
|
const tlChild = targets ?
|
|
4170
|
-
new JSAnimation(targets,/** @type {AnimationParams} */(childParams), tl, adjustedPosition, false, index,
|
|
4246
|
+
new JSAnimation(targets,/** @type {AnimationParams} */(childParams), tl, adjustedPosition, false, index, allTargets) :
|
|
4171
4247
|
new Timer(/** @type {TimerParams} */(childParams), tl, adjustedPosition);
|
|
4172
4248
|
if (tl.composition) tlChild.init(true);
|
|
4173
4249
|
// TODO: Might be better to insert at a position relative to startTime?
|
|
@@ -4215,7 +4291,7 @@ class Timeline extends Timer {
|
|
|
4215
4291
|
* @overload
|
|
4216
4292
|
* @param {TargetsParam} a1
|
|
4217
4293
|
* @param {AnimationParams} a2
|
|
4218
|
-
* @param {TimelinePosition|StaggerFunction<Number|String
|
|
4294
|
+
* @param {TimelinePosition|StaggerFunction<Number|String>|TweakRegister} [a3]
|
|
4219
4295
|
* @return {this}
|
|
4220
4296
|
*
|
|
4221
4297
|
* @overload
|
|
@@ -4225,7 +4301,7 @@ class Timeline extends Timer {
|
|
|
4225
4301
|
*
|
|
4226
4302
|
* @param {TargetsParam|TimerParams} a1
|
|
4227
4303
|
* @param {TimelinePosition|AnimationParams} a2
|
|
4228
|
-
* @param {TimelinePosition|StaggerFunction<Number|String
|
|
4304
|
+
* @param {TimelinePosition|StaggerFunction<Number|String>|TweakRegister} [a3]
|
|
4229
4305
|
*/
|
|
4230
4306
|
add(a1, a2, a3) {
|
|
4231
4307
|
const isAnim = isObj(a2);
|
|
@@ -4234,9 +4310,11 @@ class Timeline extends Timer {
|
|
|
4234
4310
|
this._hasChildren = true;
|
|
4235
4311
|
if (isAnim) {
|
|
4236
4312
|
const childParams = /** @type {AnimationParams} */(a2);
|
|
4237
|
-
|
|
4238
|
-
|
|
4239
|
-
|
|
4313
|
+
const editorHook = globals.editor && globals.editor.addTimelineChild;
|
|
4314
|
+
const isStaggerType = a3 && /** @type {TweakRegister} */(a3).type === 'Stagger' && globals.editor;
|
|
4315
|
+
// Check for function or Stagger type children positions
|
|
4316
|
+
const staggeredPosition = isFnc(a3) ? a3 : null;
|
|
4317
|
+
if (staggeredPosition || isStaggerType) {
|
|
4240
4318
|
const parsedTargetsArray = parseTargets(/** @type {TargetsParam} */(a1));
|
|
4241
4319
|
// Store initial duration before adding new children that will change the duration
|
|
4242
4320
|
const tlDuration = this.duration;
|
|
@@ -4247,28 +4325,36 @@ class Timeline extends Timer {
|
|
|
4247
4325
|
let i = 0;
|
|
4248
4326
|
/** @type {Number} */
|
|
4249
4327
|
const parsedLength = (parsedTargetsArray.length);
|
|
4328
|
+
// Call editor hook once for the entire stagger group instead of per target
|
|
4329
|
+
const resolvedParams = editorHook ? editorHook(/** @type {TargetsParam} */(a1), childParams, this.id, a3, parsedLength) : null;
|
|
4330
|
+
// Resolve stagger AFTER editor hook so tweaked position value (a3.defaultValue) is used
|
|
4331
|
+
const staggerFn = staggeredPosition || globals.editor.resolveStagger(/** @type {TweakRegister} */(a3).defaultValue);
|
|
4250
4332
|
parsedTargetsArray.forEach((/** @type {Target} */target) => {
|
|
4251
4333
|
// Create a new parameter object for each staggered children
|
|
4252
|
-
const staggeredChildParams = { ...childParams };
|
|
4334
|
+
const staggeredChildParams = { ...(resolvedParams || childParams) };
|
|
4253
4335
|
// Reset the duration of the timeline iteration before each stagger to prevent wrong start value calculation
|
|
4254
4336
|
this.duration = tlDuration;
|
|
4255
4337
|
this.iterationDuration = tlIterationDuration;
|
|
4256
4338
|
if (!isUnd(id)) staggeredChildParams.id = id + '-' + i;
|
|
4339
|
+
const staggeredTimePosition = parseTimelinePosition(this, staggerFn(target, i, parsedTargetsArray, null, this));
|
|
4257
4340
|
addTlChild(
|
|
4258
4341
|
staggeredChildParams,
|
|
4259
4342
|
this,
|
|
4260
|
-
|
|
4343
|
+
staggeredTimePosition,
|
|
4261
4344
|
target,
|
|
4262
4345
|
i,
|
|
4263
|
-
|
|
4346
|
+
parsedTargetsArray,
|
|
4264
4347
|
);
|
|
4265
4348
|
i++;
|
|
4266
4349
|
});
|
|
4267
4350
|
} else {
|
|
4351
|
+
// Call editor hook before resolving position so tweaked values are applied
|
|
4352
|
+
const resolvedChildParams = editorHook ? editorHook(/** @type {TargetsParam} */(a1), childParams, this.id, a3) : childParams;
|
|
4353
|
+
const resolvedPosition = a3 && /** @type {*} */(a3).type ? /** @type {*} */(a3).defaultValue : a3;
|
|
4268
4354
|
addTlChild(
|
|
4269
|
-
|
|
4355
|
+
resolvedChildParams,
|
|
4270
4356
|
this,
|
|
4271
|
-
parseTimelinePosition(this,
|
|
4357
|
+
parseTimelinePosition(this, resolvedPosition),
|
|
4272
4358
|
/** @type {TargetsParam} */(a1),
|
|
4273
4359
|
);
|
|
4274
4360
|
}
|
|
@@ -4390,7 +4476,7 @@ class Timeline extends Timer {
|
|
|
4390
4476
|
revert() {
|
|
4391
4477
|
super.revert();
|
|
4392
4478
|
forEachChildren(this, (/** @type {JSAnimation|Timer} */child) => child.revert, true);
|
|
4393
|
-
return
|
|
4479
|
+
return revertValues(this);
|
|
4394
4480
|
}
|
|
4395
4481
|
|
|
4396
4482
|
/**
|
|
@@ -4410,7 +4496,12 @@ class Timeline extends Timer {
|
|
|
4410
4496
|
* @param {TimelineParams} [parameters]
|
|
4411
4497
|
* @return {Timeline}
|
|
4412
4498
|
*/
|
|
4413
|
-
const createTimeline = parameters =>
|
|
4499
|
+
const createTimeline = parameters => {
|
|
4500
|
+
if (globals.editor) {
|
|
4501
|
+
return /** @type {Timeline} */(/** @type {unknown} */(globals.editor.addTimeline(parameters)));
|
|
4502
|
+
}
|
|
4503
|
+
return new Timeline(parameters).init();
|
|
4504
|
+
};
|
|
4414
4505
|
|
|
4415
4506
|
|
|
4416
4507
|
|
|
@@ -4857,6 +4948,170 @@ const createSpring = (parameters) => {
|
|
|
4857
4948
|
|
|
4858
4949
|
|
|
4859
4950
|
|
|
4951
|
+
const WAAPIAnimationsLookups = {
|
|
4952
|
+
_head: null,
|
|
4953
|
+
_tail: null,
|
|
4954
|
+
};
|
|
4955
|
+
|
|
4956
|
+
/**
|
|
4957
|
+
* @param {DOMTarget} $el
|
|
4958
|
+
* @param {String} [property]
|
|
4959
|
+
* @param {WAAPIAnimation} [parent]
|
|
4960
|
+
* @return {globalThis.Animation}
|
|
4961
|
+
*/
|
|
4962
|
+
const removeWAAPIAnimation = ($el, property, parent) => {
|
|
4963
|
+
let nextLookup = WAAPIAnimationsLookups._head;
|
|
4964
|
+
let anim;
|
|
4965
|
+
while (nextLookup) {
|
|
4966
|
+
const next = nextLookup._next;
|
|
4967
|
+
const matchTarget = nextLookup.$el === $el;
|
|
4968
|
+
const matchProperty = !property || nextLookup.property === property;
|
|
4969
|
+
const matchParent = !parent || nextLookup.parent === parent;
|
|
4970
|
+
if (matchTarget && matchProperty && matchParent) {
|
|
4971
|
+
anim = nextLookup.animation;
|
|
4972
|
+
try { anim.commitStyles(); } catch {} anim.cancel();
|
|
4973
|
+
removeChild(WAAPIAnimationsLookups, nextLookup);
|
|
4974
|
+
const lookupParent = nextLookup.parent;
|
|
4975
|
+
if (lookupParent) {
|
|
4976
|
+
lookupParent._completed++;
|
|
4977
|
+
if (lookupParent.animations.length === lookupParent._completed) {
|
|
4978
|
+
lookupParent.completed = true;
|
|
4979
|
+
lookupParent.paused = true;
|
|
4980
|
+
if (!lookupParent.muteCallbacks) {
|
|
4981
|
+
lookupParent.onComplete(lookupParent);
|
|
4982
|
+
lookupParent._resolve(lookupParent);
|
|
4983
|
+
}
|
|
4984
|
+
}
|
|
4985
|
+
}
|
|
4986
|
+
}
|
|
4987
|
+
nextLookup = next;
|
|
4988
|
+
}
|
|
4989
|
+
return anim;
|
|
4990
|
+
};
|
|
4991
|
+
|
|
4992
|
+
/**
|
|
4993
|
+
* @param {WAAPIAnimation} parent
|
|
4994
|
+
* @param {DOMTarget} $el
|
|
4995
|
+
* @param {String} property
|
|
4996
|
+
* @param {PropertyIndexedKeyframes} keyframes
|
|
4997
|
+
* @param {KeyframeAnimationOptions} params
|
|
4998
|
+
* @retun {globalThis.Animation}
|
|
4999
|
+
*/
|
|
5000
|
+
const addWAAPIAnimation = (parent, $el, property, keyframes, params) => {
|
|
5001
|
+
const animation = $el.animate(keyframes, params);
|
|
5002
|
+
const animTotalDuration = params.delay + (+params.duration * params.iterations);
|
|
5003
|
+
animation.playbackRate = parent._speed;
|
|
5004
|
+
if (parent.paused) animation.pause();
|
|
5005
|
+
if (parent.duration < animTotalDuration) {
|
|
5006
|
+
parent.duration = animTotalDuration;
|
|
5007
|
+
parent.controlAnimation = animation;
|
|
5008
|
+
}
|
|
5009
|
+
parent.animations.push(animation);
|
|
5010
|
+
removeWAAPIAnimation($el, property);
|
|
5011
|
+
addChild(WAAPIAnimationsLookups, { parent, animation, $el, property, _next: null, _prev: null });
|
|
5012
|
+
const handleRemove = () => removeWAAPIAnimation($el, property, parent);
|
|
5013
|
+
animation.oncancel = handleRemove;
|
|
5014
|
+
animation.onremove = handleRemove;
|
|
5015
|
+
if (!parent.persist) {
|
|
5016
|
+
animation.onfinish = handleRemove;
|
|
5017
|
+
}
|
|
5018
|
+
return animation;
|
|
5019
|
+
};
|
|
5020
|
+
|
|
5021
|
+
|
|
5022
|
+
|
|
5023
|
+
|
|
5024
|
+
|
|
5025
|
+
/**
|
|
5026
|
+
* @overload
|
|
5027
|
+
* @param {DOMTargetSelector} targetSelector
|
|
5028
|
+
* @param {String} propName
|
|
5029
|
+
* @return {String}
|
|
5030
|
+
*
|
|
5031
|
+
* @overload
|
|
5032
|
+
* @param {JSTargetsParam} targetSelector
|
|
5033
|
+
* @param {String} propName
|
|
5034
|
+
* @return {Number|String}
|
|
5035
|
+
*
|
|
5036
|
+
* @overload
|
|
5037
|
+
* @param {DOMTargetsParam} targetSelector
|
|
5038
|
+
* @param {String} propName
|
|
5039
|
+
* @param {String} unit
|
|
5040
|
+
* @return {String}
|
|
5041
|
+
*
|
|
5042
|
+
* @overload
|
|
5043
|
+
* @param {TargetsParam} targetSelector
|
|
5044
|
+
* @param {String} propName
|
|
5045
|
+
* @param {Boolean} unit
|
|
5046
|
+
* @return {Number}
|
|
5047
|
+
*
|
|
5048
|
+
* @param {TargetsParam} targetSelector
|
|
5049
|
+
* @param {String} propName
|
|
5050
|
+
* @param {String|Boolean} [unit]
|
|
5051
|
+
*/
|
|
5052
|
+
function get(targetSelector, propName, unit) {
|
|
5053
|
+
const targets = registerTargets(targetSelector);
|
|
5054
|
+
if (!targets.length) return;
|
|
5055
|
+
const [ target ] = targets;
|
|
5056
|
+
const tweenType = getTweenType(target, propName);
|
|
5057
|
+
const normalizePropName = sanitizePropertyName(propName, target, tweenType);
|
|
5058
|
+
let originalValue = getOriginalAnimatableValue(target, normalizePropName);
|
|
5059
|
+
if (isUnd(unit)) {
|
|
5060
|
+
return originalValue;
|
|
5061
|
+
} else {
|
|
5062
|
+
decomposeRawValue(originalValue, decomposedOriginalValue);
|
|
5063
|
+
if (decomposedOriginalValue.t === valueTypes.NUMBER || decomposedOriginalValue.t === valueTypes.UNIT) {
|
|
5064
|
+
if (unit === false) {
|
|
5065
|
+
return decomposedOriginalValue.n;
|
|
5066
|
+
} else {
|
|
5067
|
+
const convertedValue = convertValueUnit(/** @type {DOMTarget} */(target), decomposedOriginalValue, /** @type {String} */(unit), false);
|
|
5068
|
+
return `${round$1(convertedValue.n, globals.precision)}${convertedValue.u}`;
|
|
5069
|
+
}
|
|
5070
|
+
}
|
|
5071
|
+
}
|
|
5072
|
+
}
|
|
5073
|
+
|
|
5074
|
+
/**
|
|
5075
|
+
* @param {TargetsParam} targets
|
|
5076
|
+
* @param {AnimationParams} parameters
|
|
5077
|
+
* @return {JSAnimation}
|
|
5078
|
+
*/
|
|
5079
|
+
const set = (targets, parameters) => {
|
|
5080
|
+
if (isUnd(parameters)) return;
|
|
5081
|
+
parameters.duration = minValue;
|
|
5082
|
+
// Do not overrides currently active tweens by default
|
|
5083
|
+
parameters.composition = setValue(parameters.composition, compositionTypes.none);
|
|
5084
|
+
// Skip init() and force rendering by playing the animation
|
|
5085
|
+
return new JSAnimation(targets, parameters, null, 0, true).resume();
|
|
5086
|
+
};
|
|
5087
|
+
|
|
5088
|
+
/**
|
|
5089
|
+
* @param {TargetsParam} targets
|
|
5090
|
+
* @param {Renderable|WAAPIAnimation} [renderable]
|
|
5091
|
+
* @param {String} [propertyName]
|
|
5092
|
+
* @return {TargetsArray}
|
|
5093
|
+
*/
|
|
5094
|
+
const remove = (targets, renderable, propertyName) => {
|
|
5095
|
+
const targetsArray = parseTargets(targets);
|
|
5096
|
+
for (let i = 0, l = targetsArray.length; i < l; i++) {
|
|
5097
|
+
removeWAAPIAnimation(
|
|
5098
|
+
/** @type {DOMTarget} */(targetsArray[i]),
|
|
5099
|
+
propertyName,
|
|
5100
|
+
renderable && /** @type {WAAPIAnimation} */(renderable).controlAnimation && /** @type {WAAPIAnimation} */(renderable),
|
|
5101
|
+
);
|
|
5102
|
+
}
|
|
5103
|
+
removeTargetsFromRenderable(
|
|
5104
|
+
targetsArray,
|
|
5105
|
+
/** @type {Renderable} */(renderable),
|
|
5106
|
+
propertyName
|
|
5107
|
+
);
|
|
5108
|
+
return targetsArray;
|
|
5109
|
+
};
|
|
5110
|
+
|
|
5111
|
+
|
|
5112
|
+
|
|
5113
|
+
|
|
5114
|
+
|
|
4860
5115
|
/**
|
|
4861
5116
|
* @param {Event} e
|
|
4862
5117
|
*/
|
|
@@ -6059,19 +6314,20 @@ const sync = (callback = noop) => {
|
|
|
6059
6314
|
};
|
|
6060
6315
|
|
|
6061
6316
|
/**
|
|
6062
|
-
* @param {(...args: any[]) => Tickable | ((...args: any[]) => void)} constructor
|
|
6317
|
+
* @param {(...args: any[]) => Tickable | ((...args: any[]) => void) | void} constructor
|
|
6063
6318
|
* @return {(...args: any[]) => Tickable | ((...args: any[]) => void)}
|
|
6064
6319
|
*/
|
|
6065
6320
|
const keepTime = constructor => {
|
|
6066
6321
|
/** @type {Tickable} */
|
|
6067
6322
|
let tracked;
|
|
6068
6323
|
return (...args) => {
|
|
6069
|
-
let currentIteration, currentIterationProgress, reversed, alternate;
|
|
6324
|
+
let currentIteration, currentIterationProgress, reversed, alternate, startTime;
|
|
6070
6325
|
if (tracked) {
|
|
6071
6326
|
currentIteration = tracked.currentIteration;
|
|
6072
6327
|
currentIterationProgress = tracked.iterationProgress;
|
|
6073
6328
|
reversed = tracked.reversed;
|
|
6074
6329
|
alternate = tracked._alternate;
|
|
6330
|
+
startTime = tracked._startTime;
|
|
6075
6331
|
tracked.revert();
|
|
6076
6332
|
}
|
|
6077
6333
|
const cleanup = constructor(...args);
|
|
@@ -6079,6 +6335,7 @@ const keepTime = constructor => {
|
|
|
6079
6335
|
if (!isUnd(currentIterationProgress)) {
|
|
6080
6336
|
/** @type {Tickable} */(tracked).currentIteration = currentIteration;
|
|
6081
6337
|
/** @type {Tickable} */(tracked).iterationProgress = (alternate ? !(currentIteration % 2) ? reversed : !reversed : reversed) ? 1 - currentIterationProgress : currentIterationProgress;
|
|
6338
|
+
/** @type {Tickable} */(tracked)._startTime = startTime;
|
|
6082
6339
|
}
|
|
6083
6340
|
return cleanup || noop;
|
|
6084
6341
|
}
|
|
@@ -7424,12 +7681,12 @@ let transformsPropertiesRegistered = null;
|
|
|
7424
7681
|
* @param {WAAPIKeyframeValue} value
|
|
7425
7682
|
* @param {DOMTarget} $el
|
|
7426
7683
|
* @param {Number} i
|
|
7427
|
-
* @param {
|
|
7684
|
+
* @param {DOMTargetsArray} parsedTargets
|
|
7428
7685
|
* @return {String}
|
|
7429
7686
|
*/
|
|
7430
|
-
const normalizeTweenValue = (propName, value, $el, i,
|
|
7687
|
+
const normalizeTweenValue = (propName, value, $el, i, parsedTargets) => {
|
|
7431
7688
|
// Do not try to compute strings with getFunctionValue otherwise it will convert CSS variables
|
|
7432
|
-
let v = isStr(value) ? value : getFunctionValue(/** @type {any} */(value), $el, i,
|
|
7689
|
+
let v = isStr(value) ? value : getFunctionValue(/** @type {any} */(value), $el, i, parsedTargets, null, null);
|
|
7433
7690
|
if (!isNum(v)) return v;
|
|
7434
7691
|
if (commonDefaultPXProperties.includes(propName) || stringStartsWith(propName, 'translate')) return `${v}px`;
|
|
7435
7692
|
if (stringStartsWith(propName, 'rotate') || stringStartsWith(propName, 'skew')) return `${v}deg`;
|
|
@@ -7442,18 +7699,18 @@ const normalizeTweenValue = (propName, value, $el, i, targetsLength) => {
|
|
|
7442
7699
|
* @param {WAAPIKeyframeValue} from
|
|
7443
7700
|
* @param {WAAPIKeyframeValue} to
|
|
7444
7701
|
* @param {Number} i
|
|
7445
|
-
* @param {
|
|
7702
|
+
* @param {DOMTargetsArray} parsedTargets
|
|
7446
7703
|
* @return {WAAPITweenValue}
|
|
7447
7704
|
*/
|
|
7448
|
-
const parseIndividualTweenValue = ($el, propName, from, to, i,
|
|
7705
|
+
const parseIndividualTweenValue = ($el, propName, from, to, i, parsedTargets) => {
|
|
7449
7706
|
/** @type {WAAPITweenValue} */
|
|
7450
7707
|
let tweenValue = '0';
|
|
7451
|
-
const computedTo = !isUnd(to) ? normalizeTweenValue(propName, to, $el, i,
|
|
7708
|
+
const computedTo = !isUnd(to) ? normalizeTweenValue(propName, to, $el, i, parsedTargets) : getComputedStyle($el)[propName];
|
|
7452
7709
|
if (!isUnd(from)) {
|
|
7453
|
-
const computedFrom = normalizeTweenValue(propName, from, $el, i,
|
|
7710
|
+
const computedFrom = normalizeTweenValue(propName, from, $el, i, parsedTargets);
|
|
7454
7711
|
tweenValue = [computedFrom, computedTo];
|
|
7455
7712
|
} else {
|
|
7456
|
-
tweenValue = isArr(to) ? to.map((/** @type {any} */v) => normalizeTweenValue(propName, v, $el, i,
|
|
7713
|
+
tweenValue = isArr(to) ? to.map((/** @type {any} */v) => normalizeTweenValue(propName, v, $el, i, parsedTargets)) : computedTo;
|
|
7457
7714
|
}
|
|
7458
7715
|
return tweenValue;
|
|
7459
7716
|
};
|
|
@@ -7492,9 +7749,8 @@ class WAAPIAnimation {
|
|
|
7492
7749
|
}
|
|
7493
7750
|
|
|
7494
7751
|
const parsedTargets = registerTargets(targets);
|
|
7495
|
-
const targetsLength = parsedTargets.length;
|
|
7496
7752
|
|
|
7497
|
-
if (!
|
|
7753
|
+
if (!parsedTargets.length) {
|
|
7498
7754
|
console.warn(`No target found. Make sure the element you're trying to animate is accessible before creating your animation.`);
|
|
7499
7755
|
}
|
|
7500
7756
|
|
|
@@ -7550,7 +7806,7 @@ class WAAPIAnimation {
|
|
|
7550
7806
|
|
|
7551
7807
|
const easeToParse = setValue(params.ease, globals.defaults.ease);
|
|
7552
7808
|
|
|
7553
|
-
const easeFunctionResult = getFunctionValue(easeToParse, $el, i,
|
|
7809
|
+
const easeFunctionResult = getFunctionValue(easeToParse, $el, i, parsedTargets, null, null);
|
|
7554
7810
|
const keyEasing = isFnc(easeFunctionResult) || isStr(easeFunctionResult) ? easeFunctionResult : easeToParse;
|
|
7555
7811
|
|
|
7556
7812
|
const spring = /** @type {Spring} */(easeToParse).ease && easeToParse;
|
|
@@ -7558,9 +7814,9 @@ class WAAPIAnimation {
|
|
|
7558
7814
|
const easing = parseWAAPIEasing(keyEasing);
|
|
7559
7815
|
|
|
7560
7816
|
/** @type {Number} */
|
|
7561
|
-
const duration = (spring ? /** @type {Spring} */(spring).settlingDuration : getFunctionValue(setValue(params.duration, globals.defaults.duration), $el, i,
|
|
7817
|
+
const duration = (spring ? /** @type {Spring} */(spring).settlingDuration : getFunctionValue(setValue(params.duration, globals.defaults.duration), $el, i, parsedTargets, null, null)) * timeScale;
|
|
7562
7818
|
/** @type {Number} */
|
|
7563
|
-
const delay = getFunctionValue(setValue(params.delay, globals.defaults.delay), $el, i,
|
|
7819
|
+
const delay = getFunctionValue(setValue(params.delay, globals.defaults.delay), $el, i, parsedTargets, null, null) * timeScale;
|
|
7564
7820
|
/** @type {CompositeOperation} */
|
|
7565
7821
|
const composite = /** @type {CompositeOperation} */(setValue(params.composition, 'replace'));
|
|
7566
7822
|
|
|
@@ -7586,19 +7842,19 @@ class WAAPIAnimation {
|
|
|
7586
7842
|
const to = /** @type {WAAPITweenOptions} */(tweenOptions).to;
|
|
7587
7843
|
const from = /** @type {WAAPITweenOptions} */(tweenOptions).from;
|
|
7588
7844
|
/** @type {Number} */
|
|
7589
|
-
tweenParams.duration = (tweenOptionsSpring ? /** @type {Spring} */(tweenOptionsSpring).settlingDuration : getFunctionValue(setValue(tweenOptions.duration, duration), $el, i,
|
|
7845
|
+
tweenParams.duration = (tweenOptionsSpring ? /** @type {Spring} */(tweenOptionsSpring).settlingDuration : getFunctionValue(setValue(tweenOptions.duration, duration), $el, i, parsedTargets, null, null)) * timeScale;
|
|
7590
7846
|
/** @type {Number} */
|
|
7591
|
-
tweenParams.delay = getFunctionValue(setValue(tweenOptions.delay, delay), $el, i,
|
|
7847
|
+
tweenParams.delay = getFunctionValue(setValue(tweenOptions.delay, delay), $el, i, parsedTargets, null, null) * timeScale;
|
|
7592
7848
|
/** @type {CompositeOperation} */
|
|
7593
7849
|
tweenParams.composite = /** @type {CompositeOperation} */(setValue(tweenOptions.composition, composite));
|
|
7594
7850
|
/** @type {String} */
|
|
7595
7851
|
tweenParams.easing = parseWAAPIEasing(tweenOptionsEase);
|
|
7596
|
-
parsedPropertyValue = parseIndividualTweenValue($el, name, from, to, i,
|
|
7852
|
+
parsedPropertyValue = parseIndividualTweenValue($el, name, from, to, i, parsedTargets);
|
|
7597
7853
|
if (individualTransformProperty) {
|
|
7598
7854
|
keyframes[`--${individualTransformProperty}`] = parsedPropertyValue;
|
|
7599
7855
|
cachedTransforms[individualTransformProperty] = parsedPropertyValue;
|
|
7600
7856
|
} else {
|
|
7601
|
-
keyframes[name] = parseIndividualTweenValue($el, name, from, to, i,
|
|
7857
|
+
keyframes[name] = parseIndividualTweenValue($el, name, from, to, i, parsedTargets);
|
|
7602
7858
|
}
|
|
7603
7859
|
addWAAPIAnimation(this, $el, name, keyframes, tweenParams);
|
|
7604
7860
|
if (!isUnd(from)) {
|
|
@@ -7611,8 +7867,8 @@ class WAAPIAnimation {
|
|
|
7611
7867
|
}
|
|
7612
7868
|
} else {
|
|
7613
7869
|
parsedPropertyValue = isArr(propertyValue) ?
|
|
7614
|
-
propertyValue.map((/** @type {any} */v) => normalizeTweenValue(name, v, $el, i,
|
|
7615
|
-
normalizeTweenValue(name, /** @type {any} */(propertyValue), $el, i,
|
|
7870
|
+
propertyValue.map((/** @type {any} */v) => normalizeTweenValue(name, v, $el, i, parsedTargets)) :
|
|
7871
|
+
normalizeTweenValue(name, /** @type {any} */(propertyValue), $el, i, parsedTargets);
|
|
7616
7872
|
if (individualTransformProperty) {
|
|
7617
7873
|
keyframes[`--${individualTransformProperty}`] = parsedPropertyValue;
|
|
7618
7874
|
cachedTransforms[individualTransformProperty] = parsedPropertyValue;
|
|
@@ -7822,6 +8078,8 @@ const waapi = {
|
|
|
7822
8078
|
|
|
7823
8079
|
|
|
7824
8080
|
|
|
8081
|
+
|
|
8082
|
+
|
|
7825
8083
|
/**
|
|
7826
8084
|
* @typedef {DOMTargetSelector|Array<DOMTargetSelector>} LayoutChildrenParam
|
|
7827
8085
|
*/
|
|
@@ -7843,6 +8101,7 @@ const waapi = {
|
|
|
7843
8101
|
|
|
7844
8102
|
/**
|
|
7845
8103
|
* @typedef {Object} LayoutSpecificAnimationParams
|
|
8104
|
+
* @property {Number|String} [id]
|
|
7846
8105
|
* @property {Number|FunctionValue} [delay]
|
|
7847
8106
|
* @property {Number|FunctionValue} [duration]
|
|
7848
8107
|
* @property {EasingParam|FunctionValue} [ease]
|
|
@@ -7885,7 +8144,7 @@ const waapi = {
|
|
|
7885
8144
|
* @property {String} id
|
|
7886
8145
|
* @property {DOMTarget} $el
|
|
7887
8146
|
* @property {Number} index
|
|
7888
|
-
* @property {
|
|
8147
|
+
* @property {Array<DOMTarget>} targets
|
|
7889
8148
|
* @property {Number} delay
|
|
7890
8149
|
* @property {Number} duration
|
|
7891
8150
|
* @property {EasingParam} ease
|
|
@@ -8029,7 +8288,7 @@ const createNode = ($el, parentNode, state, recycledNode) => {
|
|
|
8029
8288
|
node.$measure = $el;
|
|
8030
8289
|
node.id = dataId;
|
|
8031
8290
|
node.index = 0;
|
|
8032
|
-
node.
|
|
8291
|
+
node.targets = null;
|
|
8033
8292
|
node.delay = 0;
|
|
8034
8293
|
node.duration = 0;
|
|
8035
8294
|
node.ease = null;
|
|
@@ -8215,12 +8474,12 @@ const updateNodeProperties = (node, props) => {
|
|
|
8215
8474
|
* @param {LayoutAnimationTimingsParams} params
|
|
8216
8475
|
*/
|
|
8217
8476
|
const updateNodeTimingParams = (node, params) => {
|
|
8218
|
-
const easeFunctionResult = getFunctionValue(params.ease, node.$el, node.index, node.
|
|
8477
|
+
const easeFunctionResult = getFunctionValue(params.ease, node.$el, node.index, node.targets, null, null);
|
|
8219
8478
|
const keyEasing = isFnc(easeFunctionResult) ? easeFunctionResult : params.ease;
|
|
8220
8479
|
const hasSpring = !isUnd(keyEasing) && !isUnd(/** @type {Spring} */(keyEasing).ease);
|
|
8221
8480
|
node.ease = hasSpring ? /** @type {Spring} */(keyEasing).ease : keyEasing;
|
|
8222
|
-
node.duration = hasSpring ? /** @type {Spring} */(keyEasing).settlingDuration : getFunctionValue(params.duration, node.$el, node.index, node.
|
|
8223
|
-
node.delay = getFunctionValue(params.delay, node.$el, node.index, node.
|
|
8481
|
+
node.duration = hasSpring ? /** @type {Spring} */(keyEasing).settlingDuration : getFunctionValue(params.duration, node.$el, node.index, node.targets, null, null);
|
|
8482
|
+
node.delay = getFunctionValue(params.delay, node.$el, node.index, node.targets, null, null);
|
|
8224
8483
|
};
|
|
8225
8484
|
|
|
8226
8485
|
/**
|
|
@@ -8593,10 +8852,12 @@ class LayoutSnapshot {
|
|
|
8593
8852
|
|
|
8594
8853
|
const inRootNodeIds = new Set();
|
|
8595
8854
|
// Update index and total for inital timing calculation
|
|
8596
|
-
let index = 0
|
|
8855
|
+
let index = 0;
|
|
8856
|
+
const allNodeTargets = [];
|
|
8857
|
+
this.nodes.forEach((node) => { allNodeTargets.push(node.$el); });
|
|
8597
8858
|
this.nodes.forEach((node, id) => {
|
|
8598
8859
|
node.index = index++;
|
|
8599
|
-
node.
|
|
8860
|
+
node.targets = allNodeTargets;
|
|
8600
8861
|
// Track ids of nodes that belong to the current root to filter detached matches
|
|
8601
8862
|
if (node && node.measuredIsInsideRoot) {
|
|
8602
8863
|
inRootNodeIds.add(id);
|
|
@@ -8708,8 +8969,8 @@ class AutoLayout {
|
|
|
8708
8969
|
this.params = params;
|
|
8709
8970
|
/** @type {DOMTarget} */
|
|
8710
8971
|
this.root = /** @type {DOMTarget} */(registerTargets(root)[0]);
|
|
8711
|
-
/** @type {Number} */
|
|
8712
|
-
this.id = layoutId++;
|
|
8972
|
+
/** @type {Number|String} */
|
|
8973
|
+
this.id = params.id || layoutId++;
|
|
8713
8974
|
/** @type {LayoutChildrenParam} */
|
|
8714
8975
|
this.children = params.children || '*';
|
|
8715
8976
|
/** @type {Boolean} */
|
|
@@ -8832,7 +9093,9 @@ class AutoLayout {
|
|
|
8832
9093
|
duration: setValue(params.duration, this.params.duration),
|
|
8833
9094
|
};
|
|
8834
9095
|
/** @type {TimelineParams} */
|
|
8835
|
-
const tlParams = {
|
|
9096
|
+
const tlParams = {
|
|
9097
|
+
id: this.id
|
|
9098
|
+
};
|
|
8836
9099
|
const onComplete = setValue(params.onComplete, this.params.onComplete);
|
|
8837
9100
|
const onPause = setValue(params.onPause, this.params.onPause);
|
|
8838
9101
|
for (let name in defaults) {
|
|
@@ -8845,6 +9108,13 @@ class AutoLayout {
|
|
|
8845
9108
|
}
|
|
8846
9109
|
}
|
|
8847
9110
|
tlParams.onComplete = () => {
|
|
9111
|
+
const ap = /** @type {ScrollObserver} */(params.autoplay);
|
|
9112
|
+
const ed = globals.editor;
|
|
9113
|
+
const isScrollControled = (ap && ap.linked) || (ed && ed.showPanel);
|
|
9114
|
+
if (isScrollControled) {
|
|
9115
|
+
if (onComplete) onComplete(this.timeline);
|
|
9116
|
+
return;
|
|
9117
|
+
}
|
|
8848
9118
|
// Make sure to call .cancel() after restoreNodeInlineStyles(node); otehrwise the commited styles get reverted
|
|
8849
9119
|
if (this.transformAnimation) this.transformAnimation.cancel();
|
|
8850
9120
|
newState.forEachRootNode(node => {
|
|
@@ -8866,6 +9136,13 @@ class AutoLayout {
|
|
|
8866
9136
|
});
|
|
8867
9137
|
};
|
|
8868
9138
|
tlParams.onPause = () => {
|
|
9139
|
+
const ap = /** @type {ScrollObserver} */(params.autoplay);
|
|
9140
|
+
const isScrollControled = ap && ap.linked;
|
|
9141
|
+
if (isScrollControled) {
|
|
9142
|
+
if (onComplete) onComplete(this.timeline);
|
|
9143
|
+
if (onPause) onPause(this.timeline);
|
|
9144
|
+
return;
|
|
9145
|
+
}
|
|
8869
9146
|
if (!this.root.classList.contains('is-animated')) return;
|
|
8870
9147
|
if (this.transformAnimation) this.transformAnimation.cancel();
|
|
8871
9148
|
newState.forEachRootNode(restoreNodeVisualState);
|
|
@@ -9032,41 +9309,39 @@ class AutoLayout {
|
|
|
9032
9309
|
animatedParent = animatedParent.parentNode;
|
|
9033
9310
|
}
|
|
9034
9311
|
|
|
9035
|
-
const animatingTotal = animating.length;
|
|
9036
|
-
|
|
9037
9312
|
// Root is always animated first in sync with the first child (animating.length is the total of children)
|
|
9038
9313
|
if (node === rootNode) {
|
|
9039
9314
|
node.index = 0;
|
|
9040
|
-
node.
|
|
9315
|
+
node.targets = animating;
|
|
9041
9316
|
updateNodeTimingParams(node, animationTimings);
|
|
9042
9317
|
} else if (node.isEntering) {
|
|
9043
9318
|
node.index = animatedParent ? animatedParent.index : enteringIndex;
|
|
9044
|
-
node.
|
|
9319
|
+
node.targets = animatedParent ? animating : entering;
|
|
9045
9320
|
updateNodeTimingParams(node, enterFromTimings);
|
|
9046
9321
|
enteringIndex++;
|
|
9047
9322
|
} else if (node.isLeaving) {
|
|
9048
9323
|
node.index = animatedParent ? animatedParent.index : leavingIndex;
|
|
9049
|
-
node.
|
|
9324
|
+
node.targets = animatedParent ? animating : leaving;
|
|
9050
9325
|
leavingIndex++;
|
|
9051
9326
|
updateNodeTimingParams(node, leaveToTimings);
|
|
9052
9327
|
} else if (node.isTarget) {
|
|
9053
9328
|
node.index = animatingIndex++;
|
|
9054
|
-
node.
|
|
9329
|
+
node.targets = animating;
|
|
9055
9330
|
updateNodeTimingParams(node, animationTimings);
|
|
9056
9331
|
} else {
|
|
9057
9332
|
node.index = animatedParent ? animatedParent.index : 0;
|
|
9058
|
-
node.
|
|
9333
|
+
node.targets = animating;
|
|
9059
9334
|
updateNodeTimingParams(node, swapAtTimings);
|
|
9060
9335
|
}
|
|
9061
9336
|
|
|
9062
9337
|
// Make sure the old state node has its inex and total values up to date for valid "from" function values calculation
|
|
9063
9338
|
oldStateNode.index = node.index;
|
|
9064
|
-
oldStateNode.
|
|
9339
|
+
oldStateNode.targets = node.targets;
|
|
9065
9340
|
|
|
9066
9341
|
// Computes all values up front so we can check for changes and we don't have to re-compute them inside the animation props
|
|
9067
9342
|
for (let prop in nodeProperties) {
|
|
9068
|
-
nodeProperties[prop] = getFunctionValue(nodeProperties[prop], $el, node.index, node.
|
|
9069
|
-
oldStateNodeProperties[prop] = getFunctionValue(oldStateNodeProperties[prop], $el, oldStateNode.index, oldStateNode.
|
|
9343
|
+
nodeProperties[prop] = getFunctionValue(nodeProperties[prop], $el, node.index, node.targets, null, null);
|
|
9344
|
+
oldStateNodeProperties[prop] = getFunctionValue(oldStateNodeProperties[prop], $el, oldStateNode.index, oldStateNode.targets, null, null);
|
|
9070
9345
|
}
|
|
9071
9346
|
|
|
9072
9347
|
// Use a 1px tolerance to detect dimensions changes to prevent width / height animations on barelly visible elements
|
|
@@ -9292,8 +9567,8 @@ class AutoLayout {
|
|
|
9292
9567
|
}
|
|
9293
9568
|
$el.style.transform = oldState.getComputedValue($el, 'transform');
|
|
9294
9569
|
if (animatedSwap.includes($el)) {
|
|
9295
|
-
node.ease = getFunctionValue(swapAtParams.ease, $el, node.index, node.
|
|
9296
|
-
node.duration = getFunctionValue(swapAtParams.duration, $el, node.index, node.
|
|
9570
|
+
node.ease = getFunctionValue(swapAtParams.ease, $el, node.index, node.targets, null, null);
|
|
9571
|
+
node.duration = getFunctionValue(swapAtParams.duration, $el, node.index, node.targets, null, null);
|
|
9297
9572
|
}
|
|
9298
9573
|
}
|
|
9299
9574
|
this.transformAnimation = waapi.animate(transformed, {
|
|
@@ -9308,7 +9583,7 @@ class AutoLayout {
|
|
|
9308
9583
|
if (!animatedSwap.includes($el)) return newValue;
|
|
9309
9584
|
const oldValue = oldState.getComputedValue($el, 'transform');
|
|
9310
9585
|
const node = newState.getNode($el);
|
|
9311
|
-
return [oldValue, getFunctionValue(swapAtProps.transform, $el, node.index, node.
|
|
9586
|
+
return [oldValue, getFunctionValue(swapAtProps.transform, $el, node.index, node.targets, null, null), newValue]
|
|
9312
9587
|
},
|
|
9313
9588
|
autoplay: false,
|
|
9314
9589
|
// persist: true,
|
|
@@ -9365,10 +9640,13 @@ const chain = fn => {
|
|
|
9365
9640
|
const result = fn(...args);
|
|
9366
9641
|
return new Proxy(noop, {
|
|
9367
9642
|
apply: (_, __, [v]) => result(v),
|
|
9368
|
-
get: (_, prop) =>
|
|
9369
|
-
|
|
9370
|
-
return (/**@
|
|
9371
|
-
|
|
9643
|
+
get: (_, prop) => {
|
|
9644
|
+
if (!chainables[prop]) return undefined;
|
|
9645
|
+
return chain(/**@param {...Number|String} nextArgs */(...nextArgs) => {
|
|
9646
|
+
const nextResult = chainables[prop](...nextArgs);
|
|
9647
|
+
return (/**@type {Number|String} */v) => nextResult(result(v));
|
|
9648
|
+
})
|
|
9649
|
+
}
|
|
9372
9650
|
});
|
|
9373
9651
|
}
|
|
9374
9652
|
};
|
|
@@ -9579,24 +9857,28 @@ const shuffle = items => {
|
|
|
9579
9857
|
* @param {StaggerParams} [params]
|
|
9580
9858
|
* @return {StaggerFunction<Number>}
|
|
9581
9859
|
*/
|
|
9860
|
+
|
|
9582
9861
|
/**
|
|
9583
9862
|
* @overload
|
|
9584
9863
|
* @param {String} val
|
|
9585
9864
|
* @param {StaggerParams} [params]
|
|
9586
9865
|
* @return {StaggerFunction<String>}
|
|
9587
9866
|
*/
|
|
9867
|
+
|
|
9588
9868
|
/**
|
|
9589
9869
|
* @overload
|
|
9590
9870
|
* @param {[Number, Number]} val
|
|
9591
9871
|
* @param {StaggerParams} [params]
|
|
9592
9872
|
* @return {StaggerFunction<Number>}
|
|
9593
9873
|
*/
|
|
9874
|
+
|
|
9594
9875
|
/**
|
|
9595
9876
|
* @overload
|
|
9596
9877
|
* @param {[String, String]} val
|
|
9597
9878
|
* @param {StaggerParams} [params]
|
|
9598
9879
|
* @return {StaggerFunction<String>}
|
|
9599
9880
|
*/
|
|
9881
|
+
|
|
9600
9882
|
/**
|
|
9601
9883
|
* @param {Number|String|[Number, Number]|[String, String]} val The staggered value or range
|
|
9602
9884
|
* @param {StaggerParams} [params] The stagger parameters
|
|
@@ -9605,6 +9887,7 @@ const shuffle = items => {
|
|
|
9605
9887
|
const stagger = (val, params = {}) => {
|
|
9606
9888
|
let values = [];
|
|
9607
9889
|
let maxValue = 0;
|
|
9890
|
+
let cachedOffset;
|
|
9608
9891
|
const from = params.from;
|
|
9609
9892
|
const reversed = params.reversed;
|
|
9610
9893
|
const ease = params.ease;
|
|
@@ -9612,12 +9895,14 @@ const stagger = (val, params = {}) => {
|
|
|
9612
9895
|
const hasSpring = hasEasing && !isUnd(/** @type {Spring} */(ease).ease);
|
|
9613
9896
|
const staggerEase = hasSpring ? /** @type {Spring} */(ease).ease : hasEasing ? parseEase(ease) : null;
|
|
9614
9897
|
const grid = params.grid;
|
|
9898
|
+
const autoGrid = grid === true;
|
|
9615
9899
|
const axis = params.axis;
|
|
9616
9900
|
const customTotal = params.total;
|
|
9617
9901
|
const fromFirst = isUnd(from) || from === 0 || from === 'first';
|
|
9618
9902
|
const fromCenter = from === 'center';
|
|
9619
9903
|
const fromLast = from === 'last';
|
|
9620
9904
|
const fromRandom = from === 'random';
|
|
9905
|
+
const fromArr = isArr(from);
|
|
9621
9906
|
const isRange = isArr(val);
|
|
9622
9907
|
const useProp = params.use;
|
|
9623
9908
|
const val1 = isRange ? parseNumber(val[0]) : parseNumber(val);
|
|
@@ -9625,40 +9910,129 @@ const stagger = (val, params = {}) => {
|
|
|
9625
9910
|
const unitMatch = unitsExecRgx.exec((isRange ? val[1] : val) + emptyString);
|
|
9626
9911
|
const start = params.start || 0 + (isRange ? val1 : 0);
|
|
9627
9912
|
let fromIndex = fromFirst ? 0 : isNum(from) ? from : 0;
|
|
9628
|
-
return (target, i, t, tl) => {
|
|
9913
|
+
return (target, i, t, _, tl) => {
|
|
9629
9914
|
const [ registeredTarget ] = registerTargets(target);
|
|
9630
|
-
const total = isUnd(customTotal) ? t : customTotal;
|
|
9915
|
+
const total = isUnd(customTotal) ? t.length : customTotal;
|
|
9631
9916
|
const customIndex = !isUnd(useProp) ? isFnc(useProp) ? useProp(registeredTarget, i, total) : getOriginalAnimatableValue(registeredTarget, useProp) : false;
|
|
9632
9917
|
const staggerIndex = isNum(customIndex) || isStr(customIndex) && isNum(+customIndex) ? +customIndex : i;
|
|
9633
9918
|
if (fromCenter) fromIndex = (total - 1) / 2;
|
|
9634
9919
|
if (fromLast) fromIndex = total - 1;
|
|
9635
9920
|
if (!values.length) {
|
|
9636
|
-
|
|
9637
|
-
|
|
9638
|
-
|
|
9921
|
+
if (autoGrid) {
|
|
9922
|
+
let hasPositions = true;
|
|
9923
|
+
let minPosX = Infinity;
|
|
9924
|
+
let minPosY = Infinity;
|
|
9925
|
+
let maxPosX = -Infinity;
|
|
9926
|
+
let maxPosY = -Infinity;
|
|
9927
|
+
const pxArr = [];
|
|
9928
|
+
const pyArr = [];
|
|
9929
|
+
for (let index = 0; index < total; index++) {
|
|
9930
|
+
const el = t[index];
|
|
9931
|
+
let px = 0;
|
|
9932
|
+
let py = 0;
|
|
9933
|
+
let found = false;
|
|
9934
|
+
if (el && isFnc(el.getBoundingClientRect)) {
|
|
9935
|
+
const rect = el.getBoundingClientRect();
|
|
9936
|
+
px = rect.left + rect.width / 2;
|
|
9937
|
+
py = rect.top + rect.height / 2;
|
|
9938
|
+
found = true;
|
|
9939
|
+
} else {
|
|
9940
|
+
const obj = /** @type {JSTarget} */(el);
|
|
9941
|
+
if (obj && isNum(obj.x) && isNum(obj.y)) {
|
|
9942
|
+
px = obj.x;
|
|
9943
|
+
py = obj.y;
|
|
9944
|
+
found = true;
|
|
9945
|
+
}
|
|
9946
|
+
}
|
|
9947
|
+
if (!found) {
|
|
9948
|
+
hasPositions = false;
|
|
9949
|
+
break;
|
|
9950
|
+
}
|
|
9951
|
+
pxArr.push(px);
|
|
9952
|
+
pyArr.push(py);
|
|
9953
|
+
if (px < minPosX) minPosX = px;
|
|
9954
|
+
if (py < minPosY) minPosY = py;
|
|
9955
|
+
if (px > maxPosX) maxPosX = px;
|
|
9956
|
+
if (py > maxPosY) maxPosY = py;
|
|
9957
|
+
}
|
|
9958
|
+
if (hasPositions) {
|
|
9959
|
+
let fX = pxArr[0];
|
|
9960
|
+
let fY = pyArr[0];
|
|
9961
|
+
if (fromArr) {
|
|
9962
|
+
fX = minPosX + from[0] * (maxPosX - minPosX);
|
|
9963
|
+
fY = minPosY + from[1] * (maxPosY - minPosY);
|
|
9964
|
+
} else if (fromCenter) {
|
|
9965
|
+
fX = (minPosX + maxPosX) / 2;
|
|
9966
|
+
fY = (minPosY + maxPosY) / 2;
|
|
9967
|
+
} else if (fromLast) {
|
|
9968
|
+
fX = pxArr[total - 1];
|
|
9969
|
+
fY = pyArr[total - 1];
|
|
9970
|
+
} else if (isNum(from)) {
|
|
9971
|
+
fX = pxArr[from];
|
|
9972
|
+
fY = pyArr[from];
|
|
9973
|
+
}
|
|
9974
|
+
for (let index = 0; index < total; index++) {
|
|
9975
|
+
const distanceX = fX - pxArr[index];
|
|
9976
|
+
const distanceY = fY - pyArr[index];
|
|
9977
|
+
let value = sqrt(distanceX * distanceX + distanceY * distanceY);
|
|
9978
|
+
if (axis === 'x') value = -distanceX;
|
|
9979
|
+
if (axis === 'y') value = -distanceY;
|
|
9980
|
+
values.push(value);
|
|
9981
|
+
}
|
|
9982
|
+
let minDist = Infinity;
|
|
9983
|
+
for (let index = 0, l = values.length; index < l; index++) {
|
|
9984
|
+
const absVal = abs(values[index]);
|
|
9985
|
+
if (absVal > 0 && absVal < minDist) minDist = absVal;
|
|
9986
|
+
}
|
|
9987
|
+
if (minDist > 0 && minDist < Infinity) {
|
|
9988
|
+
for (let index = 0, l = values.length; index < l; index++) {
|
|
9989
|
+
values[index] = values[index] / minDist;
|
|
9990
|
+
}
|
|
9991
|
+
}
|
|
9639
9992
|
} else {
|
|
9640
|
-
|
|
9641
|
-
|
|
9642
|
-
|
|
9643
|
-
|
|
9644
|
-
|
|
9645
|
-
|
|
9646
|
-
|
|
9647
|
-
|
|
9648
|
-
|
|
9649
|
-
|
|
9993
|
+
for (let index = 0; index < total; index++) {
|
|
9994
|
+
values.push(abs(fromIndex - index));
|
|
9995
|
+
}
|
|
9996
|
+
}
|
|
9997
|
+
} else {
|
|
9998
|
+
for (let index = 0; index < total; index++) {
|
|
9999
|
+
if (!grid) {
|
|
10000
|
+
values.push(abs(fromIndex - index));
|
|
10001
|
+
} else {
|
|
10002
|
+
let fromX, fromY;
|
|
10003
|
+
if (fromArr) {
|
|
10004
|
+
fromX = from[0] * (grid[0] - 1);
|
|
10005
|
+
fromY = from[1] * (grid[1] - 1);
|
|
10006
|
+
} else if (fromCenter) {
|
|
10007
|
+
fromX = (grid[0] - 1) / 2;
|
|
10008
|
+
fromY = (grid[1] - 1) / 2;
|
|
10009
|
+
} else {
|
|
10010
|
+
fromX = fromIndex % grid[0];
|
|
10011
|
+
fromY = floor(fromIndex / grid[0]);
|
|
10012
|
+
}
|
|
10013
|
+
const toX = index % grid[0];
|
|
10014
|
+
const toY = floor(index / grid[0]);
|
|
10015
|
+
const distanceX = fromX - toX;
|
|
10016
|
+
const distanceY = fromY - toY;
|
|
10017
|
+
let value = sqrt(distanceX * distanceX + distanceY * distanceY);
|
|
10018
|
+
if (axis === 'x') value = -distanceX;
|
|
10019
|
+
if (axis === 'y') value = -distanceY;
|
|
10020
|
+
values.push(value);
|
|
10021
|
+
}
|
|
9650
10022
|
}
|
|
9651
|
-
maxValue = max(...values);
|
|
9652
10023
|
}
|
|
10024
|
+
maxValue = max(...values);
|
|
9653
10025
|
if (staggerEase) values = values.map(val => staggerEase(val / maxValue) * maxValue);
|
|
9654
10026
|
if (reversed) values = values.map(val => axis ? (val < 0) ? val * -1 : -val : abs(maxValue - val));
|
|
9655
10027
|
if (fromRandom) values = shuffle(values);
|
|
9656
10028
|
}
|
|
9657
10029
|
const spacing = isRange ? (val2 - val1) / maxValue : val1;
|
|
9658
|
-
|
|
10030
|
+
if (isUnd(cachedOffset)) {
|
|
10031
|
+
cachedOffset = tl ? parseTimelinePosition(tl, isUnd(params.start) ? tl.iterationDuration : start) : /** @type {Number} */(start);
|
|
10032
|
+
}
|
|
9659
10033
|
/** @type {String|Number} */
|
|
9660
|
-
let output =
|
|
9661
|
-
if (params.modifier) output = params.modifier(output);
|
|
10034
|
+
let output = cachedOffset + ((spacing * round$1(values[staggerIndex], 2)) || 0);
|
|
10035
|
+
if (params.modifier) output = params.modifier(/** @type {Number} */(output));
|
|
9662
10036
|
if (unitMatch) output = `${output}${unitMatch[2]}`;
|
|
9663
10037
|
return output;
|
|
9664
10038
|
}
|
|
@@ -9667,11 +10041,13 @@ const stagger = (val, params = {}) => {
|
|
|
9667
10041
|
var index$2 = /*#__PURE__*/Object.freeze({
|
|
9668
10042
|
__proto__: null,
|
|
9669
10043
|
$: registerTargets,
|
|
10044
|
+
addChild: addChild,
|
|
9670
10045
|
clamp: clamp,
|
|
9671
10046
|
cleanInlineStyles: cleanInlineStyles,
|
|
9672
10047
|
createSeededRandom: createSeededRandom,
|
|
9673
10048
|
damp: damp,
|
|
9674
10049
|
degToRad: degToRad,
|
|
10050
|
+
forEachChildren: forEachChildren,
|
|
9675
10051
|
get: get,
|
|
9676
10052
|
keepTime: keepTime,
|
|
9677
10053
|
lerp: lerp,
|
|
@@ -9682,6 +10058,7 @@ var index$2 = /*#__PURE__*/Object.freeze({
|
|
|
9682
10058
|
random: random,
|
|
9683
10059
|
randomPick: randomPick,
|
|
9684
10060
|
remove: remove,
|
|
10061
|
+
removeChild: removeChild,
|
|
9685
10062
|
round: round,
|
|
9686
10063
|
roundPad: roundPad,
|
|
9687
10064
|
set: set,
|
|
@@ -9881,7 +10258,7 @@ const createDrawable = (selector, start = 0, end = 0) => {
|
|
|
9881
10258
|
* @param {Number} [precision]
|
|
9882
10259
|
* @return {FunctionValue}
|
|
9883
10260
|
*/
|
|
9884
|
-
const morphTo = (path2, precision = .33) => ($path1) => {
|
|
10261
|
+
const morphTo = (path2, precision = .33) => ($path1, index, total, prevTween) => {
|
|
9885
10262
|
const tagName1 = ($path1.tagName || '').toLowerCase();
|
|
9886
10263
|
if (!tagName1.match(/^(path|polygon|polyline)$/)) {
|
|
9887
10264
|
throw new Error(`Can't morph a <${$path1.tagName}> SVG element. Use <path>, <polygon> or <polyline>.`);
|
|
@@ -9896,7 +10273,7 @@ const morphTo = (path2, precision = .33) => ($path1) => {
|
|
|
9896
10273
|
}
|
|
9897
10274
|
const isPath = $path1.tagName === 'path';
|
|
9898
10275
|
const separator = isPath ? ' ' : ',';
|
|
9899
|
-
const previousPoints =
|
|
10276
|
+
const previousPoints = prevTween ? prevTween._value : null;
|
|
9900
10277
|
if (previousPoints) $path1.setAttribute(isPath ? 'd' : 'points', previousPoints);
|
|
9901
10278
|
|
|
9902
10279
|
let v1 = '', v2 = '';
|
|
@@ -9918,8 +10295,6 @@ const morphTo = (path2, precision = .33) => ($path1) => {
|
|
|
9918
10295
|
}
|
|
9919
10296
|
}
|
|
9920
10297
|
|
|
9921
|
-
$path1[morphPointsSymbol] = v2;
|
|
9922
|
-
|
|
9923
10298
|
return [v1, v2];
|
|
9924
10299
|
};
|
|
9925
10300
|
|
|
@@ -10105,7 +10480,7 @@ const processHTMLTemplate = (htmlTemplate, store, node, $parentFragment, type, d
|
|
|
10105
10480
|
*/
|
|
10106
10481
|
class TextSplitter {
|
|
10107
10482
|
/**
|
|
10108
|
-
* @param {
|
|
10483
|
+
* @param {Element|NodeList|String|Array<Element>} target
|
|
10109
10484
|
* @param {TextSplitterParams} [parameters]
|
|
10110
10485
|
*/
|
|
10111
10486
|
constructor(target, parameters = {}) {
|
|
@@ -10177,11 +10552,11 @@ class TextSplitter {
|
|
|
10177
10552
|
}
|
|
10178
10553
|
|
|
10179
10554
|
/**
|
|
10180
|
-
* @param {(...args: any[]) => Tickable | (() => void)} effect
|
|
10555
|
+
* @param {(...args: any[]) => Tickable | (() => void) | void} effect
|
|
10181
10556
|
* @return this
|
|
10182
10557
|
*/
|
|
10183
10558
|
addEffect(effect) {
|
|
10184
|
-
if (!isFnc(effect))
|
|
10559
|
+
if (!isFnc(effect)) { console.warn('Effect must return a function.'); return this; }
|
|
10185
10560
|
const refreshableEffect = keepTime(effect);
|
|
10186
10561
|
this.effects.push(refreshableEffect);
|
|
10187
10562
|
if (this.ready) this.effectsCleanups[this.effects.length - 1] = refreshableEffect(this);
|
|
@@ -10387,7 +10762,7 @@ class TextSplitter {
|
|
|
10387
10762
|
}
|
|
10388
10763
|
|
|
10389
10764
|
/**
|
|
10390
|
-
* @param {
|
|
10765
|
+
* @param {Element|NodeList|String|Array<Element>} target
|
|
10391
10766
|
* @param {TextSplitterParams} [parameters]
|
|
10392
10767
|
* @return {TextSplitter}
|
|
10393
10768
|
*/
|
|
@@ -10405,11 +10780,263 @@ const split = (target, parameters) => {
|
|
|
10405
10780
|
return new TextSplitter(target, parameters);
|
|
10406
10781
|
};
|
|
10407
10782
|
|
|
10783
|
+
|
|
10784
|
+
|
|
10785
|
+
/**
|
|
10786
|
+
* '-' 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-')
|
|
10787
|
+
* @param {String} str
|
|
10788
|
+
* @return {String}
|
|
10789
|
+
*/
|
|
10790
|
+
const expandCharRanges = (str) => {
|
|
10791
|
+
let result = '';
|
|
10792
|
+
for (let i = 0, l = str.length; i < l; i++) {
|
|
10793
|
+
if (i + 2 < l && str[i + 1] === '-' && str.charCodeAt(i) < str.charCodeAt(i + 2)) {
|
|
10794
|
+
const start = str.charCodeAt(i);
|
|
10795
|
+
const end = str.charCodeAt(i + 2);
|
|
10796
|
+
for (let c = start; c <= end; c++) result += String.fromCharCode(c);
|
|
10797
|
+
i += 2;
|
|
10798
|
+
} else {
|
|
10799
|
+
result += str[i];
|
|
10800
|
+
}
|
|
10801
|
+
}
|
|
10802
|
+
return result;
|
|
10803
|
+
};
|
|
10804
|
+
|
|
10805
|
+
const charSets = {
|
|
10806
|
+
lowercase: 'a-z',
|
|
10807
|
+
uppercase: 'A-Z',
|
|
10808
|
+
numbers: '0-9',
|
|
10809
|
+
symbols: '!%#_|*+=',
|
|
10810
|
+
braille: '⠀-⣿',
|
|
10811
|
+
blocks: '▀-▟',
|
|
10812
|
+
shades: '░-▓',
|
|
10813
|
+
};
|
|
10814
|
+
|
|
10815
|
+
const originalTexts = new WeakMap();
|
|
10816
|
+
|
|
10817
|
+
/**
|
|
10818
|
+
* Returns a function-based tween value that scrambles the target's text content,
|
|
10819
|
+
* progressively revealing the original text.
|
|
10820
|
+
*
|
|
10821
|
+
* @param {ScrambleTextParams} [params]
|
|
10822
|
+
* @return {FunctionValue}
|
|
10823
|
+
*/
|
|
10824
|
+
const scrambleText = (params = {}) => {
|
|
10825
|
+
if (!params) params = {};
|
|
10826
|
+
const charsParam = params.chars;
|
|
10827
|
+
const easeFn = parseEase(params.ease || 'linear');
|
|
10828
|
+
const text = params.text;
|
|
10829
|
+
const fromParam = params.from;
|
|
10830
|
+
const reversed = params.reversed || false;
|
|
10831
|
+
const perturbation = params.perturbation || 0;
|
|
10832
|
+
const cursorParam = params.cursor;
|
|
10833
|
+
const cursorChars = cursorParam === true ? '_'
|
|
10834
|
+
: typeof cursorParam === 'number' ? String.fromCharCode(cursorParam)
|
|
10835
|
+
: typeof cursorParam === 'string' ? cursorParam
|
|
10836
|
+
: '';
|
|
10837
|
+
const cursorLen = cursorChars.length;
|
|
10838
|
+
const seed = params.seed || 0;
|
|
10839
|
+
const override = params.override !== undefined ? params.override : true;
|
|
10840
|
+
const revealRate = params.revealRate || 60;
|
|
10841
|
+
const interval = 1000 * globals.timeScale / revealRate;
|
|
10842
|
+
const settleDuration = params.settleDuration || 300 * globals.timeScale;
|
|
10843
|
+
const settleRate = params.settleRate || 30;
|
|
10844
|
+
const durationParam = params.duration;
|
|
10845
|
+
const revealDelayParam = params.revealDelay;
|
|
10846
|
+
const delayParam = params.delay;
|
|
10847
|
+
const onChange = params.onChange || noop;
|
|
10848
|
+
|
|
10849
|
+
return (target, index, targets, prevTween) => {
|
|
10850
|
+
const rawChars = typeof charsParam === 'function' ? charsParam(target, index, targets) : (charsParam || 'a-zA-Z0-9!%#_');
|
|
10851
|
+
const characters = expandCharRanges(charSets[rawChars] || rawChars);
|
|
10852
|
+
const totalChars = characters.length - 1;
|
|
10853
|
+
const duration = typeof durationParam === 'function' ? durationParam(target, index, targets) : durationParam;
|
|
10854
|
+
const revealDelay = typeof revealDelayParam === 'function' ? revealDelayParam(target, index, targets) : (revealDelayParam || 0);
|
|
10855
|
+
const delay = typeof delayParam === 'function' ? delayParam(target, index, targets) : (delayParam || 0);
|
|
10856
|
+
const rng = seed ? createSeededRandom(seed) : createSeededRandom();
|
|
10857
|
+
if (!originalTexts.has(target)) originalTexts.set(target, target.textContent);
|
|
10858
|
+
const startingText = prevTween ? prevTween._value : target.textContent;
|
|
10859
|
+
const targetText = text !== undefined
|
|
10860
|
+
? (typeof text === 'function' ? text(target, index, targets) : text)
|
|
10861
|
+
: prevTween ? prevTween._value
|
|
10862
|
+
: originalTexts.get(target);
|
|
10863
|
+
const settledText = targetText === ' ' || targetText === ' ' ? ' ' : targetText;
|
|
10864
|
+
const startLength = startingText === ' ' ? 0 : startingText.length;
|
|
10865
|
+
const endLength = settledText.length;
|
|
10866
|
+
const overrideChars = override === true ? characters
|
|
10867
|
+
: typeof override === 'string' && override.length > 0 ? expandCharRanges(charSets[/** @type {String} */(override)] || /** @type {String} */(override))
|
|
10868
|
+
: null;
|
|
10869
|
+
const totalOverrideChars = overrideChars ? overrideChars.length - 1 : 0;
|
|
10870
|
+
// Space override uses so the browser doesn't collapse consecutive spaces in innerHTML
|
|
10871
|
+
const overrideChar = override === ' ' ? ' ' : null;
|
|
10872
|
+
// When starting from blank, only animate the target text length to avoid padding beyond it
|
|
10873
|
+
const animLength = override === '' ? endLength : Math.max(startLength, endLength);
|
|
10874
|
+
// Compute total duration from interval spacing and settle time, or use the explicit duration
|
|
10875
|
+
const animDuration = duration > 0 ? duration : (animLength - 1) * interval + settleDuration;
|
|
10876
|
+
const computedDuration = round$1((animDuration + revealDelay) / globals.timeScale, 0) * globals.timeScale;
|
|
10877
|
+
const revealDelayRatio = revealDelay > 0 ? round$1(revealDelay / computedDuration, 12) : 0;
|
|
10878
|
+
// Auto-resolve reveal direction: shrinking text reveals from right, growing from left
|
|
10879
|
+
const resolvedFrom = fromParam === undefined || fromParam === 'auto' ? (endLength < startLength ? 'right' : 'left') : fromParam;
|
|
10880
|
+
const charOrder = new Int32Array(animLength);
|
|
10881
|
+
if (resolvedFrom === 'random') {
|
|
10882
|
+
for (let i = 0; i < animLength; i++) charOrder[i] = i;
|
|
10883
|
+
for (let i = animLength - 1; i > 0; i--) {
|
|
10884
|
+
const j = rng(0, i);
|
|
10885
|
+
const t = charOrder[i]; charOrder[i] = charOrder[j]; charOrder[j] = t;
|
|
10886
|
+
}
|
|
10887
|
+
} else {
|
|
10888
|
+
const ref = resolvedFrom === 'right' ? (override === '' || !startLength ? animLength : startLength) - 1
|
|
10889
|
+
: resolvedFrom === 'center' ? ((override === '' || !startLength ? animLength : startLength) - 1) / 2
|
|
10890
|
+
: typeof resolvedFrom === 'number' ? resolvedFrom
|
|
10891
|
+
: 0;
|
|
10892
|
+
const abs = Math.abs;
|
|
10893
|
+
const indices = new Array(animLength);
|
|
10894
|
+
for (let i = 0; i < animLength; i++) indices[i] = i;
|
|
10895
|
+
indices.sort((a, b) => abs(a - ref) - abs(b - ref));
|
|
10896
|
+
for (let i = 0; i < animLength; i++) charOrder[indices[i]] = i;
|
|
10897
|
+
}
|
|
10898
|
+
if (reversed) {
|
|
10899
|
+
const last = animLength - 1;
|
|
10900
|
+
for (let i = 0; i < animLength; i++) charOrder[i] = last - charOrder[i];
|
|
10901
|
+
}
|
|
10902
|
+
// settleRatio is the fraction of the animation each character spends in the active scrambling zone
|
|
10903
|
+
const settleRatio = round$1(settleDuration / animDuration, 12);
|
|
10904
|
+
// settleSpacing is the time gap between consecutive characters entering the active zone
|
|
10905
|
+
const settleSpacing = round$1((1 - settleRatio) / animLength, 12);
|
|
10906
|
+
const cursorZone = cursorLen * settleSpacing;
|
|
10907
|
+
// stepRatio controls how often scramble characters refresh (based on settleRate)
|
|
10908
|
+
const stepRatio = round$1(1000 * globals.timeScale / (settleRate * computedDuration), 12);
|
|
10909
|
+
// Pre-compute per-character start and settle times
|
|
10910
|
+
const charStarts = new Float32Array(animLength);
|
|
10911
|
+
const charEnds = new Float32Array(animLength);
|
|
10912
|
+
const scale = perturbation > 0 ? perturbation * settleRatio : 0;
|
|
10913
|
+
for (let c = 0; c < animLength; c++) {
|
|
10914
|
+
const so = scale > 0 ? (rng(0, 2000) - 1000) / 1000 * scale : 0;
|
|
10915
|
+
const eo = scale > 0 ? (rng(0, 2000) - 1000) / 1000 * scale : 0;
|
|
10916
|
+
charStarts[c] = charOrder[c] * settleSpacing + so;
|
|
10917
|
+
charEnds[c] = Math.ceil((charStarts[c] + settleRatio + eo) / stepRatio) * stepRatio;
|
|
10918
|
+
}
|
|
10919
|
+
// When text shrinks with non-sequential from modes, delay target settle times past all extras
|
|
10920
|
+
if (endLength < animLength && resolvedFrom !== 'left' && resolvedFrom !== 'right' && resolvedFrom !== 'random') {
|
|
10921
|
+
let maxExtraEnd = 0;
|
|
10922
|
+
for (let c = endLength; c < animLength; c++) {
|
|
10923
|
+
if (charEnds[c] > maxExtraEnd) maxExtraEnd = charEnds[c];
|
|
10924
|
+
}
|
|
10925
|
+
const targets = new Array(endLength);
|
|
10926
|
+
for (let c = 0; c < endLength; c++) targets[c] = c;
|
|
10927
|
+
targets.sort((a, b) => charOrder[a] - charOrder[b]);
|
|
10928
|
+
const targetSpacing = (1 - maxExtraEnd) / endLength;
|
|
10929
|
+
for (let i = 0; i < endLength; i++) {
|
|
10930
|
+
const revealTime = maxExtraEnd + i * targetSpacing;
|
|
10931
|
+
if (revealTime > charEnds[targets[i]]) {
|
|
10932
|
+
charEnds[targets[i]] = revealTime;
|
|
10933
|
+
}
|
|
10934
|
+
}
|
|
10935
|
+
}
|
|
10936
|
+
// charCache holds the current scramble character for each position, refreshed at settleRate
|
|
10937
|
+
const charCache = new Array(animLength);
|
|
10938
|
+
for (let c = 0; c < animLength; c++) {
|
|
10939
|
+
charCache[c] = characters[rng(0, totalChars)];
|
|
10940
|
+
}
|
|
10941
|
+
// overrideCache holds scramble characters for the starting text (override: true or custom string)
|
|
10942
|
+
const overrideCache = overrideChars ? (overrideChars === characters ? charCache : new Array(animLength)) : null;
|
|
10943
|
+
if (overrideCache && overrideCache !== charCache) {
|
|
10944
|
+
for (let c = 0; c < animLength; c++) {
|
|
10945
|
+
overrideCache[c] = overrideChar || /** @type {String} */(overrideChars)[rng(0, overrideChars.length - 1)];
|
|
10946
|
+
}
|
|
10947
|
+
}
|
|
10948
|
+
// Build the initial display text based on override mode
|
|
10949
|
+
let fillStartText = startingText;
|
|
10950
|
+
if (!prevTween) {
|
|
10951
|
+
if (override === '') {
|
|
10952
|
+
fillStartText = '';
|
|
10953
|
+
} else if (overrideChars) {
|
|
10954
|
+
fillStartText = '';
|
|
10955
|
+
for (let c = 0; c < startLength; c++) {
|
|
10956
|
+
fillStartText += startingText[c] === ' ' ? ' ' : /** @type {Array<String>} */(overrideCache)[c];
|
|
10957
|
+
}
|
|
10958
|
+
}
|
|
10959
|
+
}
|
|
10960
|
+
|
|
10961
|
+
let lastValue = -1;
|
|
10962
|
+
let lastStep = -1;
|
|
10963
|
+
let scrambled = '';
|
|
10964
|
+
const hasOverride = override !== '';
|
|
10965
|
+
const hasOverrideChars = !!overrideChars;
|
|
10966
|
+
const hasCursor = cursorLen > 0;
|
|
10967
|
+
|
|
10968
|
+
return {
|
|
10969
|
+
from: 0,
|
|
10970
|
+
to: 1,
|
|
10971
|
+
duration: computedDuration,
|
|
10972
|
+
delay: delay,
|
|
10973
|
+
ease: 'linear',
|
|
10974
|
+
modifier: (v) => {
|
|
10975
|
+
if (v === lastValue) return scrambled;
|
|
10976
|
+
lastValue = v;
|
|
10977
|
+
if (delay > 0 && v <= 0) { scrambled = startingText; return startingText; }
|
|
10978
|
+
if (v <= 0) { scrambled = fillStartText; return fillStartText; }
|
|
10979
|
+
if (v >= 1) { scrambled = settledText; return settledText; }
|
|
10980
|
+
scrambled = '';
|
|
10981
|
+
// Only refresh scramble characters when we cross a settleRate step boundary
|
|
10982
|
+
const currentStep = (v / stepRatio) | 0;
|
|
10983
|
+
const refreshChars = currentStep !== lastStep;
|
|
10984
|
+
if (refreshChars) lastStep = currentStep;
|
|
10985
|
+
// Subtract delay ratio to get the effective animation progress
|
|
10986
|
+
const linear = revealDelayRatio > 0 ? (v - revealDelayRatio) / (1 - revealDelayRatio) : v;
|
|
10987
|
+
const t = linear > 0 ? easeFn(linear) : 0;
|
|
10988
|
+
for (let c = 0; c < animLength; c++) {
|
|
10989
|
+
// Each character has its own start/end window based on its reveal order
|
|
10990
|
+
const charStart = charStarts[c];
|
|
10991
|
+
const charEnd = charEnds[c];
|
|
10992
|
+
// Settled zone: character has finished its transition
|
|
10993
|
+
if (t >= charEnd) {
|
|
10994
|
+
if (c < endLength) scrambled += settledText[c];
|
|
10995
|
+
continue;
|
|
10996
|
+
}
|
|
10997
|
+
// Pre-transition zone: reveal wave hasn't reached this character yet
|
|
10998
|
+
if (t <= 0 || t < charStart) {
|
|
10999
|
+
if (hasOverride && c < startLength) {
|
|
11000
|
+
if (hasOverrideChars) {
|
|
11001
|
+
if (startingText[c] === ' ') {
|
|
11002
|
+
scrambled += ' ';
|
|
11003
|
+
} else {
|
|
11004
|
+
if (refreshChars) /** @type {Array<String>} */(overrideCache)[c] = overrideChar || /** @type {String} */(overrideChars)[rng(0, totalOverrideChars)];
|
|
11005
|
+
scrambled += /** @type {Array<String>} */(overrideCache)[c];
|
|
11006
|
+
}
|
|
11007
|
+
} else {
|
|
11008
|
+
// Default (override: false): show the original starting text
|
|
11009
|
+
scrambled += startingText[c];
|
|
11010
|
+
}
|
|
11011
|
+
}
|
|
11012
|
+
continue;
|
|
11013
|
+
}
|
|
11014
|
+
// Active zone: character is between charStart and charEnd
|
|
11015
|
+
const isSpace = (c < endLength && settledText[c] === ' ') || (c < startLength && startingText[c] === ' ');
|
|
11016
|
+
if (isSpace) {
|
|
11017
|
+
scrambled += ' ';
|
|
11018
|
+
} else if (hasCursor && t - charStart < cursorZone) {
|
|
11019
|
+
// Cursor sub-zone: show cursor character based on position within cursor width
|
|
11020
|
+
scrambled += cursorChars[cursorLen - 1 - (((t - charStart) / settleSpacing) | 0)];
|
|
11021
|
+
} else {
|
|
11022
|
+
// Scramble zone: show cycling random characters
|
|
11023
|
+
if (refreshChars) charCache[c] = characters[rng(0, totalChars)];
|
|
11024
|
+
scrambled += charCache[c];
|
|
11025
|
+
}
|
|
11026
|
+
}
|
|
11027
|
+
if (refreshChars) onChange(scrambled, t);
|
|
11028
|
+
return scrambled;
|
|
11029
|
+
}
|
|
11030
|
+
}
|
|
11031
|
+
}
|
|
11032
|
+
};
|
|
11033
|
+
|
|
10408
11034
|
var index = /*#__PURE__*/Object.freeze({
|
|
10409
11035
|
__proto__: null,
|
|
10410
11036
|
TextSplitter: TextSplitter,
|
|
11037
|
+
scrambleText: scrambleText,
|
|
10411
11038
|
split: split,
|
|
10412
11039
|
splitText: splitText
|
|
10413
11040
|
});
|
|
10414
11041
|
|
|
10415
|
-
export { registerTargets as $, Animatable, AutoLayout, Draggable, JSAnimation, Scope, ScrollObserver, Spring, TextSplitter, Timeline, Timer, WAAPIAnimation, animate, clamp, cleanInlineStyles, createAnimatable, createDraggable, createDrawable, createLayout, createMotionPath, createScope, createSeededRandom, createSpring, createTimeline, createTimer, cubicBezier, damp, degToRad, eases, index$3 as easings, engine, get, irregular, keepTime, lerp, linear, mapRange, morphTo, onScroll, padEnd, padStart, radToDeg, random, randomPick, remove, round, roundPad, scrollContainers, set, shuffle, snap, split, splitText, spring, stagger, steps, index$1 as svg, sync, index as text, index$2 as utils, waapi, wrap };
|
|
11042
|
+
export { registerTargets as $, Animatable, AutoLayout, Draggable, JSAnimation, Scope, ScrollObserver, Spring, TextSplitter, Timeline, Timer, WAAPIAnimation, addChild, animate, clamp, cleanInlineStyles, createAnimatable, createDraggable, createDrawable, createLayout, createMotionPath, createScope, createSeededRandom, createSpring, createTimeline, createTimer, cubicBezier, damp, degToRad, eases, index$3 as easings, engine, forEachChildren, get, globals, irregular, keepTime, lerp, linear, mapRange, morphTo, onScroll, padEnd, padStart, radToDeg, random, randomPick, remove, removeChild, round, roundPad, scrambleText, scrollContainers, set, shuffle, snap, split, splitText, spring, stagger, steps, index$1 as svg, sync, index as text, index$2 as utils, waapi, wrap };
|