animejs 4.3.6 → 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 +8 -11
- package/dist/bundles/anime.esm.js +1033 -421
- package/dist/bundles/anime.esm.min.js +2 -2
- package/dist/bundles/anime.umd.js +1038 -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 +29 -25
- package/dist/modules/layout/layout.d.ts +4 -3
- package/dist/modules/layout/layout.js +30 -26
- 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.6', 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;
|
|
1123
|
+
}
|
|
1124
|
+
pos++;
|
|
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
|
+
}
|
|
1082
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);
|
|
1083
1155
|
}
|
|
1084
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;
|
|
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
|
-
);
|
|
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();
|
|
4071
4151
|
}
|
|
4072
|
-
removeTargetsFromRenderable(
|
|
4073
|
-
targetsArray,
|
|
4074
|
-
/** @type {Renderable} */(renderable),
|
|
4075
|
-
propertyName
|
|
4076
|
-
);
|
|
4077
|
-
return targetsArray;
|
|
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;
|
|
@@ -7845,6 +8101,7 @@ const waapi = {
|
|
|
7845
8101
|
|
|
7846
8102
|
/**
|
|
7847
8103
|
* @typedef {Object} LayoutSpecificAnimationParams
|
|
8104
|
+
* @property {Number|String} [id]
|
|
7848
8105
|
* @property {Number|FunctionValue} [delay]
|
|
7849
8106
|
* @property {Number|FunctionValue} [duration]
|
|
7850
8107
|
* @property {EasingParam|FunctionValue} [ease]
|
|
@@ -7887,7 +8144,7 @@ const waapi = {
|
|
|
7887
8144
|
* @property {String} id
|
|
7888
8145
|
* @property {DOMTarget} $el
|
|
7889
8146
|
* @property {Number} index
|
|
7890
|
-
* @property {
|
|
8147
|
+
* @property {Array<DOMTarget>} targets
|
|
7891
8148
|
* @property {Number} delay
|
|
7892
8149
|
* @property {Number} duration
|
|
7893
8150
|
* @property {EasingParam} ease
|
|
@@ -8031,7 +8288,7 @@ const createNode = ($el, parentNode, state, recycledNode) => {
|
|
|
8031
8288
|
node.$measure = $el;
|
|
8032
8289
|
node.id = dataId;
|
|
8033
8290
|
node.index = 0;
|
|
8034
|
-
node.
|
|
8291
|
+
node.targets = null;
|
|
8035
8292
|
node.delay = 0;
|
|
8036
8293
|
node.duration = 0;
|
|
8037
8294
|
node.ease = null;
|
|
@@ -8217,12 +8474,12 @@ const updateNodeProperties = (node, props) => {
|
|
|
8217
8474
|
* @param {LayoutAnimationTimingsParams} params
|
|
8218
8475
|
*/
|
|
8219
8476
|
const updateNodeTimingParams = (node, params) => {
|
|
8220
|
-
const easeFunctionResult = getFunctionValue(params.ease, node.$el, node.index, node.
|
|
8477
|
+
const easeFunctionResult = getFunctionValue(params.ease, node.$el, node.index, node.targets, null, null);
|
|
8221
8478
|
const keyEasing = isFnc(easeFunctionResult) ? easeFunctionResult : params.ease;
|
|
8222
8479
|
const hasSpring = !isUnd(keyEasing) && !isUnd(/** @type {Spring} */(keyEasing).ease);
|
|
8223
8480
|
node.ease = hasSpring ? /** @type {Spring} */(keyEasing).ease : keyEasing;
|
|
8224
|
-
node.duration = hasSpring ? /** @type {Spring} */(keyEasing).settlingDuration : getFunctionValue(params.duration, node.$el, node.index, node.
|
|
8225
|
-
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);
|
|
8226
8483
|
};
|
|
8227
8484
|
|
|
8228
8485
|
/**
|
|
@@ -8595,10 +8852,12 @@ class LayoutSnapshot {
|
|
|
8595
8852
|
|
|
8596
8853
|
const inRootNodeIds = new Set();
|
|
8597
8854
|
// Update index and total for inital timing calculation
|
|
8598
|
-
let index = 0
|
|
8855
|
+
let index = 0;
|
|
8856
|
+
const allNodeTargets = [];
|
|
8857
|
+
this.nodes.forEach((node) => { allNodeTargets.push(node.$el); });
|
|
8599
8858
|
this.nodes.forEach((node, id) => {
|
|
8600
8859
|
node.index = index++;
|
|
8601
|
-
node.
|
|
8860
|
+
node.targets = allNodeTargets;
|
|
8602
8861
|
// Track ids of nodes that belong to the current root to filter detached matches
|
|
8603
8862
|
if (node && node.measuredIsInsideRoot) {
|
|
8604
8863
|
inRootNodeIds.add(id);
|
|
@@ -8710,8 +8969,8 @@ class AutoLayout {
|
|
|
8710
8969
|
this.params = params;
|
|
8711
8970
|
/** @type {DOMTarget} */
|
|
8712
8971
|
this.root = /** @type {DOMTarget} */(registerTargets(root)[0]);
|
|
8713
|
-
/** @type {Number} */
|
|
8714
|
-
this.id = layoutId++;
|
|
8972
|
+
/** @type {Number|String} */
|
|
8973
|
+
this.id = params.id || layoutId++;
|
|
8715
8974
|
/** @type {LayoutChildrenParam} */
|
|
8716
8975
|
this.children = params.children || '*';
|
|
8717
8976
|
/** @type {Boolean} */
|
|
@@ -8834,7 +9093,9 @@ class AutoLayout {
|
|
|
8834
9093
|
duration: setValue(params.duration, this.params.duration),
|
|
8835
9094
|
};
|
|
8836
9095
|
/** @type {TimelineParams} */
|
|
8837
|
-
const tlParams = {
|
|
9096
|
+
const tlParams = {
|
|
9097
|
+
id: this.id
|
|
9098
|
+
};
|
|
8838
9099
|
const onComplete = setValue(params.onComplete, this.params.onComplete);
|
|
8839
9100
|
const onPause = setValue(params.onPause, this.params.onPause);
|
|
8840
9101
|
for (let name in defaults) {
|
|
@@ -8848,7 +9109,8 @@ class AutoLayout {
|
|
|
8848
9109
|
}
|
|
8849
9110
|
tlParams.onComplete = () => {
|
|
8850
9111
|
const ap = /** @type {ScrollObserver} */(params.autoplay);
|
|
8851
|
-
const
|
|
9112
|
+
const ed = globals.editor;
|
|
9113
|
+
const isScrollControled = (ap && ap.linked) || (ed && ed.showPanel);
|
|
8852
9114
|
if (isScrollControled) {
|
|
8853
9115
|
if (onComplete) onComplete(this.timeline);
|
|
8854
9116
|
return;
|
|
@@ -9047,41 +9309,39 @@ class AutoLayout {
|
|
|
9047
9309
|
animatedParent = animatedParent.parentNode;
|
|
9048
9310
|
}
|
|
9049
9311
|
|
|
9050
|
-
const animatingTotal = animating.length;
|
|
9051
|
-
|
|
9052
9312
|
// Root is always animated first in sync with the first child (animating.length is the total of children)
|
|
9053
9313
|
if (node === rootNode) {
|
|
9054
9314
|
node.index = 0;
|
|
9055
|
-
node.
|
|
9315
|
+
node.targets = animating;
|
|
9056
9316
|
updateNodeTimingParams(node, animationTimings);
|
|
9057
9317
|
} else if (node.isEntering) {
|
|
9058
9318
|
node.index = animatedParent ? animatedParent.index : enteringIndex;
|
|
9059
|
-
node.
|
|
9319
|
+
node.targets = animatedParent ? animating : entering;
|
|
9060
9320
|
updateNodeTimingParams(node, enterFromTimings);
|
|
9061
9321
|
enteringIndex++;
|
|
9062
9322
|
} else if (node.isLeaving) {
|
|
9063
9323
|
node.index = animatedParent ? animatedParent.index : leavingIndex;
|
|
9064
|
-
node.
|
|
9324
|
+
node.targets = animatedParent ? animating : leaving;
|
|
9065
9325
|
leavingIndex++;
|
|
9066
9326
|
updateNodeTimingParams(node, leaveToTimings);
|
|
9067
9327
|
} else if (node.isTarget) {
|
|
9068
9328
|
node.index = animatingIndex++;
|
|
9069
|
-
node.
|
|
9329
|
+
node.targets = animating;
|
|
9070
9330
|
updateNodeTimingParams(node, animationTimings);
|
|
9071
9331
|
} else {
|
|
9072
9332
|
node.index = animatedParent ? animatedParent.index : 0;
|
|
9073
|
-
node.
|
|
9333
|
+
node.targets = animating;
|
|
9074
9334
|
updateNodeTimingParams(node, swapAtTimings);
|
|
9075
9335
|
}
|
|
9076
9336
|
|
|
9077
9337
|
// Make sure the old state node has its inex and total values up to date for valid "from" function values calculation
|
|
9078
9338
|
oldStateNode.index = node.index;
|
|
9079
|
-
oldStateNode.
|
|
9339
|
+
oldStateNode.targets = node.targets;
|
|
9080
9340
|
|
|
9081
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
|
|
9082
9342
|
for (let prop in nodeProperties) {
|
|
9083
|
-
nodeProperties[prop] = getFunctionValue(nodeProperties[prop], $el, node.index, node.
|
|
9084
|
-
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);
|
|
9085
9345
|
}
|
|
9086
9346
|
|
|
9087
9347
|
// Use a 1px tolerance to detect dimensions changes to prevent width / height animations on barelly visible elements
|
|
@@ -9307,8 +9567,8 @@ class AutoLayout {
|
|
|
9307
9567
|
}
|
|
9308
9568
|
$el.style.transform = oldState.getComputedValue($el, 'transform');
|
|
9309
9569
|
if (animatedSwap.includes($el)) {
|
|
9310
|
-
node.ease = getFunctionValue(swapAtParams.ease, $el, node.index, node.
|
|
9311
|
-
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);
|
|
9312
9572
|
}
|
|
9313
9573
|
}
|
|
9314
9574
|
this.transformAnimation = waapi.animate(transformed, {
|
|
@@ -9323,7 +9583,7 @@ class AutoLayout {
|
|
|
9323
9583
|
if (!animatedSwap.includes($el)) return newValue;
|
|
9324
9584
|
const oldValue = oldState.getComputedValue($el, 'transform');
|
|
9325
9585
|
const node = newState.getNode($el);
|
|
9326
|
-
return [oldValue, getFunctionValue(swapAtProps.transform, $el, node.index, node.
|
|
9586
|
+
return [oldValue, getFunctionValue(swapAtProps.transform, $el, node.index, node.targets, null, null), newValue]
|
|
9327
9587
|
},
|
|
9328
9588
|
autoplay: false,
|
|
9329
9589
|
// persist: true,
|
|
@@ -9380,10 +9640,13 @@ const chain = fn => {
|
|
|
9380
9640
|
const result = fn(...args);
|
|
9381
9641
|
return new Proxy(noop, {
|
|
9382
9642
|
apply: (_, __, [v]) => result(v),
|
|
9383
|
-
get: (_, prop) =>
|
|
9384
|
-
|
|
9385
|
-
return (/**@
|
|
9386
|
-
|
|
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
|
+
}
|
|
9387
9650
|
});
|
|
9388
9651
|
}
|
|
9389
9652
|
};
|
|
@@ -9594,24 +9857,28 @@ const shuffle = items => {
|
|
|
9594
9857
|
* @param {StaggerParams} [params]
|
|
9595
9858
|
* @return {StaggerFunction<Number>}
|
|
9596
9859
|
*/
|
|
9860
|
+
|
|
9597
9861
|
/**
|
|
9598
9862
|
* @overload
|
|
9599
9863
|
* @param {String} val
|
|
9600
9864
|
* @param {StaggerParams} [params]
|
|
9601
9865
|
* @return {StaggerFunction<String>}
|
|
9602
9866
|
*/
|
|
9867
|
+
|
|
9603
9868
|
/**
|
|
9604
9869
|
* @overload
|
|
9605
9870
|
* @param {[Number, Number]} val
|
|
9606
9871
|
* @param {StaggerParams} [params]
|
|
9607
9872
|
* @return {StaggerFunction<Number>}
|
|
9608
9873
|
*/
|
|
9874
|
+
|
|
9609
9875
|
/**
|
|
9610
9876
|
* @overload
|
|
9611
9877
|
* @param {[String, String]} val
|
|
9612
9878
|
* @param {StaggerParams} [params]
|
|
9613
9879
|
* @return {StaggerFunction<String>}
|
|
9614
9880
|
*/
|
|
9881
|
+
|
|
9615
9882
|
/**
|
|
9616
9883
|
* @param {Number|String|[Number, Number]|[String, String]} val The staggered value or range
|
|
9617
9884
|
* @param {StaggerParams} [params] The stagger parameters
|
|
@@ -9620,6 +9887,7 @@ const shuffle = items => {
|
|
|
9620
9887
|
const stagger = (val, params = {}) => {
|
|
9621
9888
|
let values = [];
|
|
9622
9889
|
let maxValue = 0;
|
|
9890
|
+
let cachedOffset;
|
|
9623
9891
|
const from = params.from;
|
|
9624
9892
|
const reversed = params.reversed;
|
|
9625
9893
|
const ease = params.ease;
|
|
@@ -9627,12 +9895,14 @@ const stagger = (val, params = {}) => {
|
|
|
9627
9895
|
const hasSpring = hasEasing && !isUnd(/** @type {Spring} */(ease).ease);
|
|
9628
9896
|
const staggerEase = hasSpring ? /** @type {Spring} */(ease).ease : hasEasing ? parseEase(ease) : null;
|
|
9629
9897
|
const grid = params.grid;
|
|
9898
|
+
const autoGrid = grid === true;
|
|
9630
9899
|
const axis = params.axis;
|
|
9631
9900
|
const customTotal = params.total;
|
|
9632
9901
|
const fromFirst = isUnd(from) || from === 0 || from === 'first';
|
|
9633
9902
|
const fromCenter = from === 'center';
|
|
9634
9903
|
const fromLast = from === 'last';
|
|
9635
9904
|
const fromRandom = from === 'random';
|
|
9905
|
+
const fromArr = isArr(from);
|
|
9636
9906
|
const isRange = isArr(val);
|
|
9637
9907
|
const useProp = params.use;
|
|
9638
9908
|
const val1 = isRange ? parseNumber(val[0]) : parseNumber(val);
|
|
@@ -9640,40 +9910,129 @@ const stagger = (val, params = {}) => {
|
|
|
9640
9910
|
const unitMatch = unitsExecRgx.exec((isRange ? val[1] : val) + emptyString);
|
|
9641
9911
|
const start = params.start || 0 + (isRange ? val1 : 0);
|
|
9642
9912
|
let fromIndex = fromFirst ? 0 : isNum(from) ? from : 0;
|
|
9643
|
-
return (target, i, t, tl) => {
|
|
9913
|
+
return (target, i, t, _, tl) => {
|
|
9644
9914
|
const [ registeredTarget ] = registerTargets(target);
|
|
9645
|
-
const total = isUnd(customTotal) ? t : customTotal;
|
|
9915
|
+
const total = isUnd(customTotal) ? t.length : customTotal;
|
|
9646
9916
|
const customIndex = !isUnd(useProp) ? isFnc(useProp) ? useProp(registeredTarget, i, total) : getOriginalAnimatableValue(registeredTarget, useProp) : false;
|
|
9647
9917
|
const staggerIndex = isNum(customIndex) || isStr(customIndex) && isNum(+customIndex) ? +customIndex : i;
|
|
9648
9918
|
if (fromCenter) fromIndex = (total - 1) / 2;
|
|
9649
9919
|
if (fromLast) fromIndex = total - 1;
|
|
9650
9920
|
if (!values.length) {
|
|
9651
|
-
|
|
9652
|
-
|
|
9653
|
-
|
|
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
|
+
}
|
|
9654
9992
|
} else {
|
|
9655
|
-
|
|
9656
|
-
|
|
9657
|
-
|
|
9658
|
-
|
|
9659
|
-
|
|
9660
|
-
|
|
9661
|
-
|
|
9662
|
-
|
|
9663
|
-
|
|
9664
|
-
|
|
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
|
+
}
|
|
9665
10022
|
}
|
|
9666
|
-
maxValue = max(...values);
|
|
9667
10023
|
}
|
|
10024
|
+
maxValue = max(...values);
|
|
9668
10025
|
if (staggerEase) values = values.map(val => staggerEase(val / maxValue) * maxValue);
|
|
9669
10026
|
if (reversed) values = values.map(val => axis ? (val < 0) ? val * -1 : -val : abs(maxValue - val));
|
|
9670
10027
|
if (fromRandom) values = shuffle(values);
|
|
9671
10028
|
}
|
|
9672
10029
|
const spacing = isRange ? (val2 - val1) / maxValue : val1;
|
|
9673
|
-
|
|
10030
|
+
if (isUnd(cachedOffset)) {
|
|
10031
|
+
cachedOffset = tl ? parseTimelinePosition(tl, isUnd(params.start) ? tl.iterationDuration : start) : /** @type {Number} */(start);
|
|
10032
|
+
}
|
|
9674
10033
|
/** @type {String|Number} */
|
|
9675
|
-
let output =
|
|
9676
|
-
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));
|
|
9677
10036
|
if (unitMatch) output = `${output}${unitMatch[2]}`;
|
|
9678
10037
|
return output;
|
|
9679
10038
|
}
|
|
@@ -9682,11 +10041,13 @@ const stagger = (val, params = {}) => {
|
|
|
9682
10041
|
var index$2 = /*#__PURE__*/Object.freeze({
|
|
9683
10042
|
__proto__: null,
|
|
9684
10043
|
$: registerTargets,
|
|
10044
|
+
addChild: addChild,
|
|
9685
10045
|
clamp: clamp,
|
|
9686
10046
|
cleanInlineStyles: cleanInlineStyles,
|
|
9687
10047
|
createSeededRandom: createSeededRandom,
|
|
9688
10048
|
damp: damp,
|
|
9689
10049
|
degToRad: degToRad,
|
|
10050
|
+
forEachChildren: forEachChildren,
|
|
9690
10051
|
get: get,
|
|
9691
10052
|
keepTime: keepTime,
|
|
9692
10053
|
lerp: lerp,
|
|
@@ -9697,6 +10058,7 @@ var index$2 = /*#__PURE__*/Object.freeze({
|
|
|
9697
10058
|
random: random,
|
|
9698
10059
|
randomPick: randomPick,
|
|
9699
10060
|
remove: remove,
|
|
10061
|
+
removeChild: removeChild,
|
|
9700
10062
|
round: round,
|
|
9701
10063
|
roundPad: roundPad,
|
|
9702
10064
|
set: set,
|
|
@@ -9896,7 +10258,7 @@ const createDrawable = (selector, start = 0, end = 0) => {
|
|
|
9896
10258
|
* @param {Number} [precision]
|
|
9897
10259
|
* @return {FunctionValue}
|
|
9898
10260
|
*/
|
|
9899
|
-
const morphTo = (path2, precision = .33) => ($path1) => {
|
|
10261
|
+
const morphTo = (path2, precision = .33) => ($path1, index, total, prevTween) => {
|
|
9900
10262
|
const tagName1 = ($path1.tagName || '').toLowerCase();
|
|
9901
10263
|
if (!tagName1.match(/^(path|polygon|polyline)$/)) {
|
|
9902
10264
|
throw new Error(`Can't morph a <${$path1.tagName}> SVG element. Use <path>, <polygon> or <polyline>.`);
|
|
@@ -9911,7 +10273,7 @@ const morphTo = (path2, precision = .33) => ($path1) => {
|
|
|
9911
10273
|
}
|
|
9912
10274
|
const isPath = $path1.tagName === 'path';
|
|
9913
10275
|
const separator = isPath ? ' ' : ',';
|
|
9914
|
-
const previousPoints =
|
|
10276
|
+
const previousPoints = prevTween ? prevTween._value : null;
|
|
9915
10277
|
if (previousPoints) $path1.setAttribute(isPath ? 'd' : 'points', previousPoints);
|
|
9916
10278
|
|
|
9917
10279
|
let v1 = '', v2 = '';
|
|
@@ -9933,8 +10295,6 @@ const morphTo = (path2, precision = .33) => ($path1) => {
|
|
|
9933
10295
|
}
|
|
9934
10296
|
}
|
|
9935
10297
|
|
|
9936
|
-
$path1[morphPointsSymbol] = v2;
|
|
9937
|
-
|
|
9938
10298
|
return [v1, v2];
|
|
9939
10299
|
};
|
|
9940
10300
|
|
|
@@ -10120,7 +10480,7 @@ const processHTMLTemplate = (htmlTemplate, store, node, $parentFragment, type, d
|
|
|
10120
10480
|
*/
|
|
10121
10481
|
class TextSplitter {
|
|
10122
10482
|
/**
|
|
10123
|
-
* @param {
|
|
10483
|
+
* @param {Element|NodeList|String|Array<Element>} target
|
|
10124
10484
|
* @param {TextSplitterParams} [parameters]
|
|
10125
10485
|
*/
|
|
10126
10486
|
constructor(target, parameters = {}) {
|
|
@@ -10192,11 +10552,11 @@ class TextSplitter {
|
|
|
10192
10552
|
}
|
|
10193
10553
|
|
|
10194
10554
|
/**
|
|
10195
|
-
* @param {(...args: any[]) => Tickable | (() => void)} effect
|
|
10555
|
+
* @param {(...args: any[]) => Tickable | (() => void) | void} effect
|
|
10196
10556
|
* @return this
|
|
10197
10557
|
*/
|
|
10198
10558
|
addEffect(effect) {
|
|
10199
|
-
if (!isFnc(effect))
|
|
10559
|
+
if (!isFnc(effect)) { console.warn('Effect must return a function.'); return this; }
|
|
10200
10560
|
const refreshableEffect = keepTime(effect);
|
|
10201
10561
|
this.effects.push(refreshableEffect);
|
|
10202
10562
|
if (this.ready) this.effectsCleanups[this.effects.length - 1] = refreshableEffect(this);
|
|
@@ -10402,7 +10762,7 @@ class TextSplitter {
|
|
|
10402
10762
|
}
|
|
10403
10763
|
|
|
10404
10764
|
/**
|
|
10405
|
-
* @param {
|
|
10765
|
+
* @param {Element|NodeList|String|Array<Element>} target
|
|
10406
10766
|
* @param {TextSplitterParams} [parameters]
|
|
10407
10767
|
* @return {TextSplitter}
|
|
10408
10768
|
*/
|
|
@@ -10420,11 +10780,263 @@ const split = (target, parameters) => {
|
|
|
10420
10780
|
return new TextSplitter(target, parameters);
|
|
10421
10781
|
};
|
|
10422
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
|
+
|
|
10423
11034
|
var index = /*#__PURE__*/Object.freeze({
|
|
10424
11035
|
__proto__: null,
|
|
10425
11036
|
TextSplitter: TextSplitter,
|
|
11037
|
+
scrambleText: scrambleText,
|
|
10426
11038
|
split: split,
|
|
10427
11039
|
splitText: splitText
|
|
10428
11040
|
});
|
|
10429
11041
|
|
|
10430
|
-
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 };
|