animejs 4.3.5 → 4.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -12
- package/dist/bundles/anime.esm.js +1048 -421
- package/dist/bundles/anime.esm.min.js +2 -2
- package/dist/bundles/anime.umd.js +1053 -421
- package/dist/bundles/anime.umd.min.js +2 -2
- package/dist/modules/animatable/animatable.cjs +1 -1
- package/dist/modules/animatable/animatable.js +2 -2
- package/dist/modules/animatable/index.cjs +1 -1
- package/dist/modules/animatable/index.js +1 -1
- package/dist/modules/animation/additive.cjs +1 -1
- package/dist/modules/animation/additive.js +1 -1
- package/dist/modules/animation/animation.cjs +38 -16
- package/dist/modules/animation/animation.d.ts +2 -2
- package/dist/modules/animation/animation.js +42 -20
- package/dist/modules/animation/composition.cjs +1 -1
- package/dist/modules/animation/composition.js +3 -3
- package/dist/modules/animation/index.cjs +1 -1
- package/dist/modules/animation/index.js +1 -1
- package/dist/modules/core/clock.cjs +1 -1
- package/dist/modules/core/clock.js +1 -1
- package/dist/modules/core/colors.cjs +1 -1
- package/dist/modules/core/colors.js +1 -1
- package/dist/modules/core/consts.cjs +3 -9
- package/dist/modules/core/consts.d.ts +1 -5
- package/dist/modules/core/consts.js +4 -8
- package/dist/modules/core/globals.cjs +16 -5
- package/dist/modules/core/globals.d.ts +22 -1
- package/dist/modules/core/globals.js +18 -6
- package/dist/modules/core/helpers.cjs +7 -10
- package/dist/modules/core/helpers.js +8 -11
- package/dist/modules/core/render.cjs +66 -63
- package/dist/modules/core/render.js +68 -65
- package/dist/modules/core/styles.cjs +53 -32
- package/dist/modules/core/styles.d.ts +1 -0
- package/dist/modules/core/styles.js +55 -35
- package/dist/modules/core/targets.cjs +1 -1
- package/dist/modules/core/targets.js +1 -1
- package/dist/modules/core/transforms.cjs +129 -13
- package/dist/modules/core/transforms.d.ts +1 -0
- package/dist/modules/core/transforms.js +130 -15
- package/dist/modules/core/units.cjs +1 -1
- package/dist/modules/core/units.js +1 -1
- package/dist/modules/core/values.cjs +68 -8
- package/dist/modules/core/values.d.ts +5 -2
- package/dist/modules/core/values.js +69 -11
- package/dist/modules/draggable/draggable.cjs +1 -1
- package/dist/modules/draggable/draggable.js +1 -1
- package/dist/modules/draggable/index.cjs +1 -1
- package/dist/modules/draggable/index.js +1 -1
- package/dist/modules/easings/cubic-bezier/index.cjs +1 -1
- package/dist/modules/easings/cubic-bezier/index.js +1 -1
- package/dist/modules/easings/eases/index.cjs +1 -1
- package/dist/modules/easings/eases/index.js +1 -1
- package/dist/modules/easings/eases/parser.cjs +1 -1
- package/dist/modules/easings/eases/parser.js +1 -1
- package/dist/modules/easings/index.cjs +1 -1
- package/dist/modules/easings/index.js +1 -1
- package/dist/modules/easings/irregular/index.cjs +1 -1
- package/dist/modules/easings/irregular/index.js +1 -1
- package/dist/modules/easings/linear/index.cjs +1 -1
- package/dist/modules/easings/linear/index.js +1 -1
- package/dist/modules/easings/none.cjs +1 -1
- package/dist/modules/easings/none.js +1 -1
- package/dist/modules/easings/spring/index.cjs +1 -1
- package/dist/modules/easings/spring/index.js +1 -1
- package/dist/modules/easings/steps/index.cjs +1 -1
- package/dist/modules/easings/steps/index.js +1 -1
- package/dist/modules/engine/engine.cjs +1 -1
- package/dist/modules/engine/engine.js +1 -1
- package/dist/modules/engine/index.cjs +1 -1
- package/dist/modules/engine/index.js +1 -1
- package/dist/modules/events/index.cjs +1 -1
- package/dist/modules/events/index.js +1 -1
- package/dist/modules/events/scroll.cjs +1 -1
- package/dist/modules/events/scroll.js +1 -1
- package/dist/modules/index.cjs +9 -1
- package/dist/modules/index.d.ts +1 -0
- package/dist/modules/index.js +4 -1
- package/dist/modules/layout/index.cjs +1 -1
- package/dist/modules/layout/index.js +1 -1
- package/dist/modules/layout/layout.cjs +47 -24
- package/dist/modules/layout/layout.d.ts +4 -3
- package/dist/modules/layout/layout.js +48 -25
- package/dist/modules/scope/index.cjs +1 -1
- package/dist/modules/scope/index.js +1 -1
- package/dist/modules/scope/scope.cjs +1 -1
- package/dist/modules/scope/scope.js +1 -1
- package/dist/modules/svg/drawable.cjs +1 -1
- package/dist/modules/svg/drawable.js +1 -1
- package/dist/modules/svg/helpers.cjs +1 -1
- package/dist/modules/svg/helpers.js +1 -1
- package/dist/modules/svg/index.cjs +1 -1
- package/dist/modules/svg/index.js +1 -1
- package/dist/modules/svg/morphto.cjs +3 -6
- package/dist/modules/svg/morphto.js +3 -6
- package/dist/modules/svg/motionpath.cjs +1 -1
- package/dist/modules/svg/motionpath.js +1 -1
- package/dist/modules/text/index.cjs +3 -1
- package/dist/modules/text/index.d.ts +1 -0
- package/dist/modules/text/index.js +2 -1
- package/dist/modules/text/scramble.cjs +272 -0
- package/dist/modules/text/scramble.d.ts +3 -0
- package/dist/modules/text/scramble.js +270 -0
- package/dist/modules/text/split.cjs +5 -5
- package/dist/modules/text/split.d.ts +5 -5
- package/dist/modules/text/split.js +5 -5
- package/dist/modules/timeline/index.cjs +1 -1
- package/dist/modules/timeline/index.js +1 -1
- package/dist/modules/timeline/position.cjs +1 -1
- package/dist/modules/timeline/position.js +1 -1
- package/dist/modules/timeline/timeline.cjs +36 -18
- package/dist/modules/timeline/timeline.d.ts +6 -5
- package/dist/modules/timeline/timeline.js +37 -19
- package/dist/modules/timer/index.cjs +1 -1
- package/dist/modules/timer/index.js +1 -1
- package/dist/modules/timer/timer.cjs +8 -12
- package/dist/modules/timer/timer.d.ts +2 -0
- package/dist/modules/timer/timer.js +9 -13
- package/dist/modules/types/index.d.ts +76 -8
- package/dist/modules/utils/chainable.cjs +8 -5
- package/dist/modules/utils/chainable.js +8 -5
- package/dist/modules/utils/index.cjs +5 -1
- package/dist/modules/utils/index.d.ts +1 -0
- package/dist/modules/utils/index.js +2 -1
- package/dist/modules/utils/number.cjs +1 -1
- package/dist/modules/utils/number.js +1 -1
- package/dist/modules/utils/random.cjs +1 -1
- package/dist/modules/utils/random.js +1 -1
- package/dist/modules/utils/stagger.cjs +117 -20
- package/dist/modules/utils/stagger.js +118 -21
- package/dist/modules/utils/target.cjs +1 -1
- package/dist/modules/utils/target.js +1 -1
- package/dist/modules/utils/time.cjs +5 -3
- package/dist/modules/utils/time.d.ts +1 -1
- package/dist/modules/utils/time.js +5 -3
- package/dist/modules/waapi/composition.cjs +1 -1
- package/dist/modules/waapi/composition.js +1 -1
- package/dist/modules/waapi/index.cjs +1 -1
- package/dist/modules/waapi/index.js +1 -1
- package/dist/modules/waapi/waapi.cjs +19 -20
- package/dist/modules/waapi/waapi.js +20 -21
- package/package.json +2 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Anime.js - UMD 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
|
/**
|
|
@@ -647,7 +670,7 @@
|
|
|
647
670
|
// TODO: Do we need to check if we're running inside a worker ?
|
|
648
671
|
const isBrowser = typeof window !== 'undefined';
|
|
649
672
|
|
|
650
|
-
/** @typedef {Window & {AnimeJS: Array}
|
|
673
|
+
/** @typedef {Window & {AnimeJS: Array}|null} AnimeJSWindow
|
|
651
674
|
|
|
652
675
|
/** @type {AnimeJSWindow} */
|
|
653
676
|
const win = isBrowser ? /** @type {AnimeJSWindow} */(/** @type {unknown} */(window)) : null;
|
|
@@ -694,7 +717,6 @@
|
|
|
694
717
|
const isDomSymbol = Symbol();
|
|
695
718
|
const isSvgSymbol = Symbol();
|
|
696
719
|
const transformsSymbol = Symbol();
|
|
697
|
-
const morphPointsSymbol = Symbol();
|
|
698
720
|
const proxyTargetSymbol = Symbol();
|
|
699
721
|
|
|
700
722
|
// Numbers
|
|
@@ -718,6 +740,7 @@
|
|
|
718
740
|
})();
|
|
719
741
|
|
|
720
742
|
const validTransforms = [
|
|
743
|
+
'perspective',
|
|
721
744
|
'translateX',
|
|
722
745
|
'translateY',
|
|
723
746
|
'translateZ',
|
|
@@ -732,9 +755,6 @@
|
|
|
732
755
|
'skew',
|
|
733
756
|
'skewX',
|
|
734
757
|
'skewY',
|
|
735
|
-
'matrix',
|
|
736
|
-
'matrix3d',
|
|
737
|
-
'perspective',
|
|
738
758
|
];
|
|
739
759
|
|
|
740
760
|
const transformsFragmentStrings = /*#__PURE__*/ validTransforms.reduce((a, v) => ({...a, [v]: v + '('}), {});
|
|
@@ -757,12 +777,23 @@
|
|
|
757
777
|
// export const unitsExecRgx = /^([-+]?\d*\.?\d+(?:[eE][-+]?\d+)?)+([a-z]+|%)$/i;
|
|
758
778
|
const unitsExecRgx = /^([-+]?\d*\.?\d+(?:e[-+]?\d+)?)([a-z]+|%)$/i;
|
|
759
779
|
const lowerCaseRgx = /([a-z])([A-Z])/g;
|
|
760
|
-
const transformsExecRgx = /(\w+)(\([^)]+\)+)/g; // Match inline transforms with cacl() values, returns the value wrapped in ()
|
|
761
780
|
const relativeValuesExecRgx = /(\*=|\+=|-=)/;
|
|
762
781
|
const cssVariableMatchRgx = /var\(\s*(--[\w-]+)(?:\s*,\s*([^)]+))?\s*\)/;
|
|
763
782
|
|
|
764
783
|
|
|
765
784
|
|
|
785
|
+
/**
|
|
786
|
+
* @typedef {Object} EditorGlobals
|
|
787
|
+
* @property {boolean} showPanel
|
|
788
|
+
* @property {boolean} synced
|
|
789
|
+
* @property {Function} addAnimation
|
|
790
|
+
* @property {Function} addTimeline
|
|
791
|
+
* @property {Function} addTimelineChild
|
|
792
|
+
* @property {Function} resolveStagger
|
|
793
|
+
* @property {Object|null} _head
|
|
794
|
+
* @property {Object|null} _tail
|
|
795
|
+
*/
|
|
796
|
+
|
|
766
797
|
/** @type {DefaultsParams} */
|
|
767
798
|
const defaults = {
|
|
768
799
|
id: null,
|
|
@@ -806,11 +837,11 @@
|
|
|
806
837
|
timeScale: 1,
|
|
807
838
|
/** @type {Number} */
|
|
808
839
|
tickThreshold: 200,
|
|
840
|
+
/** @type {EditorGlobals|null} */
|
|
841
|
+
editor: null,
|
|
809
842
|
};
|
|
810
843
|
|
|
811
|
-
const
|
|
812
|
-
|
|
813
|
-
const globalVersions = { version: '4.3.5', engine: null };
|
|
844
|
+
const globalVersions = { version: '4.4.0', engine: null };
|
|
814
845
|
|
|
815
846
|
if (isBrowser) {
|
|
816
847
|
if (!win.AnimeJS) win.AnimeJS = [];
|
|
@@ -926,8 +957,6 @@
|
|
|
926
957
|
*/
|
|
927
958
|
const clamp$1 = (v, min, max) => v < min ? min : v > max ? max : v;
|
|
928
959
|
|
|
929
|
-
const powCache = {};
|
|
930
|
-
|
|
931
960
|
/**
|
|
932
961
|
* Rounds a number to specified decimal places
|
|
933
962
|
*
|
|
@@ -935,13 +964,12 @@
|
|
|
935
964
|
* @param {Number} decimalLength - Number of decimal places
|
|
936
965
|
* @return {Number}
|
|
937
966
|
*/
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
};
|
|
967
|
+
const round$1 = (v, decimalLength) => {
|
|
968
|
+
if (decimalLength < 0) return v;
|
|
969
|
+
if (!decimalLength) return _round(v);
|
|
970
|
+
const p = 10 ** decimalLength;
|
|
971
|
+
return _round(v * p) / p;
|
|
972
|
+
};
|
|
945
973
|
|
|
946
974
|
/**
|
|
947
975
|
* Snaps a value to nearest increment or array value
|
|
@@ -1072,28 +1100,143 @@
|
|
|
1072
1100
|
*/
|
|
1073
1101
|
const parseInlineTransforms = (target, propName, animationInlineStyles) => {
|
|
1074
1102
|
const inlineTransforms = target.style.transform;
|
|
1075
|
-
let inlinedStylesPropertyValue;
|
|
1076
1103
|
if (inlineTransforms) {
|
|
1077
1104
|
const cachedTransforms = target[transformsSymbol];
|
|
1078
|
-
let
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1105
|
+
let pos = 0;
|
|
1106
|
+
const len = inlineTransforms.length;
|
|
1107
|
+
let fullTranslateValue;
|
|
1108
|
+
while (pos < len) {
|
|
1109
|
+
// Skip whitespace
|
|
1110
|
+
while (pos < len && inlineTransforms.charCodeAt(pos) === 32) pos++;
|
|
1111
|
+
if (pos >= len) break;
|
|
1112
|
+
// Read function name
|
|
1113
|
+
const nameStart = pos;
|
|
1114
|
+
while (pos < len && inlineTransforms.charCodeAt(pos) !== 40) pos++;
|
|
1115
|
+
if (pos >= len) break;
|
|
1116
|
+
const name = inlineTransforms.substring(nameStart, pos);
|
|
1117
|
+
// Scan to closing paren, recording top-level comma positions
|
|
1118
|
+
let depth = 1;
|
|
1119
|
+
const valueStart = pos + 1;
|
|
1120
|
+
let c1 = -1, c2 = -1;
|
|
1121
|
+
pos++;
|
|
1122
|
+
while (pos < len && depth > 0) {
|
|
1123
|
+
const c = inlineTransforms.charCodeAt(pos);
|
|
1124
|
+
if (c === 40) depth++;
|
|
1125
|
+
else if (c === 41) depth--;
|
|
1126
|
+
else if (c === 44 && depth === 1) {
|
|
1127
|
+
if (c1 === -1) c1 = pos;
|
|
1128
|
+
else if (c2 === -1) c2 = pos;
|
|
1088
1129
|
}
|
|
1130
|
+
pos++;
|
|
1089
1131
|
}
|
|
1132
|
+
const valueEnd = pos - 1;
|
|
1133
|
+
// Decompose multi-arg functions into individual axis properties
|
|
1134
|
+
if (name === 'translate' || name === 'translate3d') {
|
|
1135
|
+
if (c1 === -1) {
|
|
1136
|
+
cachedTransforms.translateX = inlineTransforms.substring(valueStart, valueEnd).trim();
|
|
1137
|
+
} else {
|
|
1138
|
+
cachedTransforms.translateX = inlineTransforms.substring(valueStart, c1).trim();
|
|
1139
|
+
if (c2 === -1) {
|
|
1140
|
+
cachedTransforms.translateY = inlineTransforms.substring(c1 + 1, valueEnd).trim();
|
|
1141
|
+
} else {
|
|
1142
|
+
cachedTransforms.translateY = inlineTransforms.substring(c1 + 1, c2).trim();
|
|
1143
|
+
cachedTransforms.translateZ = inlineTransforms.substring(c2 + 1, valueEnd).trim();
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
1146
|
+
fullTranslateValue = inlineTransforms.substring(valueStart, valueEnd);
|
|
1147
|
+
} else if (name === 'scale' || name === 'scale3d') {
|
|
1148
|
+
if (c1 === -1) {
|
|
1149
|
+
cachedTransforms.scale = inlineTransforms.substring(valueStart, valueEnd).trim();
|
|
1150
|
+
} else {
|
|
1151
|
+
cachedTransforms.scaleX = inlineTransforms.substring(valueStart, c1).trim();
|
|
1152
|
+
if (c2 === -1) {
|
|
1153
|
+
cachedTransforms.scaleY = inlineTransforms.substring(c1 + 1, valueEnd).trim();
|
|
1154
|
+
} else {
|
|
1155
|
+
cachedTransforms.scaleY = inlineTransforms.substring(c1 + 1, c2).trim();
|
|
1156
|
+
cachedTransforms.scaleZ = inlineTransforms.substring(c2 + 1, valueEnd).trim();
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1159
|
+
} else {
|
|
1160
|
+
cachedTransforms[name] = inlineTransforms.substring(valueStart, valueEnd);
|
|
1161
|
+
}
|
|
1162
|
+
}
|
|
1163
|
+
// Resolve the requested property from the cache
|
|
1164
|
+
if (propName === 'translate3d' && fullTranslateValue) {
|
|
1165
|
+
if (animationInlineStyles) animationInlineStyles[propName] = fullTranslateValue;
|
|
1166
|
+
return fullTranslateValue;
|
|
1167
|
+
}
|
|
1168
|
+
const cached = cachedTransforms[propName];
|
|
1169
|
+
if (!isUnd(cached)) {
|
|
1170
|
+
if (animationInlineStyles) animationInlineStyles[propName] = cached;
|
|
1171
|
+
return cached;
|
|
1090
1172
|
}
|
|
1091
1173
|
}
|
|
1092
|
-
return
|
|
1174
|
+
return propName === 'translate3d' ? '0px, 0px, 0px' :
|
|
1175
|
+
propName === 'rotate3d' ? '0, 0, 0, 0deg' :
|
|
1093
1176
|
stringStartsWith(propName, 'scale') ? '1' :
|
|
1094
1177
|
stringStartsWith(propName, 'rotate') || stringStartsWith(propName, 'skew') ? '0deg' : '0px';
|
|
1095
1178
|
};
|
|
1096
1179
|
|
|
1180
|
+
/**
|
|
1181
|
+
* Builds a CSS transform string from the target's cached transform properties.
|
|
1182
|
+
* Iterates validTransforms in order (perspective > translate > rotate > scale > skew > matrix).
|
|
1183
|
+
* When adjacent axis properties are all present, emits a shorter shorthand (translateX + translateY -> translate(x, y))
|
|
1184
|
+
* The index is advanced past consumed properties so they are not emitted twice.
|
|
1185
|
+
* Properties without a grouping partner (e.g. translateY alone, scaleZ alone) emit individually.
|
|
1186
|
+
*
|
|
1187
|
+
* @param {Record<String, String>} props
|
|
1188
|
+
* @return {String}
|
|
1189
|
+
*/
|
|
1190
|
+
const buildTransformString = (props) => {
|
|
1191
|
+
let str = emptyString;
|
|
1192
|
+
for (let i = 0, l = validTransforms.length; i < l; i++) {
|
|
1193
|
+
const key = validTransforms[i];
|
|
1194
|
+
const val = props[key];
|
|
1195
|
+
if (val !== undefined) {
|
|
1196
|
+
// Group translateX with adjacent translateY / translateZ
|
|
1197
|
+
if (key === 'translateX') {
|
|
1198
|
+
const next = props.translateY;
|
|
1199
|
+
if (next !== undefined) {
|
|
1200
|
+
const next2 = props.translateZ;
|
|
1201
|
+
if (next2 !== undefined) {
|
|
1202
|
+
str += `translate3d(${val},${next},${next2}) `;
|
|
1203
|
+
i += 2;
|
|
1204
|
+
} else {
|
|
1205
|
+
str += `translate(${val},${next}) `;
|
|
1206
|
+
i += 1;
|
|
1207
|
+
}
|
|
1208
|
+
continue;
|
|
1209
|
+
}
|
|
1210
|
+
}
|
|
1211
|
+
// Group scaleX with adjacent scaleY / scaleZ (only when standalone scale is absent)
|
|
1212
|
+
if (key === 'scaleX' && props.scale === undefined) {
|
|
1213
|
+
const next = props.scaleY;
|
|
1214
|
+
if (next !== undefined) {
|
|
1215
|
+
const next2 = props.scaleZ;
|
|
1216
|
+
if (next2 !== undefined) {
|
|
1217
|
+
str += `scale3d(${val},${next},${next2}) `;
|
|
1218
|
+
i += 2;
|
|
1219
|
+
} else {
|
|
1220
|
+
str += `scale(${val},${next}) `;
|
|
1221
|
+
i += 1;
|
|
1222
|
+
}
|
|
1223
|
+
continue;
|
|
1224
|
+
}
|
|
1225
|
+
}
|
|
1226
|
+
// All other properties: emit individually using pre-built fragment string
|
|
1227
|
+
str += `${transformsFragmentStrings[key]}${val}) `;
|
|
1228
|
+
}
|
|
1229
|
+
// Preserve non-animatable rotate3d in correct position (after rotateZ, before scale)
|
|
1230
|
+
if (key === 'rotateZ') {
|
|
1231
|
+
if (props.rotate3d !== undefined) str += `rotate3d(${props.rotate3d}) `;
|
|
1232
|
+
}
|
|
1233
|
+
}
|
|
1234
|
+
// Preserve non-animatable matrix/matrix3d from inline styles
|
|
1235
|
+
if (props.matrix !== undefined) str += `matrix(${props.matrix}) `;
|
|
1236
|
+
if (props.matrix3d !== undefined) str += `matrix3d(${props.matrix3d}) `;
|
|
1237
|
+
return str;
|
|
1238
|
+
};
|
|
1239
|
+
|
|
1097
1240
|
|
|
1098
1241
|
|
|
1099
1242
|
/**
|
|
@@ -1195,15 +1338,16 @@
|
|
|
1195
1338
|
* @param {TweenPropValue} value
|
|
1196
1339
|
* @param {Target} target
|
|
1197
1340
|
* @param {Number} index
|
|
1198
|
-
* @param {
|
|
1199
|
-
* @param {Object}
|
|
1341
|
+
* @param {TargetsArray} targets
|
|
1342
|
+
* @param {Object|null} store
|
|
1343
|
+
* @param {Tween|null} prevTween
|
|
1200
1344
|
* @return {any}
|
|
1201
1345
|
*/
|
|
1202
|
-
const getFunctionValue = (value, target, index,
|
|
1346
|
+
const getFunctionValue = (value, target, index, targets, store, prevTween) => {
|
|
1203
1347
|
let func;
|
|
1204
1348
|
if (isFnc(value)) {
|
|
1205
1349
|
func = () => {
|
|
1206
|
-
const computed = /** @type {Function} */(value)(target, index,
|
|
1350
|
+
const computed = /** @type {Function} */(value)(target, index, targets, prevTween);
|
|
1207
1351
|
// Fallback to 0 if the function returns undefined / NaN / null / false / 0
|
|
1208
1352
|
return !isNaN(+computed) ? +computed : computed || 0;
|
|
1209
1353
|
};
|
|
@@ -1270,9 +1414,17 @@
|
|
|
1270
1414
|
*/
|
|
1271
1415
|
const getOriginalAnimatableValue = (target, propName, tweenType, animationInlineStyles) => {
|
|
1272
1416
|
const type = !isUnd(tweenType) ? tweenType : getTweenType(target, propName);
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1417
|
+
if (type === tweenTypes.OBJECT) {
|
|
1418
|
+
const value = target[propName];
|
|
1419
|
+
if (value && animationInlineStyles) animationInlineStyles[propName] = value;
|
|
1420
|
+
return value || 0;
|
|
1421
|
+
}
|
|
1422
|
+
if (type === tweenTypes.ATTRIBUTE) {
|
|
1423
|
+
const value = /** @type {DOMTarget} */(target).getAttribute(propName);
|
|
1424
|
+
if (value && animationInlineStyles) animationInlineStyles[propName] = value;
|
|
1425
|
+
return value;
|
|
1426
|
+
}
|
|
1427
|
+
return type === tweenTypes.TRANSFORM ? parseInlineTransforms(/** @type {DOMTarget} */(target), propName, animationInlineStyles) :
|
|
1276
1428
|
type === tweenTypes.CSS_VAR ? getCSSValue(/** @type {DOMTarget} */(target), propName, animationInlineStyles).trimStart() :
|
|
1277
1429
|
getCSSValue(/** @type {DOMTarget} */(target), propName, animationInlineStyles);
|
|
1278
1430
|
};
|
|
@@ -1374,6 +1526,54 @@
|
|
|
1374
1526
|
|
|
1375
1527
|
const decomposedOriginalValue = createDecomposedValueTargetObject();
|
|
1376
1528
|
|
|
1529
|
+
/**
|
|
1530
|
+
* @param {Tween} tween
|
|
1531
|
+
* @param {Number} progress
|
|
1532
|
+
* @param {Number} precision
|
|
1533
|
+
* @return {String}
|
|
1534
|
+
*/
|
|
1535
|
+
const composeColorValue = (tween, progress, precision) => {
|
|
1536
|
+
const mod = tween._modifier;
|
|
1537
|
+
const fn = tween._fromNumbers;
|
|
1538
|
+
const tn = tween._toNumbers;
|
|
1539
|
+
const r = round$1(clamp$1(/** @type {Number} */(mod(lerp$1(fn[0], tn[0], progress))), 0, 255), 0);
|
|
1540
|
+
const g = round$1(clamp$1(/** @type {Number} */(mod(lerp$1(fn[1], tn[1], progress))), 0, 255), 0);
|
|
1541
|
+
const b = round$1(clamp$1(/** @type {Number} */(mod(lerp$1(fn[2], tn[2], progress))), 0, 255), 0);
|
|
1542
|
+
const a = clamp$1(/** @type {Number} */(mod(round$1(lerp$1(fn[3], tn[3], progress), precision))), 0, 1);
|
|
1543
|
+
if (tween._composition !== compositionTypes.none) {
|
|
1544
|
+
const ns = tween._numbers;
|
|
1545
|
+
ns[0] = r;
|
|
1546
|
+
ns[1] = g;
|
|
1547
|
+
ns[2] = b;
|
|
1548
|
+
ns[3] = a;
|
|
1549
|
+
}
|
|
1550
|
+
return `rgba(${r},${g},${b},${a})`;
|
|
1551
|
+
};
|
|
1552
|
+
|
|
1553
|
+
/**
|
|
1554
|
+
* @param {Tween} tween
|
|
1555
|
+
* @param {Number} progress
|
|
1556
|
+
* @param {Number} precision
|
|
1557
|
+
* @return {String}
|
|
1558
|
+
*/
|
|
1559
|
+
const composeComplexValue = (tween, progress, precision) => {
|
|
1560
|
+
const mod = tween._modifier;
|
|
1561
|
+
const fn = tween._fromNumbers;
|
|
1562
|
+
const tn = tween._toNumbers;
|
|
1563
|
+
const ts = tween._strings;
|
|
1564
|
+
const hasComposition = tween._composition !== compositionTypes.none;
|
|
1565
|
+
let v = ts[0];
|
|
1566
|
+
for (let j = 0, l = tn.length; j < l; j++) {
|
|
1567
|
+
const n = /** @type {Number} */(mod(round$1(lerp$1(fn[j], tn[j], progress), precision)));
|
|
1568
|
+
const s = ts[j + 1];
|
|
1569
|
+
v += `${s ? n + s : n}`;
|
|
1570
|
+
if (hasComposition) {
|
|
1571
|
+
tween._numbers[j] = n;
|
|
1572
|
+
}
|
|
1573
|
+
}
|
|
1574
|
+
return v;
|
|
1575
|
+
};
|
|
1576
|
+
|
|
1377
1577
|
|
|
1378
1578
|
|
|
1379
1579
|
|
|
@@ -1402,7 +1602,6 @@
|
|
|
1402
1602
|
const _hasChildren = tickable._hasChildren;
|
|
1403
1603
|
const tickableDelay = tickable._delay;
|
|
1404
1604
|
const tickablePrevAbsoluteTime = tickable._currentTime; // TODO: rename ._currentTime to ._absoluteCurrentTime
|
|
1405
|
-
|
|
1406
1605
|
const tickableEndTime = tickableDelay + iterationDuration;
|
|
1407
1606
|
const tickableAbsoluteTime = time - tickableDelay;
|
|
1408
1607
|
const tickablePrevTime = clamp$1(tickablePrevAbsoluteTime, -tickableDelay, duration);
|
|
@@ -1534,30 +1733,9 @@
|
|
|
1534
1733
|
number = /** @type {Number} */(tweenModifier(round$1(lerp$1(tween._fromNumber, tween._toNumber, tweenProgress), tweenPrecision)));
|
|
1535
1734
|
value = `${number}${tween._unit}`;
|
|
1536
1735
|
} else if (tweenValueType === valueTypes.COLOR) {
|
|
1537
|
-
|
|
1538
|
-
const tn = tween._toNumbers;
|
|
1539
|
-
const r = round$1(clamp$1(/** @type {Number} */(tweenModifier(lerp$1(fn[0], tn[0], tweenProgress))), 0, 255), 0);
|
|
1540
|
-
const g = round$1(clamp$1(/** @type {Number} */(tweenModifier(lerp$1(fn[1], tn[1], tweenProgress))), 0, 255), 0);
|
|
1541
|
-
const b = round$1(clamp$1(/** @type {Number} */(tweenModifier(lerp$1(fn[2], tn[2], tweenProgress))), 0, 255), 0);
|
|
1542
|
-
const a = clamp$1(/** @type {Number} */(tweenModifier(round$1(lerp$1(fn[3], tn[3], tweenProgress), tweenPrecision))), 0, 1);
|
|
1543
|
-
value = `rgba(${r},${g},${b},${a})`;
|
|
1544
|
-
if (tweenHasComposition) {
|
|
1545
|
-
const ns = tween._numbers;
|
|
1546
|
-
ns[0] = r;
|
|
1547
|
-
ns[1] = g;
|
|
1548
|
-
ns[2] = b;
|
|
1549
|
-
ns[3] = a;
|
|
1550
|
-
}
|
|
1736
|
+
value = composeColorValue(tween, tweenProgress, tweenPrecision);
|
|
1551
1737
|
} else if (tweenValueType === valueTypes.COMPLEX) {
|
|
1552
|
-
value = tween
|
|
1553
|
-
for (let j = 0, l = tween._toNumbers.length; j < l; j++) {
|
|
1554
|
-
const n = /** @type {Number} */(tweenModifier(round$1(lerp$1(tween._fromNumbers[j], tween._toNumbers[j], tweenProgress), tweenPrecision)));
|
|
1555
|
-
const s = tween._strings[j + 1];
|
|
1556
|
-
value += `${s ? n + s : n}`;
|
|
1557
|
-
if (tweenHasComposition) {
|
|
1558
|
-
tween._numbers[j] = n;
|
|
1559
|
-
}
|
|
1560
|
-
}
|
|
1738
|
+
value = composeComplexValue(tween, tweenProgress, tweenPrecision);
|
|
1561
1739
|
}
|
|
1562
1740
|
|
|
1563
1741
|
// For additive tweens and Animatables
|
|
@@ -1600,14 +1778,8 @@
|
|
|
1600
1778
|
|
|
1601
1779
|
}
|
|
1602
1780
|
|
|
1603
|
-
// NOTE: Possible improvement: Use translate(x,y) / translate3d(x,y,z) syntax
|
|
1604
|
-
// to reduce memory usage on string composition
|
|
1605
1781
|
if (tweenTransformsNeedUpdate && tween._renderTransforms) {
|
|
1606
|
-
|
|
1607
|
-
for (let key in tweenTargetTransformsProperties) {
|
|
1608
|
-
str += `${transformsFragmentStrings[key]}${tweenTargetTransformsProperties[key]}) `;
|
|
1609
|
-
}
|
|
1610
|
-
tweenStyle.transform = str;
|
|
1782
|
+
tweenStyle.transform = buildTransformString(tweenTargetTransformsProperties);
|
|
1611
1783
|
tweenTransformsNeedUpdate = 0;
|
|
1612
1784
|
}
|
|
1613
1785
|
|
|
@@ -1664,6 +1836,50 @@
|
|
|
1664
1836
|
return hasRendered;
|
|
1665
1837
|
};
|
|
1666
1838
|
|
|
1839
|
+
// Shared context for extracted forEachChildren callbacks in tick()
|
|
1840
|
+
// Avoids closure allocation every frame
|
|
1841
|
+
|
|
1842
|
+
let renderCtxChildrenTime = 0;
|
|
1843
|
+
let renderCtxTlFps = 0;
|
|
1844
|
+
let renderCtxTickTime = 0;
|
|
1845
|
+
let renderCtxTickMode = 0;
|
|
1846
|
+
let renderCtxMuteCallbacks = 0;
|
|
1847
|
+
let renderCtxInternalRender = 0;
|
|
1848
|
+
let renderCtxChildrenHasRendered = 0;
|
|
1849
|
+
let renderCtxChildrenHaveCompleted = true;
|
|
1850
|
+
let loopCtxIsRunningBackwards = false;
|
|
1851
|
+
let loopCtxIterationDuration = 0;
|
|
1852
|
+
let loopCtxMuteCallbacks = 0;
|
|
1853
|
+
|
|
1854
|
+
/** @param {JSAnimation} child */
|
|
1855
|
+
const tickLoopChild = (child) => {
|
|
1856
|
+
if (!loopCtxIsRunningBackwards) {
|
|
1857
|
+
// Force an internal render to trigger the callbacks if the child has not completed on loop
|
|
1858
|
+
if (!child.completed && !child.backwards && child._currentTime < child.iterationDuration) {
|
|
1859
|
+
render(child, loopCtxIterationDuration, loopCtxMuteCallbacks, 1, tickModes.FORCE);
|
|
1860
|
+
}
|
|
1861
|
+
// Reset their began and completed flags to allow retrigering callbacks on the next iteration
|
|
1862
|
+
child.began = false;
|
|
1863
|
+
child.completed = false;
|
|
1864
|
+
} else {
|
|
1865
|
+
const childDuration = child.duration;
|
|
1866
|
+
const childStartTime = child._offset + child._delay;
|
|
1867
|
+
const childEndTime = childStartTime + childDuration;
|
|
1868
|
+
// Triggers the onComplete callback on reverse for children on the edges of the timeline
|
|
1869
|
+
if (!loopCtxMuteCallbacks && childDuration <= minValue && (!childStartTime || childEndTime === loopCtxIterationDuration)) {
|
|
1870
|
+
child.onComplete(child);
|
|
1871
|
+
}
|
|
1872
|
+
}
|
|
1873
|
+
};
|
|
1874
|
+
|
|
1875
|
+
/** @param {JSAnimation} child */
|
|
1876
|
+
const tickRenderChild = (child) => {
|
|
1877
|
+
const childTime = round$1((renderCtxChildrenTime - child._offset) * child._speed, 12); // Rounding is needed when using seconds
|
|
1878
|
+
const childTickMode = child._fps < renderCtxTlFps ? child.requestTick(renderCtxTickTime) : renderCtxTickMode;
|
|
1879
|
+
renderCtxChildrenHasRendered += render(child, childTime, renderCtxMuteCallbacks, renderCtxInternalRender, childTickMode);
|
|
1880
|
+
if (!child.completed && renderCtxChildrenHaveCompleted) renderCtxChildrenHaveCompleted = false;
|
|
1881
|
+
};
|
|
1882
|
+
|
|
1667
1883
|
/**
|
|
1668
1884
|
* @param {Tickable} tickable
|
|
1669
1885
|
* @param {Number} time
|
|
@@ -1680,45 +1896,30 @@
|
|
|
1680
1896
|
const tlIsRunningBackwards = tl.backwards;
|
|
1681
1897
|
const tlChildrenTime = internalRender ? time : tl._iterationTime;
|
|
1682
1898
|
const tlCildrenTickTime = now();
|
|
1683
|
-
|
|
1684
1899
|
let tlChildrenHasRendered = 0;
|
|
1685
1900
|
let tlChildrenHaveCompleted = true;
|
|
1686
|
-
|
|
1687
1901
|
// If the timeline has looped forward, we need to manually triggers children skipped callbacks
|
|
1688
1902
|
if (!internalRender && tl._currentIteration !== _currentIteration) {
|
|
1689
1903
|
const tlIterationDuration = tl.iterationDuration;
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
render(child, tlIterationDuration, muteCallbacks, 1, tickModes.FORCE);
|
|
1695
|
-
}
|
|
1696
|
-
// Reset their began and completed flags to allow retrigering callbacks on the next iteration
|
|
1697
|
-
child.began = false;
|
|
1698
|
-
child.completed = false;
|
|
1699
|
-
} else {
|
|
1700
|
-
const childDuration = child.duration;
|
|
1701
|
-
const childStartTime = child._offset + child._delay;
|
|
1702
|
-
const childEndTime = childStartTime + childDuration;
|
|
1703
|
-
// Triggers the onComplete callback on reverse for children on the edges of the timeline
|
|
1704
|
-
if (!muteCallbacks && childDuration <= minValue && (!childStartTime || childEndTime === tlIterationDuration)) {
|
|
1705
|
-
child.onComplete(child);
|
|
1706
|
-
}
|
|
1707
|
-
}
|
|
1708
|
-
});
|
|
1904
|
+
loopCtxIsRunningBackwards = tlIsRunningBackwards;
|
|
1905
|
+
loopCtxIterationDuration = tlIterationDuration;
|
|
1906
|
+
loopCtxMuteCallbacks = muteCallbacks;
|
|
1907
|
+
forEachChildren(tl, tickLoopChild);
|
|
1709
1908
|
if (!muteCallbacks) tl.onLoop(/** @type {CallbackArgument} */(tl));
|
|
1710
1909
|
}
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1910
|
+
renderCtxChildrenTime = tlChildrenTime;
|
|
1911
|
+
renderCtxTlFps = tl._fps;
|
|
1912
|
+
renderCtxTickTime = tlCildrenTickTime;
|
|
1913
|
+
renderCtxTickMode = tickMode;
|
|
1914
|
+
renderCtxMuteCallbacks = muteCallbacks;
|
|
1915
|
+
renderCtxInternalRender = internalRender;
|
|
1916
|
+
renderCtxChildrenHasRendered = 0;
|
|
1917
|
+
renderCtxChildrenHaveCompleted = true;
|
|
1918
|
+
forEachChildren(tl, tickRenderChild, tlIsRunningBackwards);
|
|
1919
|
+
tlChildrenHasRendered = renderCtxChildrenHasRendered;
|
|
1920
|
+
tlChildrenHaveCompleted = renderCtxChildrenHaveCompleted;
|
|
1719
1921
|
// Renders on timeline are triggered by its children so it needs to be set after rendering the children
|
|
1720
1922
|
if (!muteCallbacks && tlChildrenHasRendered) tl.onRender(/** @type {CallbackArgument} */(tl));
|
|
1721
|
-
|
|
1722
1923
|
// Triggers the timeline onComplete() once all chindren all completed and the current time has reached the end
|
|
1723
1924
|
if ((tlChildrenHaveCompleted || tlIsRunningBackwards) && tl._currentTime >= tl.duration) {
|
|
1724
1925
|
// Make sure the paused flag is false in case it has been skipped in the render function
|
|
@@ -1772,59 +1973,78 @@
|
|
|
1772
1973
|
/**
|
|
1773
1974
|
* @template {Renderable} T
|
|
1774
1975
|
* @param {T} renderable
|
|
1976
|
+
* @param {Boolean} [inlineStylesOnly]
|
|
1775
1977
|
* @return {T}
|
|
1776
1978
|
*/
|
|
1777
|
-
const
|
|
1778
|
-
// Allow
|
|
1979
|
+
const revertValues = (renderable, inlineStylesOnly = false) => {
|
|
1980
|
+
// Allow revertValues() to be called on timelines
|
|
1779
1981
|
if (renderable._hasChildren) {
|
|
1780
|
-
forEachChildren(renderable,
|
|
1982
|
+
forEachChildren(renderable, (/** @type {Renderable} */child) => revertValues(child, inlineStylesOnly), true);
|
|
1781
1983
|
} else {
|
|
1782
1984
|
const animation = /** @type {JSAnimation} */(renderable);
|
|
1783
1985
|
animation.pause();
|
|
1784
1986
|
forEachChildren(animation, (/** @type {Tween} */tween) => {
|
|
1785
1987
|
const tweenProperty = tween.property;
|
|
1786
1988
|
const tweenTarget = tween.target;
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
if (
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
if (!Object.keys(cachedTransforms).length) {
|
|
1800
|
-
targetStyle.removeProperty('transform');
|
|
1989
|
+
const tweenType = tween._tweenType;
|
|
1990
|
+
const originalInlinedValue = tween._inlineValue;
|
|
1991
|
+
const tweenHadNoInlineValue = isNil(originalInlinedValue) || originalInlinedValue === emptyString;
|
|
1992
|
+
if (tweenType === tweenTypes.OBJECT) {
|
|
1993
|
+
if (!inlineStylesOnly && !tweenHadNoInlineValue) {
|
|
1994
|
+
tweenTarget[tweenProperty] = originalInlinedValue;
|
|
1995
|
+
}
|
|
1996
|
+
} else if (tweenTarget[isDomSymbol]) {
|
|
1997
|
+
if (tweenType === tweenTypes.ATTRIBUTE) {
|
|
1998
|
+
if (!inlineStylesOnly) {
|
|
1999
|
+
if (tweenHadNoInlineValue) {
|
|
2000
|
+
/** @type {DOMTarget} */(tweenTarget).removeAttribute(tweenProperty);
|
|
1801
2001
|
} else {
|
|
1802
|
-
|
|
1803
|
-
for (let key in cachedTransforms) {
|
|
1804
|
-
str += transformsFragmentStrings[key] + cachedTransforms[key] + ') ';
|
|
1805
|
-
}
|
|
1806
|
-
targetStyle.transform = str;
|
|
2002
|
+
/** @type {DOMTarget} */(tweenTarget).setAttribute(tweenProperty, /** @type {String} */(originalInlinedValue));
|
|
1807
2003
|
}
|
|
1808
2004
|
}
|
|
1809
2005
|
} else {
|
|
1810
|
-
|
|
1811
|
-
|
|
2006
|
+
const targetStyle = /** @type {DOMTarget} */(tweenTarget).style;
|
|
2007
|
+
if (tweenType === tweenTypes.TRANSFORM) {
|
|
2008
|
+
const cachedTransforms = tweenTarget[transformsSymbol];
|
|
2009
|
+
if (tweenHadNoInlineValue) {
|
|
2010
|
+
delete cachedTransforms[tweenProperty];
|
|
2011
|
+
} else {
|
|
2012
|
+
cachedTransforms[tweenProperty] = originalInlinedValue;
|
|
2013
|
+
}
|
|
2014
|
+
if (tween._renderTransforms) {
|
|
2015
|
+
if (!Object.keys(cachedTransforms).length) {
|
|
2016
|
+
targetStyle.removeProperty('transform');
|
|
2017
|
+
} else {
|
|
2018
|
+
targetStyle.transform = buildTransformString(cachedTransforms);
|
|
2019
|
+
}
|
|
2020
|
+
}
|
|
1812
2021
|
} else {
|
|
1813
|
-
|
|
2022
|
+
if (tweenHadNoInlineValue) {
|
|
2023
|
+
targetStyle.removeProperty(toLowerCase(tweenProperty));
|
|
2024
|
+
} else {
|
|
2025
|
+
targetStyle[tweenProperty] = originalInlinedValue;
|
|
2026
|
+
}
|
|
1814
2027
|
}
|
|
1815
2028
|
}
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
2029
|
+
}
|
|
2030
|
+
if (tweenTarget[isDomSymbol] && animation._tail === tween) {
|
|
2031
|
+
animation.targets.forEach(t => {
|
|
2032
|
+
if (t.getAttribute && t.getAttribute('style') === emptyString) {
|
|
2033
|
+
t.removeAttribute('style');
|
|
2034
|
+
} });
|
|
1822
2035
|
}
|
|
1823
2036
|
});
|
|
1824
2037
|
}
|
|
1825
2038
|
return renderable;
|
|
1826
2039
|
};
|
|
1827
2040
|
|
|
2041
|
+
/**
|
|
2042
|
+
* @template {Renderable} T
|
|
2043
|
+
* @param {T} renderable
|
|
2044
|
+
* @return {T}
|
|
2045
|
+
*/
|
|
2046
|
+
const cleanInlineStyles = renderable => revertValues(renderable, true);
|
|
2047
|
+
|
|
1828
2048
|
|
|
1829
2049
|
|
|
1830
2050
|
/*
|
|
@@ -2509,6 +2729,9 @@
|
|
|
2509
2729
|
|
|
2510
2730
|
let timerId = 0;
|
|
2511
2731
|
|
|
2732
|
+
/** @param {Timer} prev @param {Timer} child */
|
|
2733
|
+
const sortByPriority = (prev, child) => prev._priority > child._priority;
|
|
2734
|
+
|
|
2512
2735
|
/**
|
|
2513
2736
|
* Base class used to create Timers, Animations and Timelines
|
|
2514
2737
|
*/
|
|
@@ -2535,6 +2758,7 @@
|
|
|
2535
2758
|
autoplay,
|
|
2536
2759
|
frameRate,
|
|
2537
2760
|
playbackRate,
|
|
2761
|
+
priority,
|
|
2538
2762
|
onComplete,
|
|
2539
2763
|
onLoop,
|
|
2540
2764
|
onPause,
|
|
@@ -2556,16 +2780,6 @@
|
|
|
2556
2780
|
/** @type {Number} */(timerLoop) < 0 ? Infinity :
|
|
2557
2781
|
/** @type {Number} */(timerLoop) + 1;
|
|
2558
2782
|
|
|
2559
|
-
if (devTools) {
|
|
2560
|
-
const isInfinite = timerIterationCount === Infinity;
|
|
2561
|
-
const registered = devTools.register(this, parameters, isInfinite);
|
|
2562
|
-
if (registered && isInfinite) {
|
|
2563
|
-
const minIterations = alternate ? 2 : 1;
|
|
2564
|
-
const iterations = parent ? devTools.maxNestedInfiniteLoops : devTools.maxInfiniteLoops;
|
|
2565
|
-
timerIterationCount = Math.max(iterations, minIterations);
|
|
2566
|
-
}
|
|
2567
|
-
}
|
|
2568
|
-
|
|
2569
2783
|
let offsetPosition = 0;
|
|
2570
2784
|
|
|
2571
2785
|
if (parent) {
|
|
@@ -2649,6 +2863,8 @@
|
|
|
2649
2863
|
this._fps = setValue(frameRate, timerDefaults.frameRate);
|
|
2650
2864
|
/** @type {Number} */
|
|
2651
2865
|
this._speed = setValue(playbackRate, timerDefaults.playbackRate);
|
|
2866
|
+
/** @type {Number} */
|
|
2867
|
+
this._priority = +setValue(priority, 1);
|
|
2652
2868
|
}
|
|
2653
2869
|
|
|
2654
2870
|
get cancelled() {
|
|
@@ -2793,7 +3009,7 @@
|
|
|
2793
3009
|
tick(this, minValue, 0, 0, tickModes.FORCE);
|
|
2794
3010
|
} else {
|
|
2795
3011
|
if (!this._running) {
|
|
2796
|
-
addChild(engine, this);
|
|
3012
|
+
addChild(engine, this, sortByPriority);
|
|
2797
3013
|
engine._hasChildren = true;
|
|
2798
3014
|
this._running = true;
|
|
2799
3015
|
}
|
|
@@ -3388,7 +3604,7 @@
|
|
|
3388
3604
|
* @param {Number} [parentPosition]
|
|
3389
3605
|
* @param {Boolean} [fastSet=false]
|
|
3390
3606
|
* @param {Number} [index=0]
|
|
3391
|
-
* @param {
|
|
3607
|
+
* @param {TargetsArray} [allTargets]
|
|
3392
3608
|
*/
|
|
3393
3609
|
constructor(
|
|
3394
3610
|
targets,
|
|
@@ -3397,7 +3613,7 @@
|
|
|
3397
3613
|
parentPosition,
|
|
3398
3614
|
fastSet = false,
|
|
3399
3615
|
index = 0,
|
|
3400
|
-
|
|
3616
|
+
allTargets
|
|
3401
3617
|
) {
|
|
3402
3618
|
|
|
3403
3619
|
super(/** @type {TimerParams & AnimationParams} */(parameters), parent, parentPosition);
|
|
@@ -3448,7 +3664,7 @@
|
|
|
3448
3664
|
|
|
3449
3665
|
const target = parsedTargets[targetIndex];
|
|
3450
3666
|
const ti = index || targetIndex;
|
|
3451
|
-
const tl =
|
|
3667
|
+
const tl = allTargets || parsedTargets;
|
|
3452
3668
|
|
|
3453
3669
|
let lastTransformGroupIndex = NaN;
|
|
3454
3670
|
let lastTransformGroupLength = NaN;
|
|
@@ -3524,7 +3740,14 @@
|
|
|
3524
3740
|
toFunctionStore.func = null;
|
|
3525
3741
|
fromFunctionStore.func = null;
|
|
3526
3742
|
|
|
3527
|
-
const
|
|
3743
|
+
const computedComposition = getFunctionValue(setValue(key.composition, tComposition), target, ti, tl, null, null);
|
|
3744
|
+
const tweenComposition = isNum(computedComposition) ? computedComposition : compositionTypes[computedComposition];
|
|
3745
|
+
if (!siblings && tweenComposition !== compositionTypes.none) siblings = getTweenSiblings(target, propName);
|
|
3746
|
+
// Timelines pass the last sibling tween if it belongs to the same timeline
|
|
3747
|
+
// Standalone animations only pass prevTween when the property has multiple keyframes
|
|
3748
|
+
const tailTween = siblings ? siblings._tail : null;
|
|
3749
|
+
const prevSiblingTween = parent && tailTween && tailTween.parent.parent === parent ? tailTween : prevTween;
|
|
3750
|
+
const computedToValue = getFunctionValue(key.to, target, ti, tl, toFunctionStore, prevSiblingTween);
|
|
3528
3751
|
|
|
3529
3752
|
let tweenToValue;
|
|
3530
3753
|
// Allows function based values to return an object syntax value ({to: v})
|
|
@@ -3534,20 +3757,18 @@
|
|
|
3534
3757
|
} else {
|
|
3535
3758
|
tweenToValue = computedToValue;
|
|
3536
3759
|
}
|
|
3537
|
-
const tweenFromValue = getFunctionValue(key.from, target, ti, tl);
|
|
3760
|
+
const tweenFromValue = getFunctionValue(key.from, target, ti, tl, null, prevSiblingTween);
|
|
3538
3761
|
const easeToParse = key.ease || tEasing;
|
|
3539
3762
|
|
|
3540
|
-
const easeFunctionResult = getFunctionValue(easeToParse, target, ti, tl);
|
|
3763
|
+
const easeFunctionResult = getFunctionValue(easeToParse, target, ti, tl, null, prevSiblingTween);
|
|
3541
3764
|
const keyEasing = isFnc(easeFunctionResult) || isStr(easeFunctionResult) ? easeFunctionResult : easeToParse;
|
|
3542
3765
|
|
|
3543
3766
|
const hasSpring = !isUnd(keyEasing) && !isUnd(/** @type {Spring} */(keyEasing).ease);
|
|
3544
3767
|
const tweenEasing = hasSpring ? /** @type {Spring} */(keyEasing).ease : keyEasing;
|
|
3545
3768
|
// Calculate default individual keyframe duration by dividing the tl of keyframes
|
|
3546
|
-
const tweenDuration = hasSpring ? /** @type {Spring} */(keyEasing).settlingDuration : getFunctionValue(setValue(key.duration, (l > 1 ? getFunctionValue(tDuration, target, ti, tl) / l : tDuration)), target, ti, tl);
|
|
3769
|
+
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);
|
|
3547
3770
|
// Default delay value should only be applied to the first tween
|
|
3548
|
-
const tweenDelay = getFunctionValue(setValue(key.delay, (!tweenIndex ? tDelay : 0)), target, ti, tl);
|
|
3549
|
-
const computedComposition = getFunctionValue(setValue(key.composition, tComposition), target, ti, tl);
|
|
3550
|
-
const tweenComposition = isNum(computedComposition) ? computedComposition : compositionTypes[computedComposition];
|
|
3771
|
+
const tweenDelay = getFunctionValue(setValue(key.delay, (!tweenIndex ? tDelay : 0)), target, ti, tl, null, prevSiblingTween);
|
|
3551
3772
|
// Modifiers are treated differently and don't accept function based value to prevent having to pass a function wrapper
|
|
3552
3773
|
const tweenModifier = key.modifier || tModifier;
|
|
3553
3774
|
const hasFromvalue = !isUnd(tweenFromValue);
|
|
@@ -3564,7 +3785,6 @@
|
|
|
3564
3785
|
let prevSibling = prevTween;
|
|
3565
3786
|
|
|
3566
3787
|
if (tweenComposition !== compositionTypes.none) {
|
|
3567
|
-
if (!siblings) siblings = getTweenSiblings(target, propName);
|
|
3568
3788
|
let nextSibling = siblings._head;
|
|
3569
3789
|
// Iterate trough all the next siblings until we find a sibling with an equal or inferior start time
|
|
3570
3790
|
while (nextSibling && !nextSibling._isOverridden && nextSibling._absoluteStartTime <= absoluteStartTime) {
|
|
@@ -3583,8 +3803,8 @@
|
|
|
3583
3803
|
|
|
3584
3804
|
// Decompose values
|
|
3585
3805
|
if (isFromToValue) {
|
|
3586
|
-
decomposeRawValue(isFromToArray ? getFunctionValue(tweenToValue[0], target, ti, tl, fromFunctionStore) : tweenFromValue, fromTargetObject);
|
|
3587
|
-
decomposeRawValue(isFromToArray ? getFunctionValue(tweenToValue[1], target, ti, tl, toFunctionStore) : tweenToValue, toTargetObject);
|
|
3806
|
+
decomposeRawValue(isFromToArray ? getFunctionValue(tweenToValue[0], target, ti, tl, fromFunctionStore, prevSiblingTween) : tweenFromValue, fromTargetObject);
|
|
3807
|
+
decomposeRawValue(isFromToArray ? getFunctionValue(tweenToValue[1], target, ti, tl, toFunctionStore, prevSiblingTween) : tweenToValue, toTargetObject);
|
|
3588
3808
|
// Needed to force an inline style registration
|
|
3589
3809
|
const originalValue = getOriginalAnimatableValue(target, propName, tweenType, inlineStylesStore);
|
|
3590
3810
|
if (fromTargetObject.t === valueTypes.NUMBER) {
|
|
@@ -3738,6 +3958,18 @@
|
|
|
3738
3958
|
composeTween(tween, siblings);
|
|
3739
3959
|
}
|
|
3740
3960
|
|
|
3961
|
+
// Pre-compute the tween end value for function-based value chaining (ie morphTo / scrambleText in keyframe arrays and timelines)
|
|
3962
|
+
const vt = tween._valueType;
|
|
3963
|
+
if (vt === valueTypes.COMPLEX) {
|
|
3964
|
+
tween._value = composeComplexValue(tween, 1, -1);
|
|
3965
|
+
} else if (vt === valueTypes.COLOR) {
|
|
3966
|
+
tween._value = composeColorValue(tween, 1, -1);
|
|
3967
|
+
} else if (vt === valueTypes.UNIT) {
|
|
3968
|
+
tween._value = `${tweenModifier(tween._toNumber)}${tween._unit}`;
|
|
3969
|
+
} else {
|
|
3970
|
+
tween._value = tweenModifier(tween._toNumber);
|
|
3971
|
+
}
|
|
3972
|
+
|
|
3741
3973
|
if (isNaN(firstTweenChangeStartTime)) {
|
|
3742
3974
|
firstTweenChangeStartTime = tween._startTime;
|
|
3743
3975
|
}
|
|
@@ -3895,7 +4127,7 @@
|
|
|
3895
4127
|
*/
|
|
3896
4128
|
revert() {
|
|
3897
4129
|
super.revert();
|
|
3898
|
-
return
|
|
4130
|
+
return revertValues(this);
|
|
3899
4131
|
}
|
|
3900
4132
|
|
|
3901
4133
|
/**
|
|
@@ -3916,171 +4148,13 @@
|
|
|
3916
4148
|
* @param {TargetsParam} targets
|
|
3917
4149
|
* @param {AnimationParams} parameters
|
|
3918
4150
|
* @return {JSAnimation}
|
|
3919
|
-
*/
|
|
3920
|
-
const animate = (targets, parameters) =>
|
|
3921
|
-
|
|
3922
|
-
|
|
3923
|
-
|
|
3924
|
-
|
|
3925
|
-
|
|
3926
|
-
const WAAPIAnimationsLookups = {
|
|
3927
|
-
_head: null,
|
|
3928
|
-
_tail: null,
|
|
3929
|
-
};
|
|
3930
|
-
|
|
3931
|
-
/**
|
|
3932
|
-
* @param {DOMTarget} $el
|
|
3933
|
-
* @param {String} [property]
|
|
3934
|
-
* @param {WAAPIAnimation} [parent]
|
|
3935
|
-
* @return {globalThis.Animation}
|
|
3936
|
-
*/
|
|
3937
|
-
const removeWAAPIAnimation = ($el, property, parent) => {
|
|
3938
|
-
let nextLookup = WAAPIAnimationsLookups._head;
|
|
3939
|
-
let anim;
|
|
3940
|
-
while (nextLookup) {
|
|
3941
|
-
const next = nextLookup._next;
|
|
3942
|
-
const matchTarget = nextLookup.$el === $el;
|
|
3943
|
-
const matchProperty = !property || nextLookup.property === property;
|
|
3944
|
-
const matchParent = !parent || nextLookup.parent === parent;
|
|
3945
|
-
if (matchTarget && matchProperty && matchParent) {
|
|
3946
|
-
anim = nextLookup.animation;
|
|
3947
|
-
try { anim.commitStyles(); } catch {} anim.cancel();
|
|
3948
|
-
removeChild(WAAPIAnimationsLookups, nextLookup);
|
|
3949
|
-
const lookupParent = nextLookup.parent;
|
|
3950
|
-
if (lookupParent) {
|
|
3951
|
-
lookupParent._completed++;
|
|
3952
|
-
if (lookupParent.animations.length === lookupParent._completed) {
|
|
3953
|
-
lookupParent.completed = true;
|
|
3954
|
-
lookupParent.paused = true;
|
|
3955
|
-
if (!lookupParent.muteCallbacks) {
|
|
3956
|
-
lookupParent.onComplete(lookupParent);
|
|
3957
|
-
lookupParent._resolve(lookupParent);
|
|
3958
|
-
}
|
|
3959
|
-
}
|
|
3960
|
-
}
|
|
3961
|
-
}
|
|
3962
|
-
nextLookup = next;
|
|
3963
|
-
}
|
|
3964
|
-
return anim;
|
|
3965
|
-
};
|
|
3966
|
-
|
|
3967
|
-
/**
|
|
3968
|
-
* @param {WAAPIAnimation} parent
|
|
3969
|
-
* @param {DOMTarget} $el
|
|
3970
|
-
* @param {String} property
|
|
3971
|
-
* @param {PropertyIndexedKeyframes} keyframes
|
|
3972
|
-
* @param {KeyframeAnimationOptions} params
|
|
3973
|
-
* @retun {globalThis.Animation}
|
|
3974
|
-
*/
|
|
3975
|
-
const addWAAPIAnimation = (parent, $el, property, keyframes, params) => {
|
|
3976
|
-
const animation = $el.animate(keyframes, params);
|
|
3977
|
-
const animTotalDuration = params.delay + (+params.duration * params.iterations);
|
|
3978
|
-
animation.playbackRate = parent._speed;
|
|
3979
|
-
if (parent.paused) animation.pause();
|
|
3980
|
-
if (parent.duration < animTotalDuration) {
|
|
3981
|
-
parent.duration = animTotalDuration;
|
|
3982
|
-
parent.controlAnimation = animation;
|
|
3983
|
-
}
|
|
3984
|
-
parent.animations.push(animation);
|
|
3985
|
-
removeWAAPIAnimation($el, property);
|
|
3986
|
-
addChild(WAAPIAnimationsLookups, { parent, animation, $el, property, _next: null, _prev: null });
|
|
3987
|
-
const handleRemove = () => removeWAAPIAnimation($el, property, parent);
|
|
3988
|
-
animation.oncancel = handleRemove;
|
|
3989
|
-
animation.onremove = handleRemove;
|
|
3990
|
-
if (!parent.persist) {
|
|
3991
|
-
animation.onfinish = handleRemove;
|
|
3992
|
-
}
|
|
3993
|
-
return animation;
|
|
3994
|
-
};
|
|
3995
|
-
|
|
3996
|
-
|
|
3997
|
-
|
|
3998
|
-
|
|
3999
|
-
|
|
4000
|
-
/**
|
|
4001
|
-
* @overload
|
|
4002
|
-
* @param {DOMTargetSelector} targetSelector
|
|
4003
|
-
* @param {String} propName
|
|
4004
|
-
* @return {String}
|
|
4005
|
-
*
|
|
4006
|
-
* @overload
|
|
4007
|
-
* @param {JSTargetsParam} targetSelector
|
|
4008
|
-
* @param {String} propName
|
|
4009
|
-
* @return {Number|String}
|
|
4010
|
-
*
|
|
4011
|
-
* @overload
|
|
4012
|
-
* @param {DOMTargetsParam} targetSelector
|
|
4013
|
-
* @param {String} propName
|
|
4014
|
-
* @param {String} unit
|
|
4015
|
-
* @return {String}
|
|
4016
|
-
*
|
|
4017
|
-
* @overload
|
|
4018
|
-
* @param {TargetsParam} targetSelector
|
|
4019
|
-
* @param {String} propName
|
|
4020
|
-
* @param {Boolean} unit
|
|
4021
|
-
* @return {Number}
|
|
4022
|
-
*
|
|
4023
|
-
* @param {TargetsParam} targetSelector
|
|
4024
|
-
* @param {String} propName
|
|
4025
|
-
* @param {String|Boolean} [unit]
|
|
4026
|
-
*/
|
|
4027
|
-
function get(targetSelector, propName, unit) {
|
|
4028
|
-
const targets = registerTargets(targetSelector);
|
|
4029
|
-
if (!targets.length) return;
|
|
4030
|
-
const [ target ] = targets;
|
|
4031
|
-
const tweenType = getTweenType(target, propName);
|
|
4032
|
-
const normalizePropName = sanitizePropertyName(propName, target, tweenType);
|
|
4033
|
-
let originalValue = getOriginalAnimatableValue(target, normalizePropName);
|
|
4034
|
-
if (isUnd(unit)) {
|
|
4035
|
-
return originalValue;
|
|
4036
|
-
} else {
|
|
4037
|
-
decomposeRawValue(originalValue, decomposedOriginalValue);
|
|
4038
|
-
if (decomposedOriginalValue.t === valueTypes.NUMBER || decomposedOriginalValue.t === valueTypes.UNIT) {
|
|
4039
|
-
if (unit === false) {
|
|
4040
|
-
return decomposedOriginalValue.n;
|
|
4041
|
-
} else {
|
|
4042
|
-
const convertedValue = convertValueUnit(/** @type {DOMTarget} */(target), decomposedOriginalValue, /** @type {String} */(unit), false);
|
|
4043
|
-
return `${round$1(convertedValue.n, globals.precision)}${convertedValue.u}`;
|
|
4044
|
-
}
|
|
4045
|
-
}
|
|
4046
|
-
}
|
|
4047
|
-
}
|
|
4048
|
-
|
|
4049
|
-
/**
|
|
4050
|
-
* @param {TargetsParam} targets
|
|
4051
|
-
* @param {AnimationParams} parameters
|
|
4052
|
-
* @return {JSAnimation}
|
|
4053
|
-
*/
|
|
4054
|
-
const set = (targets, parameters) => {
|
|
4055
|
-
if (isUnd(parameters)) return;
|
|
4056
|
-
parameters.duration = minValue;
|
|
4057
|
-
// Do not overrides currently active tweens by default
|
|
4058
|
-
parameters.composition = setValue(parameters.composition, compositionTypes.none);
|
|
4059
|
-
// Skip init() and force rendering by playing the animation
|
|
4060
|
-
return new JSAnimation(targets, parameters, null, 0, true).resume();
|
|
4061
|
-
};
|
|
4062
|
-
|
|
4063
|
-
/**
|
|
4064
|
-
* @param {TargetsParam} targets
|
|
4065
|
-
* @param {Renderable|WAAPIAnimation} [renderable]
|
|
4066
|
-
* @param {String} [propertyName]
|
|
4067
|
-
* @return {TargetsArray}
|
|
4068
|
-
*/
|
|
4069
|
-
const remove = (targets, renderable, propertyName) => {
|
|
4070
|
-
const targetsArray = parseTargets(targets);
|
|
4071
|
-
for (let i = 0, l = targetsArray.length; i < l; i++) {
|
|
4072
|
-
removeWAAPIAnimation(
|
|
4073
|
-
/** @type {DOMTarget} */(targetsArray[i]),
|
|
4074
|
-
propertyName,
|
|
4075
|
-
renderable && /** @type {WAAPIAnimation} */(renderable).controlAnimation && /** @type {WAAPIAnimation} */(renderable),
|
|
4076
|
-
);
|
|
4077
|
-
}
|
|
4078
|
-
removeTargetsFromRenderable(
|
|
4079
|
-
targetsArray,
|
|
4080
|
-
/** @type {Renderable} */(renderable),
|
|
4081
|
-
propertyName
|
|
4082
|
-
);
|
|
4083
|
-
return targetsArray;
|
|
4151
|
+
*/
|
|
4152
|
+
const animate = (targets, parameters) => {
|
|
4153
|
+
if (globals.editor) {
|
|
4154
|
+
return globals.editor.addAnimation(targets, parameters);
|
|
4155
|
+
} else {
|
|
4156
|
+
return new JSAnimation(targets, parameters, null, 0, false).init();
|
|
4157
|
+
}
|
|
4084
4158
|
};
|
|
4085
4159
|
|
|
4086
4160
|
|
|
@@ -4136,6 +4210,8 @@
|
|
|
4136
4210
|
|
|
4137
4211
|
|
|
4138
4212
|
|
|
4213
|
+
|
|
4214
|
+
|
|
4139
4215
|
/**
|
|
4140
4216
|
* @param {Timeline} tl
|
|
4141
4217
|
* @return {Number}
|
|
@@ -4157,7 +4233,7 @@
|
|
|
4157
4233
|
* @param {Number} timePosition
|
|
4158
4234
|
* @param {TargetsParam} targets
|
|
4159
4235
|
* @param {Number} [index]
|
|
4160
|
-
* @param {
|
|
4236
|
+
* @param {TargetsArray} [allTargets]
|
|
4161
4237
|
* @return {Timeline}
|
|
4162
4238
|
*
|
|
4163
4239
|
* @param {TimerParams|AnimationParams} childParams
|
|
@@ -4165,15 +4241,15 @@
|
|
|
4165
4241
|
* @param {Number} timePosition
|
|
4166
4242
|
* @param {TargetsParam} [targets]
|
|
4167
4243
|
* @param {Number} [index]
|
|
4168
|
-
* @param {
|
|
4244
|
+
* @param {TargetsArray} [allTargets]
|
|
4169
4245
|
*/
|
|
4170
|
-
function addTlChild(childParams, tl, timePosition, targets, index,
|
|
4246
|
+
function addTlChild(childParams, tl, timePosition, targets, index, allTargets) {
|
|
4171
4247
|
const isSetter = isNum(childParams.duration) && /** @type {Number} */(childParams.duration) <= minValue;
|
|
4172
4248
|
// Offset the tl position with -minValue for 0 duration animations or .set() calls in order to align their end value with the defined position
|
|
4173
4249
|
const adjustedPosition = isSetter ? timePosition - minValue : timePosition;
|
|
4174
4250
|
if (tl.composition) tick(tl, adjustedPosition, 1, 1, tickModes.AUTO);
|
|
4175
4251
|
const tlChild = targets ?
|
|
4176
|
-
new JSAnimation(targets,/** @type {AnimationParams} */(childParams), tl, adjustedPosition, false, index,
|
|
4252
|
+
new JSAnimation(targets,/** @type {AnimationParams} */(childParams), tl, adjustedPosition, false, index, allTargets) :
|
|
4177
4253
|
new Timer(/** @type {TimerParams} */(childParams), tl, adjustedPosition);
|
|
4178
4254
|
if (tl.composition) tlChild.init(true);
|
|
4179
4255
|
// TODO: Might be better to insert at a position relative to startTime?
|
|
@@ -4221,7 +4297,7 @@
|
|
|
4221
4297
|
* @overload
|
|
4222
4298
|
* @param {TargetsParam} a1
|
|
4223
4299
|
* @param {AnimationParams} a2
|
|
4224
|
-
* @param {TimelinePosition|StaggerFunction<Number|String
|
|
4300
|
+
* @param {TimelinePosition|StaggerFunction<Number|String>|TweakRegister} [a3]
|
|
4225
4301
|
* @return {this}
|
|
4226
4302
|
*
|
|
4227
4303
|
* @overload
|
|
@@ -4231,7 +4307,7 @@
|
|
|
4231
4307
|
*
|
|
4232
4308
|
* @param {TargetsParam|TimerParams} a1
|
|
4233
4309
|
* @param {TimelinePosition|AnimationParams} a2
|
|
4234
|
-
* @param {TimelinePosition|StaggerFunction<Number|String
|
|
4310
|
+
* @param {TimelinePosition|StaggerFunction<Number|String>|TweakRegister} [a3]
|
|
4235
4311
|
*/
|
|
4236
4312
|
add(a1, a2, a3) {
|
|
4237
4313
|
const isAnim = isObj(a2);
|
|
@@ -4240,9 +4316,11 @@
|
|
|
4240
4316
|
this._hasChildren = true;
|
|
4241
4317
|
if (isAnim) {
|
|
4242
4318
|
const childParams = /** @type {AnimationParams} */(a2);
|
|
4243
|
-
|
|
4244
|
-
|
|
4245
|
-
|
|
4319
|
+
const editorHook = globals.editor && globals.editor.addTimelineChild;
|
|
4320
|
+
const isStaggerType = a3 && /** @type {TweakRegister} */(a3).type === 'Stagger' && globals.editor;
|
|
4321
|
+
// Check for function or Stagger type children positions
|
|
4322
|
+
const staggeredPosition = isFnc(a3) ? a3 : null;
|
|
4323
|
+
if (staggeredPosition || isStaggerType) {
|
|
4246
4324
|
const parsedTargetsArray = parseTargets(/** @type {TargetsParam} */(a1));
|
|
4247
4325
|
// Store initial duration before adding new children that will change the duration
|
|
4248
4326
|
const tlDuration = this.duration;
|
|
@@ -4253,28 +4331,36 @@
|
|
|
4253
4331
|
let i = 0;
|
|
4254
4332
|
/** @type {Number} */
|
|
4255
4333
|
const parsedLength = (parsedTargetsArray.length);
|
|
4334
|
+
// Call editor hook once for the entire stagger group instead of per target
|
|
4335
|
+
const resolvedParams = editorHook ? editorHook(/** @type {TargetsParam} */(a1), childParams, this.id, a3, parsedLength) : null;
|
|
4336
|
+
// Resolve stagger AFTER editor hook so tweaked position value (a3.defaultValue) is used
|
|
4337
|
+
const staggerFn = staggeredPosition || globals.editor.resolveStagger(/** @type {TweakRegister} */(a3).defaultValue);
|
|
4256
4338
|
parsedTargetsArray.forEach((/** @type {Target} */target) => {
|
|
4257
4339
|
// Create a new parameter object for each staggered children
|
|
4258
|
-
const staggeredChildParams = { ...childParams };
|
|
4340
|
+
const staggeredChildParams = { ...(resolvedParams || childParams) };
|
|
4259
4341
|
// Reset the duration of the timeline iteration before each stagger to prevent wrong start value calculation
|
|
4260
4342
|
this.duration = tlDuration;
|
|
4261
4343
|
this.iterationDuration = tlIterationDuration;
|
|
4262
4344
|
if (!isUnd(id)) staggeredChildParams.id = id + '-' + i;
|
|
4345
|
+
const staggeredTimePosition = parseTimelinePosition(this, staggerFn(target, i, parsedTargetsArray, null, this));
|
|
4263
4346
|
addTlChild(
|
|
4264
4347
|
staggeredChildParams,
|
|
4265
4348
|
this,
|
|
4266
|
-
|
|
4349
|
+
staggeredTimePosition,
|
|
4267
4350
|
target,
|
|
4268
4351
|
i,
|
|
4269
|
-
|
|
4352
|
+
parsedTargetsArray,
|
|
4270
4353
|
);
|
|
4271
4354
|
i++;
|
|
4272
4355
|
});
|
|
4273
4356
|
} else {
|
|
4357
|
+
// Call editor hook before resolving position so tweaked values are applied
|
|
4358
|
+
const resolvedChildParams = editorHook ? editorHook(/** @type {TargetsParam} */(a1), childParams, this.id, a3) : childParams;
|
|
4359
|
+
const resolvedPosition = a3 && /** @type {*} */(a3).type ? /** @type {*} */(a3).defaultValue : a3;
|
|
4274
4360
|
addTlChild(
|
|
4275
|
-
|
|
4361
|
+
resolvedChildParams,
|
|
4276
4362
|
this,
|
|
4277
|
-
parseTimelinePosition(this,
|
|
4363
|
+
parseTimelinePosition(this, resolvedPosition),
|
|
4278
4364
|
/** @type {TargetsParam} */(a1),
|
|
4279
4365
|
);
|
|
4280
4366
|
}
|
|
@@ -4396,7 +4482,7 @@
|
|
|
4396
4482
|
revert() {
|
|
4397
4483
|
super.revert();
|
|
4398
4484
|
forEachChildren(this, (/** @type {JSAnimation|Timer} */child) => child.revert, true);
|
|
4399
|
-
return
|
|
4485
|
+
return revertValues(this);
|
|
4400
4486
|
}
|
|
4401
4487
|
|
|
4402
4488
|
/**
|
|
@@ -4416,7 +4502,12 @@
|
|
|
4416
4502
|
* @param {TimelineParams} [parameters]
|
|
4417
4503
|
* @return {Timeline}
|
|
4418
4504
|
*/
|
|
4419
|
-
const createTimeline = parameters =>
|
|
4505
|
+
const createTimeline = parameters => {
|
|
4506
|
+
if (globals.editor) {
|
|
4507
|
+
return /** @type {Timeline} */(/** @type {unknown} */(globals.editor.addTimeline(parameters)));
|
|
4508
|
+
}
|
|
4509
|
+
return new Timeline(parameters).init();
|
|
4510
|
+
};
|
|
4420
4511
|
|
|
4421
4512
|
|
|
4422
4513
|
|
|
@@ -4863,6 +4954,170 @@
|
|
|
4863
4954
|
|
|
4864
4955
|
|
|
4865
4956
|
|
|
4957
|
+
const WAAPIAnimationsLookups = {
|
|
4958
|
+
_head: null,
|
|
4959
|
+
_tail: null,
|
|
4960
|
+
};
|
|
4961
|
+
|
|
4962
|
+
/**
|
|
4963
|
+
* @param {DOMTarget} $el
|
|
4964
|
+
* @param {String} [property]
|
|
4965
|
+
* @param {WAAPIAnimation} [parent]
|
|
4966
|
+
* @return {globalThis.Animation}
|
|
4967
|
+
*/
|
|
4968
|
+
const removeWAAPIAnimation = ($el, property, parent) => {
|
|
4969
|
+
let nextLookup = WAAPIAnimationsLookups._head;
|
|
4970
|
+
let anim;
|
|
4971
|
+
while (nextLookup) {
|
|
4972
|
+
const next = nextLookup._next;
|
|
4973
|
+
const matchTarget = nextLookup.$el === $el;
|
|
4974
|
+
const matchProperty = !property || nextLookup.property === property;
|
|
4975
|
+
const matchParent = !parent || nextLookup.parent === parent;
|
|
4976
|
+
if (matchTarget && matchProperty && matchParent) {
|
|
4977
|
+
anim = nextLookup.animation;
|
|
4978
|
+
try { anim.commitStyles(); } catch {} anim.cancel();
|
|
4979
|
+
removeChild(WAAPIAnimationsLookups, nextLookup);
|
|
4980
|
+
const lookupParent = nextLookup.parent;
|
|
4981
|
+
if (lookupParent) {
|
|
4982
|
+
lookupParent._completed++;
|
|
4983
|
+
if (lookupParent.animations.length === lookupParent._completed) {
|
|
4984
|
+
lookupParent.completed = true;
|
|
4985
|
+
lookupParent.paused = true;
|
|
4986
|
+
if (!lookupParent.muteCallbacks) {
|
|
4987
|
+
lookupParent.onComplete(lookupParent);
|
|
4988
|
+
lookupParent._resolve(lookupParent);
|
|
4989
|
+
}
|
|
4990
|
+
}
|
|
4991
|
+
}
|
|
4992
|
+
}
|
|
4993
|
+
nextLookup = next;
|
|
4994
|
+
}
|
|
4995
|
+
return anim;
|
|
4996
|
+
};
|
|
4997
|
+
|
|
4998
|
+
/**
|
|
4999
|
+
* @param {WAAPIAnimation} parent
|
|
5000
|
+
* @param {DOMTarget} $el
|
|
5001
|
+
* @param {String} property
|
|
5002
|
+
* @param {PropertyIndexedKeyframes} keyframes
|
|
5003
|
+
* @param {KeyframeAnimationOptions} params
|
|
5004
|
+
* @retun {globalThis.Animation}
|
|
5005
|
+
*/
|
|
5006
|
+
const addWAAPIAnimation = (parent, $el, property, keyframes, params) => {
|
|
5007
|
+
const animation = $el.animate(keyframes, params);
|
|
5008
|
+
const animTotalDuration = params.delay + (+params.duration * params.iterations);
|
|
5009
|
+
animation.playbackRate = parent._speed;
|
|
5010
|
+
if (parent.paused) animation.pause();
|
|
5011
|
+
if (parent.duration < animTotalDuration) {
|
|
5012
|
+
parent.duration = animTotalDuration;
|
|
5013
|
+
parent.controlAnimation = animation;
|
|
5014
|
+
}
|
|
5015
|
+
parent.animations.push(animation);
|
|
5016
|
+
removeWAAPIAnimation($el, property);
|
|
5017
|
+
addChild(WAAPIAnimationsLookups, { parent, animation, $el, property, _next: null, _prev: null });
|
|
5018
|
+
const handleRemove = () => removeWAAPIAnimation($el, property, parent);
|
|
5019
|
+
animation.oncancel = handleRemove;
|
|
5020
|
+
animation.onremove = handleRemove;
|
|
5021
|
+
if (!parent.persist) {
|
|
5022
|
+
animation.onfinish = handleRemove;
|
|
5023
|
+
}
|
|
5024
|
+
return animation;
|
|
5025
|
+
};
|
|
5026
|
+
|
|
5027
|
+
|
|
5028
|
+
|
|
5029
|
+
|
|
5030
|
+
|
|
5031
|
+
/**
|
|
5032
|
+
* @overload
|
|
5033
|
+
* @param {DOMTargetSelector} targetSelector
|
|
5034
|
+
* @param {String} propName
|
|
5035
|
+
* @return {String}
|
|
5036
|
+
*
|
|
5037
|
+
* @overload
|
|
5038
|
+
* @param {JSTargetsParam} targetSelector
|
|
5039
|
+
* @param {String} propName
|
|
5040
|
+
* @return {Number|String}
|
|
5041
|
+
*
|
|
5042
|
+
* @overload
|
|
5043
|
+
* @param {DOMTargetsParam} targetSelector
|
|
5044
|
+
* @param {String} propName
|
|
5045
|
+
* @param {String} unit
|
|
5046
|
+
* @return {String}
|
|
5047
|
+
*
|
|
5048
|
+
* @overload
|
|
5049
|
+
* @param {TargetsParam} targetSelector
|
|
5050
|
+
* @param {String} propName
|
|
5051
|
+
* @param {Boolean} unit
|
|
5052
|
+
* @return {Number}
|
|
5053
|
+
*
|
|
5054
|
+
* @param {TargetsParam} targetSelector
|
|
5055
|
+
* @param {String} propName
|
|
5056
|
+
* @param {String|Boolean} [unit]
|
|
5057
|
+
*/
|
|
5058
|
+
function get(targetSelector, propName, unit) {
|
|
5059
|
+
const targets = registerTargets(targetSelector);
|
|
5060
|
+
if (!targets.length) return;
|
|
5061
|
+
const [ target ] = targets;
|
|
5062
|
+
const tweenType = getTweenType(target, propName);
|
|
5063
|
+
const normalizePropName = sanitizePropertyName(propName, target, tweenType);
|
|
5064
|
+
let originalValue = getOriginalAnimatableValue(target, normalizePropName);
|
|
5065
|
+
if (isUnd(unit)) {
|
|
5066
|
+
return originalValue;
|
|
5067
|
+
} else {
|
|
5068
|
+
decomposeRawValue(originalValue, decomposedOriginalValue);
|
|
5069
|
+
if (decomposedOriginalValue.t === valueTypes.NUMBER || decomposedOriginalValue.t === valueTypes.UNIT) {
|
|
5070
|
+
if (unit === false) {
|
|
5071
|
+
return decomposedOriginalValue.n;
|
|
5072
|
+
} else {
|
|
5073
|
+
const convertedValue = convertValueUnit(/** @type {DOMTarget} */(target), decomposedOriginalValue, /** @type {String} */(unit), false);
|
|
5074
|
+
return `${round$1(convertedValue.n, globals.precision)}${convertedValue.u}`;
|
|
5075
|
+
}
|
|
5076
|
+
}
|
|
5077
|
+
}
|
|
5078
|
+
}
|
|
5079
|
+
|
|
5080
|
+
/**
|
|
5081
|
+
* @param {TargetsParam} targets
|
|
5082
|
+
* @param {AnimationParams} parameters
|
|
5083
|
+
* @return {JSAnimation}
|
|
5084
|
+
*/
|
|
5085
|
+
const set = (targets, parameters) => {
|
|
5086
|
+
if (isUnd(parameters)) return;
|
|
5087
|
+
parameters.duration = minValue;
|
|
5088
|
+
// Do not overrides currently active tweens by default
|
|
5089
|
+
parameters.composition = setValue(parameters.composition, compositionTypes.none);
|
|
5090
|
+
// Skip init() and force rendering by playing the animation
|
|
5091
|
+
return new JSAnimation(targets, parameters, null, 0, true).resume();
|
|
5092
|
+
};
|
|
5093
|
+
|
|
5094
|
+
/**
|
|
5095
|
+
* @param {TargetsParam} targets
|
|
5096
|
+
* @param {Renderable|WAAPIAnimation} [renderable]
|
|
5097
|
+
* @param {String} [propertyName]
|
|
5098
|
+
* @return {TargetsArray}
|
|
5099
|
+
*/
|
|
5100
|
+
const remove = (targets, renderable, propertyName) => {
|
|
5101
|
+
const targetsArray = parseTargets(targets);
|
|
5102
|
+
for (let i = 0, l = targetsArray.length; i < l; i++) {
|
|
5103
|
+
removeWAAPIAnimation(
|
|
5104
|
+
/** @type {DOMTarget} */(targetsArray[i]),
|
|
5105
|
+
propertyName,
|
|
5106
|
+
renderable && /** @type {WAAPIAnimation} */(renderable).controlAnimation && /** @type {WAAPIAnimation} */(renderable),
|
|
5107
|
+
);
|
|
5108
|
+
}
|
|
5109
|
+
removeTargetsFromRenderable(
|
|
5110
|
+
targetsArray,
|
|
5111
|
+
/** @type {Renderable} */(renderable),
|
|
5112
|
+
propertyName
|
|
5113
|
+
);
|
|
5114
|
+
return targetsArray;
|
|
5115
|
+
};
|
|
5116
|
+
|
|
5117
|
+
|
|
5118
|
+
|
|
5119
|
+
|
|
5120
|
+
|
|
4866
5121
|
/**
|
|
4867
5122
|
* @param {Event} e
|
|
4868
5123
|
*/
|
|
@@ -6065,19 +6320,20 @@
|
|
|
6065
6320
|
};
|
|
6066
6321
|
|
|
6067
6322
|
/**
|
|
6068
|
-
* @param {(...args: any[]) => Tickable | ((...args: any[]) => void)} constructor
|
|
6323
|
+
* @param {(...args: any[]) => Tickable | ((...args: any[]) => void) | void} constructor
|
|
6069
6324
|
* @return {(...args: any[]) => Tickable | ((...args: any[]) => void)}
|
|
6070
6325
|
*/
|
|
6071
6326
|
const keepTime = constructor => {
|
|
6072
6327
|
/** @type {Tickable} */
|
|
6073
6328
|
let tracked;
|
|
6074
6329
|
return (...args) => {
|
|
6075
|
-
let currentIteration, currentIterationProgress, reversed, alternate;
|
|
6330
|
+
let currentIteration, currentIterationProgress, reversed, alternate, startTime;
|
|
6076
6331
|
if (tracked) {
|
|
6077
6332
|
currentIteration = tracked.currentIteration;
|
|
6078
6333
|
currentIterationProgress = tracked.iterationProgress;
|
|
6079
6334
|
reversed = tracked.reversed;
|
|
6080
6335
|
alternate = tracked._alternate;
|
|
6336
|
+
startTime = tracked._startTime;
|
|
6081
6337
|
tracked.revert();
|
|
6082
6338
|
}
|
|
6083
6339
|
const cleanup = constructor(...args);
|
|
@@ -6085,6 +6341,7 @@
|
|
|
6085
6341
|
if (!isUnd(currentIterationProgress)) {
|
|
6086
6342
|
/** @type {Tickable} */(tracked).currentIteration = currentIteration;
|
|
6087
6343
|
/** @type {Tickable} */(tracked).iterationProgress = (alternate ? !(currentIteration % 2) ? reversed : !reversed : reversed) ? 1 - currentIterationProgress : currentIterationProgress;
|
|
6344
|
+
/** @type {Tickable} */(tracked)._startTime = startTime;
|
|
6088
6345
|
}
|
|
6089
6346
|
return cleanup || noop;
|
|
6090
6347
|
}
|
|
@@ -7430,12 +7687,12 @@
|
|
|
7430
7687
|
* @param {WAAPIKeyframeValue} value
|
|
7431
7688
|
* @param {DOMTarget} $el
|
|
7432
7689
|
* @param {Number} i
|
|
7433
|
-
* @param {
|
|
7690
|
+
* @param {DOMTargetsArray} parsedTargets
|
|
7434
7691
|
* @return {String}
|
|
7435
7692
|
*/
|
|
7436
|
-
const normalizeTweenValue = (propName, value, $el, i,
|
|
7693
|
+
const normalizeTweenValue = (propName, value, $el, i, parsedTargets) => {
|
|
7437
7694
|
// Do not try to compute strings with getFunctionValue otherwise it will convert CSS variables
|
|
7438
|
-
let v = isStr(value) ? value : getFunctionValue(/** @type {any} */(value), $el, i,
|
|
7695
|
+
let v = isStr(value) ? value : getFunctionValue(/** @type {any} */(value), $el, i, parsedTargets, null, null);
|
|
7439
7696
|
if (!isNum(v)) return v;
|
|
7440
7697
|
if (commonDefaultPXProperties.includes(propName) || stringStartsWith(propName, 'translate')) return `${v}px`;
|
|
7441
7698
|
if (stringStartsWith(propName, 'rotate') || stringStartsWith(propName, 'skew')) return `${v}deg`;
|
|
@@ -7448,18 +7705,18 @@
|
|
|
7448
7705
|
* @param {WAAPIKeyframeValue} from
|
|
7449
7706
|
* @param {WAAPIKeyframeValue} to
|
|
7450
7707
|
* @param {Number} i
|
|
7451
|
-
* @param {
|
|
7708
|
+
* @param {DOMTargetsArray} parsedTargets
|
|
7452
7709
|
* @return {WAAPITweenValue}
|
|
7453
7710
|
*/
|
|
7454
|
-
const parseIndividualTweenValue = ($el, propName, from, to, i,
|
|
7711
|
+
const parseIndividualTweenValue = ($el, propName, from, to, i, parsedTargets) => {
|
|
7455
7712
|
/** @type {WAAPITweenValue} */
|
|
7456
7713
|
let tweenValue = '0';
|
|
7457
|
-
const computedTo = !isUnd(to) ? normalizeTweenValue(propName, to, $el, i,
|
|
7714
|
+
const computedTo = !isUnd(to) ? normalizeTweenValue(propName, to, $el, i, parsedTargets) : getComputedStyle($el)[propName];
|
|
7458
7715
|
if (!isUnd(from)) {
|
|
7459
|
-
const computedFrom = normalizeTweenValue(propName, from, $el, i,
|
|
7716
|
+
const computedFrom = normalizeTweenValue(propName, from, $el, i, parsedTargets);
|
|
7460
7717
|
tweenValue = [computedFrom, computedTo];
|
|
7461
7718
|
} else {
|
|
7462
|
-
tweenValue = isArr(to) ? to.map((/** @type {any} */v) => normalizeTweenValue(propName, v, $el, i,
|
|
7719
|
+
tweenValue = isArr(to) ? to.map((/** @type {any} */v) => normalizeTweenValue(propName, v, $el, i, parsedTargets)) : computedTo;
|
|
7463
7720
|
}
|
|
7464
7721
|
return tweenValue;
|
|
7465
7722
|
};
|
|
@@ -7498,9 +7755,8 @@
|
|
|
7498
7755
|
}
|
|
7499
7756
|
|
|
7500
7757
|
const parsedTargets = registerTargets(targets);
|
|
7501
|
-
const targetsLength = parsedTargets.length;
|
|
7502
7758
|
|
|
7503
|
-
if (!
|
|
7759
|
+
if (!parsedTargets.length) {
|
|
7504
7760
|
console.warn(`No target found. Make sure the element you're trying to animate is accessible before creating your animation.`);
|
|
7505
7761
|
}
|
|
7506
7762
|
|
|
@@ -7556,7 +7812,7 @@
|
|
|
7556
7812
|
|
|
7557
7813
|
const easeToParse = setValue(params.ease, globals.defaults.ease);
|
|
7558
7814
|
|
|
7559
|
-
const easeFunctionResult = getFunctionValue(easeToParse, $el, i,
|
|
7815
|
+
const easeFunctionResult = getFunctionValue(easeToParse, $el, i, parsedTargets, null, null);
|
|
7560
7816
|
const keyEasing = isFnc(easeFunctionResult) || isStr(easeFunctionResult) ? easeFunctionResult : easeToParse;
|
|
7561
7817
|
|
|
7562
7818
|
const spring = /** @type {Spring} */(easeToParse).ease && easeToParse;
|
|
@@ -7564,9 +7820,9 @@
|
|
|
7564
7820
|
const easing = parseWAAPIEasing(keyEasing);
|
|
7565
7821
|
|
|
7566
7822
|
/** @type {Number} */
|
|
7567
|
-
const duration = (spring ? /** @type {Spring} */(spring).settlingDuration : getFunctionValue(setValue(params.duration, globals.defaults.duration), $el, i,
|
|
7823
|
+
const duration = (spring ? /** @type {Spring} */(spring).settlingDuration : getFunctionValue(setValue(params.duration, globals.defaults.duration), $el, i, parsedTargets, null, null)) * timeScale;
|
|
7568
7824
|
/** @type {Number} */
|
|
7569
|
-
const delay = getFunctionValue(setValue(params.delay, globals.defaults.delay), $el, i,
|
|
7825
|
+
const delay = getFunctionValue(setValue(params.delay, globals.defaults.delay), $el, i, parsedTargets, null, null) * timeScale;
|
|
7570
7826
|
/** @type {CompositeOperation} */
|
|
7571
7827
|
const composite = /** @type {CompositeOperation} */(setValue(params.composition, 'replace'));
|
|
7572
7828
|
|
|
@@ -7592,19 +7848,19 @@
|
|
|
7592
7848
|
const to = /** @type {WAAPITweenOptions} */(tweenOptions).to;
|
|
7593
7849
|
const from = /** @type {WAAPITweenOptions} */(tweenOptions).from;
|
|
7594
7850
|
/** @type {Number} */
|
|
7595
|
-
tweenParams.duration = (tweenOptionsSpring ? /** @type {Spring} */(tweenOptionsSpring).settlingDuration : getFunctionValue(setValue(tweenOptions.duration, duration), $el, i,
|
|
7851
|
+
tweenParams.duration = (tweenOptionsSpring ? /** @type {Spring} */(tweenOptionsSpring).settlingDuration : getFunctionValue(setValue(tweenOptions.duration, duration), $el, i, parsedTargets, null, null)) * timeScale;
|
|
7596
7852
|
/** @type {Number} */
|
|
7597
|
-
tweenParams.delay = getFunctionValue(setValue(tweenOptions.delay, delay), $el, i,
|
|
7853
|
+
tweenParams.delay = getFunctionValue(setValue(tweenOptions.delay, delay), $el, i, parsedTargets, null, null) * timeScale;
|
|
7598
7854
|
/** @type {CompositeOperation} */
|
|
7599
7855
|
tweenParams.composite = /** @type {CompositeOperation} */(setValue(tweenOptions.composition, composite));
|
|
7600
7856
|
/** @type {String} */
|
|
7601
7857
|
tweenParams.easing = parseWAAPIEasing(tweenOptionsEase);
|
|
7602
|
-
parsedPropertyValue = parseIndividualTweenValue($el, name, from, to, i,
|
|
7858
|
+
parsedPropertyValue = parseIndividualTweenValue($el, name, from, to, i, parsedTargets);
|
|
7603
7859
|
if (individualTransformProperty) {
|
|
7604
7860
|
keyframes[`--${individualTransformProperty}`] = parsedPropertyValue;
|
|
7605
7861
|
cachedTransforms[individualTransformProperty] = parsedPropertyValue;
|
|
7606
7862
|
} else {
|
|
7607
|
-
keyframes[name] = parseIndividualTweenValue($el, name, from, to, i,
|
|
7863
|
+
keyframes[name] = parseIndividualTweenValue($el, name, from, to, i, parsedTargets);
|
|
7608
7864
|
}
|
|
7609
7865
|
addWAAPIAnimation(this, $el, name, keyframes, tweenParams);
|
|
7610
7866
|
if (!isUnd(from)) {
|
|
@@ -7617,8 +7873,8 @@
|
|
|
7617
7873
|
}
|
|
7618
7874
|
} else {
|
|
7619
7875
|
parsedPropertyValue = isArr(propertyValue) ?
|
|
7620
|
-
propertyValue.map((/** @type {any} */v) => normalizeTweenValue(name, v, $el, i,
|
|
7621
|
-
normalizeTweenValue(name, /** @type {any} */(propertyValue), $el, i,
|
|
7876
|
+
propertyValue.map((/** @type {any} */v) => normalizeTweenValue(name, v, $el, i, parsedTargets)) :
|
|
7877
|
+
normalizeTweenValue(name, /** @type {any} */(propertyValue), $el, i, parsedTargets);
|
|
7622
7878
|
if (individualTransformProperty) {
|
|
7623
7879
|
keyframes[`--${individualTransformProperty}`] = parsedPropertyValue;
|
|
7624
7880
|
cachedTransforms[individualTransformProperty] = parsedPropertyValue;
|
|
@@ -7828,6 +8084,8 @@
|
|
|
7828
8084
|
|
|
7829
8085
|
|
|
7830
8086
|
|
|
8087
|
+
|
|
8088
|
+
|
|
7831
8089
|
/**
|
|
7832
8090
|
* @typedef {DOMTargetSelector|Array<DOMTargetSelector>} LayoutChildrenParam
|
|
7833
8091
|
*/
|
|
@@ -7849,6 +8107,7 @@
|
|
|
7849
8107
|
|
|
7850
8108
|
/**
|
|
7851
8109
|
* @typedef {Object} LayoutSpecificAnimationParams
|
|
8110
|
+
* @property {Number|String} [id]
|
|
7852
8111
|
* @property {Number|FunctionValue} [delay]
|
|
7853
8112
|
* @property {Number|FunctionValue} [duration]
|
|
7854
8113
|
* @property {EasingParam|FunctionValue} [ease]
|
|
@@ -7891,7 +8150,7 @@
|
|
|
7891
8150
|
* @property {String} id
|
|
7892
8151
|
* @property {DOMTarget} $el
|
|
7893
8152
|
* @property {Number} index
|
|
7894
|
-
* @property {
|
|
8153
|
+
* @property {Array<DOMTarget>} targets
|
|
7895
8154
|
* @property {Number} delay
|
|
7896
8155
|
* @property {Number} duration
|
|
7897
8156
|
* @property {EasingParam} ease
|
|
@@ -8035,7 +8294,7 @@
|
|
|
8035
8294
|
node.$measure = $el;
|
|
8036
8295
|
node.id = dataId;
|
|
8037
8296
|
node.index = 0;
|
|
8038
|
-
node.
|
|
8297
|
+
node.targets = null;
|
|
8039
8298
|
node.delay = 0;
|
|
8040
8299
|
node.duration = 0;
|
|
8041
8300
|
node.ease = null;
|
|
@@ -8221,12 +8480,12 @@
|
|
|
8221
8480
|
* @param {LayoutAnimationTimingsParams} params
|
|
8222
8481
|
*/
|
|
8223
8482
|
const updateNodeTimingParams = (node, params) => {
|
|
8224
|
-
const easeFunctionResult = getFunctionValue(params.ease, node.$el, node.index, node.
|
|
8483
|
+
const easeFunctionResult = getFunctionValue(params.ease, node.$el, node.index, node.targets, null, null);
|
|
8225
8484
|
const keyEasing = isFnc(easeFunctionResult) ? easeFunctionResult : params.ease;
|
|
8226
8485
|
const hasSpring = !isUnd(keyEasing) && !isUnd(/** @type {Spring} */(keyEasing).ease);
|
|
8227
8486
|
node.ease = hasSpring ? /** @type {Spring} */(keyEasing).ease : keyEasing;
|
|
8228
|
-
node.duration = hasSpring ? /** @type {Spring} */(keyEasing).settlingDuration : getFunctionValue(params.duration, node.$el, node.index, node.
|
|
8229
|
-
node.delay = getFunctionValue(params.delay, node.$el, node.index, node.
|
|
8487
|
+
node.duration = hasSpring ? /** @type {Spring} */(keyEasing).settlingDuration : getFunctionValue(params.duration, node.$el, node.index, node.targets, null, null);
|
|
8488
|
+
node.delay = getFunctionValue(params.delay, node.$el, node.index, node.targets, null, null);
|
|
8230
8489
|
};
|
|
8231
8490
|
|
|
8232
8491
|
/**
|
|
@@ -8599,10 +8858,12 @@
|
|
|
8599
8858
|
|
|
8600
8859
|
const inRootNodeIds = new Set();
|
|
8601
8860
|
// Update index and total for inital timing calculation
|
|
8602
|
-
let index = 0
|
|
8861
|
+
let index = 0;
|
|
8862
|
+
const allNodeTargets = [];
|
|
8863
|
+
this.nodes.forEach((node) => { allNodeTargets.push(node.$el); });
|
|
8603
8864
|
this.nodes.forEach((node, id) => {
|
|
8604
8865
|
node.index = index++;
|
|
8605
|
-
node.
|
|
8866
|
+
node.targets = allNodeTargets;
|
|
8606
8867
|
// Track ids of nodes that belong to the current root to filter detached matches
|
|
8607
8868
|
if (node && node.measuredIsInsideRoot) {
|
|
8608
8869
|
inRootNodeIds.add(id);
|
|
@@ -8714,8 +8975,8 @@
|
|
|
8714
8975
|
this.params = params;
|
|
8715
8976
|
/** @type {DOMTarget} */
|
|
8716
8977
|
this.root = /** @type {DOMTarget} */(registerTargets(root)[0]);
|
|
8717
|
-
/** @type {Number} */
|
|
8718
|
-
this.id = layoutId++;
|
|
8978
|
+
/** @type {Number|String} */
|
|
8979
|
+
this.id = params.id || layoutId++;
|
|
8719
8980
|
/** @type {LayoutChildrenParam} */
|
|
8720
8981
|
this.children = params.children || '*';
|
|
8721
8982
|
/** @type {Boolean} */
|
|
@@ -8838,7 +9099,9 @@
|
|
|
8838
9099
|
duration: setValue(params.duration, this.params.duration),
|
|
8839
9100
|
};
|
|
8840
9101
|
/** @type {TimelineParams} */
|
|
8841
|
-
const tlParams = {
|
|
9102
|
+
const tlParams = {
|
|
9103
|
+
id: this.id
|
|
9104
|
+
};
|
|
8842
9105
|
const onComplete = setValue(params.onComplete, this.params.onComplete);
|
|
8843
9106
|
const onPause = setValue(params.onPause, this.params.onPause);
|
|
8844
9107
|
for (let name in defaults) {
|
|
@@ -8851,6 +9114,13 @@
|
|
|
8851
9114
|
}
|
|
8852
9115
|
}
|
|
8853
9116
|
tlParams.onComplete = () => {
|
|
9117
|
+
const ap = /** @type {ScrollObserver} */(params.autoplay);
|
|
9118
|
+
const ed = globals.editor;
|
|
9119
|
+
const isScrollControled = (ap && ap.linked) || (ed && ed.showPanel);
|
|
9120
|
+
if (isScrollControled) {
|
|
9121
|
+
if (onComplete) onComplete(this.timeline);
|
|
9122
|
+
return;
|
|
9123
|
+
}
|
|
8854
9124
|
// Make sure to call .cancel() after restoreNodeInlineStyles(node); otehrwise the commited styles get reverted
|
|
8855
9125
|
if (this.transformAnimation) this.transformAnimation.cancel();
|
|
8856
9126
|
newState.forEachRootNode(node => {
|
|
@@ -8872,6 +9142,13 @@
|
|
|
8872
9142
|
});
|
|
8873
9143
|
};
|
|
8874
9144
|
tlParams.onPause = () => {
|
|
9145
|
+
const ap = /** @type {ScrollObserver} */(params.autoplay);
|
|
9146
|
+
const isScrollControled = ap && ap.linked;
|
|
9147
|
+
if (isScrollControled) {
|
|
9148
|
+
if (onComplete) onComplete(this.timeline);
|
|
9149
|
+
if (onPause) onPause(this.timeline);
|
|
9150
|
+
return;
|
|
9151
|
+
}
|
|
8875
9152
|
if (!this.root.classList.contains('is-animated')) return;
|
|
8876
9153
|
if (this.transformAnimation) this.transformAnimation.cancel();
|
|
8877
9154
|
newState.forEachRootNode(restoreNodeVisualState);
|
|
@@ -9038,41 +9315,39 @@
|
|
|
9038
9315
|
animatedParent = animatedParent.parentNode;
|
|
9039
9316
|
}
|
|
9040
9317
|
|
|
9041
|
-
const animatingTotal = animating.length;
|
|
9042
|
-
|
|
9043
9318
|
// Root is always animated first in sync with the first child (animating.length is the total of children)
|
|
9044
9319
|
if (node === rootNode) {
|
|
9045
9320
|
node.index = 0;
|
|
9046
|
-
node.
|
|
9321
|
+
node.targets = animating;
|
|
9047
9322
|
updateNodeTimingParams(node, animationTimings);
|
|
9048
9323
|
} else if (node.isEntering) {
|
|
9049
9324
|
node.index = animatedParent ? animatedParent.index : enteringIndex;
|
|
9050
|
-
node.
|
|
9325
|
+
node.targets = animatedParent ? animating : entering;
|
|
9051
9326
|
updateNodeTimingParams(node, enterFromTimings);
|
|
9052
9327
|
enteringIndex++;
|
|
9053
9328
|
} else if (node.isLeaving) {
|
|
9054
9329
|
node.index = animatedParent ? animatedParent.index : leavingIndex;
|
|
9055
|
-
node.
|
|
9330
|
+
node.targets = animatedParent ? animating : leaving;
|
|
9056
9331
|
leavingIndex++;
|
|
9057
9332
|
updateNodeTimingParams(node, leaveToTimings);
|
|
9058
9333
|
} else if (node.isTarget) {
|
|
9059
9334
|
node.index = animatingIndex++;
|
|
9060
|
-
node.
|
|
9335
|
+
node.targets = animating;
|
|
9061
9336
|
updateNodeTimingParams(node, animationTimings);
|
|
9062
9337
|
} else {
|
|
9063
9338
|
node.index = animatedParent ? animatedParent.index : 0;
|
|
9064
|
-
node.
|
|
9339
|
+
node.targets = animating;
|
|
9065
9340
|
updateNodeTimingParams(node, swapAtTimings);
|
|
9066
9341
|
}
|
|
9067
9342
|
|
|
9068
9343
|
// Make sure the old state node has its inex and total values up to date for valid "from" function values calculation
|
|
9069
9344
|
oldStateNode.index = node.index;
|
|
9070
|
-
oldStateNode.
|
|
9345
|
+
oldStateNode.targets = node.targets;
|
|
9071
9346
|
|
|
9072
9347
|
// Computes all values up front so we can check for changes and we don't have to re-compute them inside the animation props
|
|
9073
9348
|
for (let prop in nodeProperties) {
|
|
9074
|
-
nodeProperties[prop] = getFunctionValue(nodeProperties[prop], $el, node.index, node.
|
|
9075
|
-
oldStateNodeProperties[prop] = getFunctionValue(oldStateNodeProperties[prop], $el, oldStateNode.index, oldStateNode.
|
|
9349
|
+
nodeProperties[prop] = getFunctionValue(nodeProperties[prop], $el, node.index, node.targets, null, null);
|
|
9350
|
+
oldStateNodeProperties[prop] = getFunctionValue(oldStateNodeProperties[prop], $el, oldStateNode.index, oldStateNode.targets, null, null);
|
|
9076
9351
|
}
|
|
9077
9352
|
|
|
9078
9353
|
// Use a 1px tolerance to detect dimensions changes to prevent width / height animations on barelly visible elements
|
|
@@ -9298,8 +9573,8 @@
|
|
|
9298
9573
|
}
|
|
9299
9574
|
$el.style.transform = oldState.getComputedValue($el, 'transform');
|
|
9300
9575
|
if (animatedSwap.includes($el)) {
|
|
9301
|
-
node.ease = getFunctionValue(swapAtParams.ease, $el, node.index, node.
|
|
9302
|
-
node.duration = getFunctionValue(swapAtParams.duration, $el, node.index, node.
|
|
9576
|
+
node.ease = getFunctionValue(swapAtParams.ease, $el, node.index, node.targets, null, null);
|
|
9577
|
+
node.duration = getFunctionValue(swapAtParams.duration, $el, node.index, node.targets, null, null);
|
|
9303
9578
|
}
|
|
9304
9579
|
}
|
|
9305
9580
|
this.transformAnimation = waapi.animate(transformed, {
|
|
@@ -9314,7 +9589,7 @@
|
|
|
9314
9589
|
if (!animatedSwap.includes($el)) return newValue;
|
|
9315
9590
|
const oldValue = oldState.getComputedValue($el, 'transform');
|
|
9316
9591
|
const node = newState.getNode($el);
|
|
9317
|
-
return [oldValue, getFunctionValue(swapAtProps.transform, $el, node.index, node.
|
|
9592
|
+
return [oldValue, getFunctionValue(swapAtProps.transform, $el, node.index, node.targets, null, null), newValue]
|
|
9318
9593
|
},
|
|
9319
9594
|
autoplay: false,
|
|
9320
9595
|
// persist: true,
|
|
@@ -9371,10 +9646,13 @@
|
|
|
9371
9646
|
const result = fn(...args);
|
|
9372
9647
|
return new Proxy(noop, {
|
|
9373
9648
|
apply: (_, __, [v]) => result(v),
|
|
9374
|
-
get: (_, prop) =>
|
|
9375
|
-
|
|
9376
|
-
return (/**@
|
|
9377
|
-
|
|
9649
|
+
get: (_, prop) => {
|
|
9650
|
+
if (!chainables[prop]) return undefined;
|
|
9651
|
+
return chain(/**@param {...Number|String} nextArgs */(...nextArgs) => {
|
|
9652
|
+
const nextResult = chainables[prop](...nextArgs);
|
|
9653
|
+
return (/**@type {Number|String} */v) => nextResult(result(v));
|
|
9654
|
+
})
|
|
9655
|
+
}
|
|
9378
9656
|
});
|
|
9379
9657
|
}
|
|
9380
9658
|
};
|
|
@@ -9585,24 +9863,28 @@
|
|
|
9585
9863
|
* @param {StaggerParams} [params]
|
|
9586
9864
|
* @return {StaggerFunction<Number>}
|
|
9587
9865
|
*/
|
|
9866
|
+
|
|
9588
9867
|
/**
|
|
9589
9868
|
* @overload
|
|
9590
9869
|
* @param {String} val
|
|
9591
9870
|
* @param {StaggerParams} [params]
|
|
9592
9871
|
* @return {StaggerFunction<String>}
|
|
9593
9872
|
*/
|
|
9873
|
+
|
|
9594
9874
|
/**
|
|
9595
9875
|
* @overload
|
|
9596
9876
|
* @param {[Number, Number]} val
|
|
9597
9877
|
* @param {StaggerParams} [params]
|
|
9598
9878
|
* @return {StaggerFunction<Number>}
|
|
9599
9879
|
*/
|
|
9880
|
+
|
|
9600
9881
|
/**
|
|
9601
9882
|
* @overload
|
|
9602
9883
|
* @param {[String, String]} val
|
|
9603
9884
|
* @param {StaggerParams} [params]
|
|
9604
9885
|
* @return {StaggerFunction<String>}
|
|
9605
9886
|
*/
|
|
9887
|
+
|
|
9606
9888
|
/**
|
|
9607
9889
|
* @param {Number|String|[Number, Number]|[String, String]} val The staggered value or range
|
|
9608
9890
|
* @param {StaggerParams} [params] The stagger parameters
|
|
@@ -9611,6 +9893,7 @@
|
|
|
9611
9893
|
const stagger = (val, params = {}) => {
|
|
9612
9894
|
let values = [];
|
|
9613
9895
|
let maxValue = 0;
|
|
9896
|
+
let cachedOffset;
|
|
9614
9897
|
const from = params.from;
|
|
9615
9898
|
const reversed = params.reversed;
|
|
9616
9899
|
const ease = params.ease;
|
|
@@ -9618,12 +9901,14 @@
|
|
|
9618
9901
|
const hasSpring = hasEasing && !isUnd(/** @type {Spring} */(ease).ease);
|
|
9619
9902
|
const staggerEase = hasSpring ? /** @type {Spring} */(ease).ease : hasEasing ? parseEase(ease) : null;
|
|
9620
9903
|
const grid = params.grid;
|
|
9904
|
+
const autoGrid = grid === true;
|
|
9621
9905
|
const axis = params.axis;
|
|
9622
9906
|
const customTotal = params.total;
|
|
9623
9907
|
const fromFirst = isUnd(from) || from === 0 || from === 'first';
|
|
9624
9908
|
const fromCenter = from === 'center';
|
|
9625
9909
|
const fromLast = from === 'last';
|
|
9626
9910
|
const fromRandom = from === 'random';
|
|
9911
|
+
const fromArr = isArr(from);
|
|
9627
9912
|
const isRange = isArr(val);
|
|
9628
9913
|
const useProp = params.use;
|
|
9629
9914
|
const val1 = isRange ? parseNumber(val[0]) : parseNumber(val);
|
|
@@ -9631,40 +9916,129 @@
|
|
|
9631
9916
|
const unitMatch = unitsExecRgx.exec((isRange ? val[1] : val) + emptyString);
|
|
9632
9917
|
const start = params.start || 0 + (isRange ? val1 : 0);
|
|
9633
9918
|
let fromIndex = fromFirst ? 0 : isNum(from) ? from : 0;
|
|
9634
|
-
return (target, i, t, tl) => {
|
|
9919
|
+
return (target, i, t, _, tl) => {
|
|
9635
9920
|
const [ registeredTarget ] = registerTargets(target);
|
|
9636
|
-
const total = isUnd(customTotal) ? t : customTotal;
|
|
9921
|
+
const total = isUnd(customTotal) ? t.length : customTotal;
|
|
9637
9922
|
const customIndex = !isUnd(useProp) ? isFnc(useProp) ? useProp(registeredTarget, i, total) : getOriginalAnimatableValue(registeredTarget, useProp) : false;
|
|
9638
9923
|
const staggerIndex = isNum(customIndex) || isStr(customIndex) && isNum(+customIndex) ? +customIndex : i;
|
|
9639
9924
|
if (fromCenter) fromIndex = (total - 1) / 2;
|
|
9640
9925
|
if (fromLast) fromIndex = total - 1;
|
|
9641
9926
|
if (!values.length) {
|
|
9642
|
-
|
|
9643
|
-
|
|
9644
|
-
|
|
9927
|
+
if (autoGrid) {
|
|
9928
|
+
let hasPositions = true;
|
|
9929
|
+
let minPosX = Infinity;
|
|
9930
|
+
let minPosY = Infinity;
|
|
9931
|
+
let maxPosX = -Infinity;
|
|
9932
|
+
let maxPosY = -Infinity;
|
|
9933
|
+
const pxArr = [];
|
|
9934
|
+
const pyArr = [];
|
|
9935
|
+
for (let index = 0; index < total; index++) {
|
|
9936
|
+
const el = t[index];
|
|
9937
|
+
let px = 0;
|
|
9938
|
+
let py = 0;
|
|
9939
|
+
let found = false;
|
|
9940
|
+
if (el && isFnc(el.getBoundingClientRect)) {
|
|
9941
|
+
const rect = el.getBoundingClientRect();
|
|
9942
|
+
px = rect.left + rect.width / 2;
|
|
9943
|
+
py = rect.top + rect.height / 2;
|
|
9944
|
+
found = true;
|
|
9945
|
+
} else {
|
|
9946
|
+
const obj = /** @type {JSTarget} */(el);
|
|
9947
|
+
if (obj && isNum(obj.x) && isNum(obj.y)) {
|
|
9948
|
+
px = obj.x;
|
|
9949
|
+
py = obj.y;
|
|
9950
|
+
found = true;
|
|
9951
|
+
}
|
|
9952
|
+
}
|
|
9953
|
+
if (!found) {
|
|
9954
|
+
hasPositions = false;
|
|
9955
|
+
break;
|
|
9956
|
+
}
|
|
9957
|
+
pxArr.push(px);
|
|
9958
|
+
pyArr.push(py);
|
|
9959
|
+
if (px < minPosX) minPosX = px;
|
|
9960
|
+
if (py < minPosY) minPosY = py;
|
|
9961
|
+
if (px > maxPosX) maxPosX = px;
|
|
9962
|
+
if (py > maxPosY) maxPosY = py;
|
|
9963
|
+
}
|
|
9964
|
+
if (hasPositions) {
|
|
9965
|
+
let fX = pxArr[0];
|
|
9966
|
+
let fY = pyArr[0];
|
|
9967
|
+
if (fromArr) {
|
|
9968
|
+
fX = minPosX + from[0] * (maxPosX - minPosX);
|
|
9969
|
+
fY = minPosY + from[1] * (maxPosY - minPosY);
|
|
9970
|
+
} else if (fromCenter) {
|
|
9971
|
+
fX = (minPosX + maxPosX) / 2;
|
|
9972
|
+
fY = (minPosY + maxPosY) / 2;
|
|
9973
|
+
} else if (fromLast) {
|
|
9974
|
+
fX = pxArr[total - 1];
|
|
9975
|
+
fY = pyArr[total - 1];
|
|
9976
|
+
} else if (isNum(from)) {
|
|
9977
|
+
fX = pxArr[from];
|
|
9978
|
+
fY = pyArr[from];
|
|
9979
|
+
}
|
|
9980
|
+
for (let index = 0; index < total; index++) {
|
|
9981
|
+
const distanceX = fX - pxArr[index];
|
|
9982
|
+
const distanceY = fY - pyArr[index];
|
|
9983
|
+
let value = sqrt(distanceX * distanceX + distanceY * distanceY);
|
|
9984
|
+
if (axis === 'x') value = -distanceX;
|
|
9985
|
+
if (axis === 'y') value = -distanceY;
|
|
9986
|
+
values.push(value);
|
|
9987
|
+
}
|
|
9988
|
+
let minDist = Infinity;
|
|
9989
|
+
for (let index = 0, l = values.length; index < l; index++) {
|
|
9990
|
+
const absVal = abs(values[index]);
|
|
9991
|
+
if (absVal > 0 && absVal < minDist) minDist = absVal;
|
|
9992
|
+
}
|
|
9993
|
+
if (minDist > 0 && minDist < Infinity) {
|
|
9994
|
+
for (let index = 0, l = values.length; index < l; index++) {
|
|
9995
|
+
values[index] = values[index] / minDist;
|
|
9996
|
+
}
|
|
9997
|
+
}
|
|
9645
9998
|
} else {
|
|
9646
|
-
|
|
9647
|
-
|
|
9648
|
-
|
|
9649
|
-
|
|
9650
|
-
|
|
9651
|
-
|
|
9652
|
-
|
|
9653
|
-
|
|
9654
|
-
|
|
9655
|
-
|
|
9999
|
+
for (let index = 0; index < total; index++) {
|
|
10000
|
+
values.push(abs(fromIndex - index));
|
|
10001
|
+
}
|
|
10002
|
+
}
|
|
10003
|
+
} else {
|
|
10004
|
+
for (let index = 0; index < total; index++) {
|
|
10005
|
+
if (!grid) {
|
|
10006
|
+
values.push(abs(fromIndex - index));
|
|
10007
|
+
} else {
|
|
10008
|
+
let fromX, fromY;
|
|
10009
|
+
if (fromArr) {
|
|
10010
|
+
fromX = from[0] * (grid[0] - 1);
|
|
10011
|
+
fromY = from[1] * (grid[1] - 1);
|
|
10012
|
+
} else if (fromCenter) {
|
|
10013
|
+
fromX = (grid[0] - 1) / 2;
|
|
10014
|
+
fromY = (grid[1] - 1) / 2;
|
|
10015
|
+
} else {
|
|
10016
|
+
fromX = fromIndex % grid[0];
|
|
10017
|
+
fromY = floor(fromIndex / grid[0]);
|
|
10018
|
+
}
|
|
10019
|
+
const toX = index % grid[0];
|
|
10020
|
+
const toY = floor(index / grid[0]);
|
|
10021
|
+
const distanceX = fromX - toX;
|
|
10022
|
+
const distanceY = fromY - toY;
|
|
10023
|
+
let value = sqrt(distanceX * distanceX + distanceY * distanceY);
|
|
10024
|
+
if (axis === 'x') value = -distanceX;
|
|
10025
|
+
if (axis === 'y') value = -distanceY;
|
|
10026
|
+
values.push(value);
|
|
10027
|
+
}
|
|
9656
10028
|
}
|
|
9657
|
-
maxValue = max(...values);
|
|
9658
10029
|
}
|
|
10030
|
+
maxValue = max(...values);
|
|
9659
10031
|
if (staggerEase) values = values.map(val => staggerEase(val / maxValue) * maxValue);
|
|
9660
10032
|
if (reversed) values = values.map(val => axis ? (val < 0) ? val * -1 : -val : abs(maxValue - val));
|
|
9661
10033
|
if (fromRandom) values = shuffle(values);
|
|
9662
10034
|
}
|
|
9663
10035
|
const spacing = isRange ? (val2 - val1) / maxValue : val1;
|
|
9664
|
-
|
|
10036
|
+
if (isUnd(cachedOffset)) {
|
|
10037
|
+
cachedOffset = tl ? parseTimelinePosition(tl, isUnd(params.start) ? tl.iterationDuration : start) : /** @type {Number} */(start);
|
|
10038
|
+
}
|
|
9665
10039
|
/** @type {String|Number} */
|
|
9666
|
-
let output =
|
|
9667
|
-
if (params.modifier) output = params.modifier(output);
|
|
10040
|
+
let output = cachedOffset + ((spacing * round$1(values[staggerIndex], 2)) || 0);
|
|
10041
|
+
if (params.modifier) output = params.modifier(/** @type {Number} */(output));
|
|
9668
10042
|
if (unitMatch) output = `${output}${unitMatch[2]}`;
|
|
9669
10043
|
return output;
|
|
9670
10044
|
}
|
|
@@ -9673,11 +10047,13 @@
|
|
|
9673
10047
|
var index$2 = /*#__PURE__*/Object.freeze({
|
|
9674
10048
|
__proto__: null,
|
|
9675
10049
|
$: registerTargets,
|
|
10050
|
+
addChild: addChild,
|
|
9676
10051
|
clamp: clamp,
|
|
9677
10052
|
cleanInlineStyles: cleanInlineStyles,
|
|
9678
10053
|
createSeededRandom: createSeededRandom,
|
|
9679
10054
|
damp: damp,
|
|
9680
10055
|
degToRad: degToRad,
|
|
10056
|
+
forEachChildren: forEachChildren,
|
|
9681
10057
|
get: get,
|
|
9682
10058
|
keepTime: keepTime,
|
|
9683
10059
|
lerp: lerp,
|
|
@@ -9688,6 +10064,7 @@
|
|
|
9688
10064
|
random: random,
|
|
9689
10065
|
randomPick: randomPick,
|
|
9690
10066
|
remove: remove,
|
|
10067
|
+
removeChild: removeChild,
|
|
9691
10068
|
round: round,
|
|
9692
10069
|
roundPad: roundPad,
|
|
9693
10070
|
set: set,
|
|
@@ -9887,7 +10264,7 @@
|
|
|
9887
10264
|
* @param {Number} [precision]
|
|
9888
10265
|
* @return {FunctionValue}
|
|
9889
10266
|
*/
|
|
9890
|
-
const morphTo = (path2, precision = .33) => ($path1) => {
|
|
10267
|
+
const morphTo = (path2, precision = .33) => ($path1, index, total, prevTween) => {
|
|
9891
10268
|
const tagName1 = ($path1.tagName || '').toLowerCase();
|
|
9892
10269
|
if (!tagName1.match(/^(path|polygon|polyline)$/)) {
|
|
9893
10270
|
throw new Error(`Can't morph a <${$path1.tagName}> SVG element. Use <path>, <polygon> or <polyline>.`);
|
|
@@ -9902,7 +10279,7 @@
|
|
|
9902
10279
|
}
|
|
9903
10280
|
const isPath = $path1.tagName === 'path';
|
|
9904
10281
|
const separator = isPath ? ' ' : ',';
|
|
9905
|
-
const previousPoints =
|
|
10282
|
+
const previousPoints = prevTween ? prevTween._value : null;
|
|
9906
10283
|
if (previousPoints) $path1.setAttribute(isPath ? 'd' : 'points', previousPoints);
|
|
9907
10284
|
|
|
9908
10285
|
let v1 = '', v2 = '';
|
|
@@ -9924,8 +10301,6 @@
|
|
|
9924
10301
|
}
|
|
9925
10302
|
}
|
|
9926
10303
|
|
|
9927
|
-
$path1[morphPointsSymbol] = v2;
|
|
9928
|
-
|
|
9929
10304
|
return [v1, v2];
|
|
9930
10305
|
};
|
|
9931
10306
|
|
|
@@ -10111,7 +10486,7 @@
|
|
|
10111
10486
|
*/
|
|
10112
10487
|
class TextSplitter {
|
|
10113
10488
|
/**
|
|
10114
|
-
* @param {
|
|
10489
|
+
* @param {Element|NodeList|String|Array<Element>} target
|
|
10115
10490
|
* @param {TextSplitterParams} [parameters]
|
|
10116
10491
|
*/
|
|
10117
10492
|
constructor(target, parameters = {}) {
|
|
@@ -10183,11 +10558,11 @@
|
|
|
10183
10558
|
}
|
|
10184
10559
|
|
|
10185
10560
|
/**
|
|
10186
|
-
* @param {(...args: any[]) => Tickable | (() => void)} effect
|
|
10561
|
+
* @param {(...args: any[]) => Tickable | (() => void) | void} effect
|
|
10187
10562
|
* @return this
|
|
10188
10563
|
*/
|
|
10189
10564
|
addEffect(effect) {
|
|
10190
|
-
if (!isFnc(effect))
|
|
10565
|
+
if (!isFnc(effect)) { console.warn('Effect must return a function.'); return this; }
|
|
10191
10566
|
const refreshableEffect = keepTime(effect);
|
|
10192
10567
|
this.effects.push(refreshableEffect);
|
|
10193
10568
|
if (this.ready) this.effectsCleanups[this.effects.length - 1] = refreshableEffect(this);
|
|
@@ -10393,7 +10768,7 @@
|
|
|
10393
10768
|
}
|
|
10394
10769
|
|
|
10395
10770
|
/**
|
|
10396
|
-
* @param {
|
|
10771
|
+
* @param {Element|NodeList|String|Array<Element>} target
|
|
10397
10772
|
* @param {TextSplitterParams} [parameters]
|
|
10398
10773
|
* @return {TextSplitter}
|
|
10399
10774
|
*/
|
|
@@ -10411,9 +10786,261 @@
|
|
|
10411
10786
|
return new TextSplitter(target, parameters);
|
|
10412
10787
|
};
|
|
10413
10788
|
|
|
10789
|
+
|
|
10790
|
+
|
|
10791
|
+
/**
|
|
10792
|
+
* '-' 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-')
|
|
10793
|
+
* @param {String} str
|
|
10794
|
+
* @return {String}
|
|
10795
|
+
*/
|
|
10796
|
+
const expandCharRanges = (str) => {
|
|
10797
|
+
let result = '';
|
|
10798
|
+
for (let i = 0, l = str.length; i < l; i++) {
|
|
10799
|
+
if (i + 2 < l && str[i + 1] === '-' && str.charCodeAt(i) < str.charCodeAt(i + 2)) {
|
|
10800
|
+
const start = str.charCodeAt(i);
|
|
10801
|
+
const end = str.charCodeAt(i + 2);
|
|
10802
|
+
for (let c = start; c <= end; c++) result += String.fromCharCode(c);
|
|
10803
|
+
i += 2;
|
|
10804
|
+
} else {
|
|
10805
|
+
result += str[i];
|
|
10806
|
+
}
|
|
10807
|
+
}
|
|
10808
|
+
return result;
|
|
10809
|
+
};
|
|
10810
|
+
|
|
10811
|
+
const charSets = {
|
|
10812
|
+
lowercase: 'a-z',
|
|
10813
|
+
uppercase: 'A-Z',
|
|
10814
|
+
numbers: '0-9',
|
|
10815
|
+
symbols: '!%#_|*+=',
|
|
10816
|
+
braille: '⠀-⣿',
|
|
10817
|
+
blocks: '▀-▟',
|
|
10818
|
+
shades: '░-▓',
|
|
10819
|
+
};
|
|
10820
|
+
|
|
10821
|
+
const originalTexts = new WeakMap();
|
|
10822
|
+
|
|
10823
|
+
/**
|
|
10824
|
+
* Returns a function-based tween value that scrambles the target's text content,
|
|
10825
|
+
* progressively revealing the original text.
|
|
10826
|
+
*
|
|
10827
|
+
* @param {ScrambleTextParams} [params]
|
|
10828
|
+
* @return {FunctionValue}
|
|
10829
|
+
*/
|
|
10830
|
+
const scrambleText = (params = {}) => {
|
|
10831
|
+
if (!params) params = {};
|
|
10832
|
+
const charsParam = params.chars;
|
|
10833
|
+
const easeFn = parseEase(params.ease || 'linear');
|
|
10834
|
+
const text = params.text;
|
|
10835
|
+
const fromParam = params.from;
|
|
10836
|
+
const reversed = params.reversed || false;
|
|
10837
|
+
const perturbation = params.perturbation || 0;
|
|
10838
|
+
const cursorParam = params.cursor;
|
|
10839
|
+
const cursorChars = cursorParam === true ? '_'
|
|
10840
|
+
: typeof cursorParam === 'number' ? String.fromCharCode(cursorParam)
|
|
10841
|
+
: typeof cursorParam === 'string' ? cursorParam
|
|
10842
|
+
: '';
|
|
10843
|
+
const cursorLen = cursorChars.length;
|
|
10844
|
+
const seed = params.seed || 0;
|
|
10845
|
+
const override = params.override !== undefined ? params.override : true;
|
|
10846
|
+
const revealRate = params.revealRate || 60;
|
|
10847
|
+
const interval = 1000 * globals.timeScale / revealRate;
|
|
10848
|
+
const settleDuration = params.settleDuration || 300 * globals.timeScale;
|
|
10849
|
+
const settleRate = params.settleRate || 30;
|
|
10850
|
+
const durationParam = params.duration;
|
|
10851
|
+
const revealDelayParam = params.revealDelay;
|
|
10852
|
+
const delayParam = params.delay;
|
|
10853
|
+
const onChange = params.onChange || noop;
|
|
10854
|
+
|
|
10855
|
+
return (target, index, targets, prevTween) => {
|
|
10856
|
+
const rawChars = typeof charsParam === 'function' ? charsParam(target, index, targets) : (charsParam || 'a-zA-Z0-9!%#_');
|
|
10857
|
+
const characters = expandCharRanges(charSets[rawChars] || rawChars);
|
|
10858
|
+
const totalChars = characters.length - 1;
|
|
10859
|
+
const duration = typeof durationParam === 'function' ? durationParam(target, index, targets) : durationParam;
|
|
10860
|
+
const revealDelay = typeof revealDelayParam === 'function' ? revealDelayParam(target, index, targets) : (revealDelayParam || 0);
|
|
10861
|
+
const delay = typeof delayParam === 'function' ? delayParam(target, index, targets) : (delayParam || 0);
|
|
10862
|
+
const rng = seed ? createSeededRandom(seed) : createSeededRandom();
|
|
10863
|
+
if (!originalTexts.has(target)) originalTexts.set(target, target.textContent);
|
|
10864
|
+
const startingText = prevTween ? prevTween._value : target.textContent;
|
|
10865
|
+
const targetText = text !== undefined
|
|
10866
|
+
? (typeof text === 'function' ? text(target, index, targets) : text)
|
|
10867
|
+
: prevTween ? prevTween._value
|
|
10868
|
+
: originalTexts.get(target);
|
|
10869
|
+
const settledText = targetText === ' ' || targetText === ' ' ? ' ' : targetText;
|
|
10870
|
+
const startLength = startingText === ' ' ? 0 : startingText.length;
|
|
10871
|
+
const endLength = settledText.length;
|
|
10872
|
+
const overrideChars = override === true ? characters
|
|
10873
|
+
: typeof override === 'string' && override.length > 0 ? expandCharRanges(charSets[/** @type {String} */(override)] || /** @type {String} */(override))
|
|
10874
|
+
: null;
|
|
10875
|
+
const totalOverrideChars = overrideChars ? overrideChars.length - 1 : 0;
|
|
10876
|
+
// Space override uses so the browser doesn't collapse consecutive spaces in innerHTML
|
|
10877
|
+
const overrideChar = override === ' ' ? ' ' : null;
|
|
10878
|
+
// When starting from blank, only animate the target text length to avoid padding beyond it
|
|
10879
|
+
const animLength = override === '' ? endLength : Math.max(startLength, endLength);
|
|
10880
|
+
// Compute total duration from interval spacing and settle time, or use the explicit duration
|
|
10881
|
+
const animDuration = duration > 0 ? duration : (animLength - 1) * interval + settleDuration;
|
|
10882
|
+
const computedDuration = round$1((animDuration + revealDelay) / globals.timeScale, 0) * globals.timeScale;
|
|
10883
|
+
const revealDelayRatio = revealDelay > 0 ? round$1(revealDelay / computedDuration, 12) : 0;
|
|
10884
|
+
// Auto-resolve reveal direction: shrinking text reveals from right, growing from left
|
|
10885
|
+
const resolvedFrom = fromParam === undefined || fromParam === 'auto' ? (endLength < startLength ? 'right' : 'left') : fromParam;
|
|
10886
|
+
const charOrder = new Int32Array(animLength);
|
|
10887
|
+
if (resolvedFrom === 'random') {
|
|
10888
|
+
for (let i = 0; i < animLength; i++) charOrder[i] = i;
|
|
10889
|
+
for (let i = animLength - 1; i > 0; i--) {
|
|
10890
|
+
const j = rng(0, i);
|
|
10891
|
+
const t = charOrder[i]; charOrder[i] = charOrder[j]; charOrder[j] = t;
|
|
10892
|
+
}
|
|
10893
|
+
} else {
|
|
10894
|
+
const ref = resolvedFrom === 'right' ? (override === '' || !startLength ? animLength : startLength) - 1
|
|
10895
|
+
: resolvedFrom === 'center' ? ((override === '' || !startLength ? animLength : startLength) - 1) / 2
|
|
10896
|
+
: typeof resolvedFrom === 'number' ? resolvedFrom
|
|
10897
|
+
: 0;
|
|
10898
|
+
const abs = Math.abs;
|
|
10899
|
+
const indices = new Array(animLength);
|
|
10900
|
+
for (let i = 0; i < animLength; i++) indices[i] = i;
|
|
10901
|
+
indices.sort((a, b) => abs(a - ref) - abs(b - ref));
|
|
10902
|
+
for (let i = 0; i < animLength; i++) charOrder[indices[i]] = i;
|
|
10903
|
+
}
|
|
10904
|
+
if (reversed) {
|
|
10905
|
+
const last = animLength - 1;
|
|
10906
|
+
for (let i = 0; i < animLength; i++) charOrder[i] = last - charOrder[i];
|
|
10907
|
+
}
|
|
10908
|
+
// settleRatio is the fraction of the animation each character spends in the active scrambling zone
|
|
10909
|
+
const settleRatio = round$1(settleDuration / animDuration, 12);
|
|
10910
|
+
// settleSpacing is the time gap between consecutive characters entering the active zone
|
|
10911
|
+
const settleSpacing = round$1((1 - settleRatio) / animLength, 12);
|
|
10912
|
+
const cursorZone = cursorLen * settleSpacing;
|
|
10913
|
+
// stepRatio controls how often scramble characters refresh (based on settleRate)
|
|
10914
|
+
const stepRatio = round$1(1000 * globals.timeScale / (settleRate * computedDuration), 12);
|
|
10915
|
+
// Pre-compute per-character start and settle times
|
|
10916
|
+
const charStarts = new Float32Array(animLength);
|
|
10917
|
+
const charEnds = new Float32Array(animLength);
|
|
10918
|
+
const scale = perturbation > 0 ? perturbation * settleRatio : 0;
|
|
10919
|
+
for (let c = 0; c < animLength; c++) {
|
|
10920
|
+
const so = scale > 0 ? (rng(0, 2000) - 1000) / 1000 * scale : 0;
|
|
10921
|
+
const eo = scale > 0 ? (rng(0, 2000) - 1000) / 1000 * scale : 0;
|
|
10922
|
+
charStarts[c] = charOrder[c] * settleSpacing + so;
|
|
10923
|
+
charEnds[c] = Math.ceil((charStarts[c] + settleRatio + eo) / stepRatio) * stepRatio;
|
|
10924
|
+
}
|
|
10925
|
+
// When text shrinks with non-sequential from modes, delay target settle times past all extras
|
|
10926
|
+
if (endLength < animLength && resolvedFrom !== 'left' && resolvedFrom !== 'right' && resolvedFrom !== 'random') {
|
|
10927
|
+
let maxExtraEnd = 0;
|
|
10928
|
+
for (let c = endLength; c < animLength; c++) {
|
|
10929
|
+
if (charEnds[c] > maxExtraEnd) maxExtraEnd = charEnds[c];
|
|
10930
|
+
}
|
|
10931
|
+
const targets = new Array(endLength);
|
|
10932
|
+
for (let c = 0; c < endLength; c++) targets[c] = c;
|
|
10933
|
+
targets.sort((a, b) => charOrder[a] - charOrder[b]);
|
|
10934
|
+
const targetSpacing = (1 - maxExtraEnd) / endLength;
|
|
10935
|
+
for (let i = 0; i < endLength; i++) {
|
|
10936
|
+
const revealTime = maxExtraEnd + i * targetSpacing;
|
|
10937
|
+
if (revealTime > charEnds[targets[i]]) {
|
|
10938
|
+
charEnds[targets[i]] = revealTime;
|
|
10939
|
+
}
|
|
10940
|
+
}
|
|
10941
|
+
}
|
|
10942
|
+
// charCache holds the current scramble character for each position, refreshed at settleRate
|
|
10943
|
+
const charCache = new Array(animLength);
|
|
10944
|
+
for (let c = 0; c < animLength; c++) {
|
|
10945
|
+
charCache[c] = characters[rng(0, totalChars)];
|
|
10946
|
+
}
|
|
10947
|
+
// overrideCache holds scramble characters for the starting text (override: true or custom string)
|
|
10948
|
+
const overrideCache = overrideChars ? (overrideChars === characters ? charCache : new Array(animLength)) : null;
|
|
10949
|
+
if (overrideCache && overrideCache !== charCache) {
|
|
10950
|
+
for (let c = 0; c < animLength; c++) {
|
|
10951
|
+
overrideCache[c] = overrideChar || /** @type {String} */(overrideChars)[rng(0, overrideChars.length - 1)];
|
|
10952
|
+
}
|
|
10953
|
+
}
|
|
10954
|
+
// Build the initial display text based on override mode
|
|
10955
|
+
let fillStartText = startingText;
|
|
10956
|
+
if (!prevTween) {
|
|
10957
|
+
if (override === '') {
|
|
10958
|
+
fillStartText = '';
|
|
10959
|
+
} else if (overrideChars) {
|
|
10960
|
+
fillStartText = '';
|
|
10961
|
+
for (let c = 0; c < startLength; c++) {
|
|
10962
|
+
fillStartText += startingText[c] === ' ' ? ' ' : /** @type {Array<String>} */(overrideCache)[c];
|
|
10963
|
+
}
|
|
10964
|
+
}
|
|
10965
|
+
}
|
|
10966
|
+
|
|
10967
|
+
let lastValue = -1;
|
|
10968
|
+
let lastStep = -1;
|
|
10969
|
+
let scrambled = '';
|
|
10970
|
+
const hasOverride = override !== '';
|
|
10971
|
+
const hasOverrideChars = !!overrideChars;
|
|
10972
|
+
const hasCursor = cursorLen > 0;
|
|
10973
|
+
|
|
10974
|
+
return {
|
|
10975
|
+
from: 0,
|
|
10976
|
+
to: 1,
|
|
10977
|
+
duration: computedDuration,
|
|
10978
|
+
delay: delay,
|
|
10979
|
+
ease: 'linear',
|
|
10980
|
+
modifier: (v) => {
|
|
10981
|
+
if (v === lastValue) return scrambled;
|
|
10982
|
+
lastValue = v;
|
|
10983
|
+
if (delay > 0 && v <= 0) { scrambled = startingText; return startingText; }
|
|
10984
|
+
if (v <= 0) { scrambled = fillStartText; return fillStartText; }
|
|
10985
|
+
if (v >= 1) { scrambled = settledText; return settledText; }
|
|
10986
|
+
scrambled = '';
|
|
10987
|
+
// Only refresh scramble characters when we cross a settleRate step boundary
|
|
10988
|
+
const currentStep = (v / stepRatio) | 0;
|
|
10989
|
+
const refreshChars = currentStep !== lastStep;
|
|
10990
|
+
if (refreshChars) lastStep = currentStep;
|
|
10991
|
+
// Subtract delay ratio to get the effective animation progress
|
|
10992
|
+
const linear = revealDelayRatio > 0 ? (v - revealDelayRatio) / (1 - revealDelayRatio) : v;
|
|
10993
|
+
const t = linear > 0 ? easeFn(linear) : 0;
|
|
10994
|
+
for (let c = 0; c < animLength; c++) {
|
|
10995
|
+
// Each character has its own start/end window based on its reveal order
|
|
10996
|
+
const charStart = charStarts[c];
|
|
10997
|
+
const charEnd = charEnds[c];
|
|
10998
|
+
// Settled zone: character has finished its transition
|
|
10999
|
+
if (t >= charEnd) {
|
|
11000
|
+
if (c < endLength) scrambled += settledText[c];
|
|
11001
|
+
continue;
|
|
11002
|
+
}
|
|
11003
|
+
// Pre-transition zone: reveal wave hasn't reached this character yet
|
|
11004
|
+
if (t <= 0 || t < charStart) {
|
|
11005
|
+
if (hasOverride && c < startLength) {
|
|
11006
|
+
if (hasOverrideChars) {
|
|
11007
|
+
if (startingText[c] === ' ') {
|
|
11008
|
+
scrambled += ' ';
|
|
11009
|
+
} else {
|
|
11010
|
+
if (refreshChars) /** @type {Array<String>} */(overrideCache)[c] = overrideChar || /** @type {String} */(overrideChars)[rng(0, totalOverrideChars)];
|
|
11011
|
+
scrambled += /** @type {Array<String>} */(overrideCache)[c];
|
|
11012
|
+
}
|
|
11013
|
+
} else {
|
|
11014
|
+
// Default (override: false): show the original starting text
|
|
11015
|
+
scrambled += startingText[c];
|
|
11016
|
+
}
|
|
11017
|
+
}
|
|
11018
|
+
continue;
|
|
11019
|
+
}
|
|
11020
|
+
// Active zone: character is between charStart and charEnd
|
|
11021
|
+
const isSpace = (c < endLength && settledText[c] === ' ') || (c < startLength && startingText[c] === ' ');
|
|
11022
|
+
if (isSpace) {
|
|
11023
|
+
scrambled += ' ';
|
|
11024
|
+
} else if (hasCursor && t - charStart < cursorZone) {
|
|
11025
|
+
// Cursor sub-zone: show cursor character based on position within cursor width
|
|
11026
|
+
scrambled += cursorChars[cursorLen - 1 - (((t - charStart) / settleSpacing) | 0)];
|
|
11027
|
+
} else {
|
|
11028
|
+
// Scramble zone: show cycling random characters
|
|
11029
|
+
if (refreshChars) charCache[c] = characters[rng(0, totalChars)];
|
|
11030
|
+
scrambled += charCache[c];
|
|
11031
|
+
}
|
|
11032
|
+
}
|
|
11033
|
+
if (refreshChars) onChange(scrambled, t);
|
|
11034
|
+
return scrambled;
|
|
11035
|
+
}
|
|
11036
|
+
}
|
|
11037
|
+
}
|
|
11038
|
+
};
|
|
11039
|
+
|
|
10414
11040
|
var index = /*#__PURE__*/Object.freeze({
|
|
10415
11041
|
__proto__: null,
|
|
10416
11042
|
TextSplitter: TextSplitter,
|
|
11043
|
+
scrambleText: scrambleText,
|
|
10417
11044
|
split: split,
|
|
10418
11045
|
splitText: splitText
|
|
10419
11046
|
});
|
|
@@ -10430,6 +11057,7 @@
|
|
|
10430
11057
|
exports.Timeline = Timeline;
|
|
10431
11058
|
exports.Timer = Timer;
|
|
10432
11059
|
exports.WAAPIAnimation = WAAPIAnimation;
|
|
11060
|
+
exports.addChild = addChild;
|
|
10433
11061
|
exports.animate = animate;
|
|
10434
11062
|
exports.clamp = clamp;
|
|
10435
11063
|
exports.cleanInlineStyles = cleanInlineStyles;
|
|
@@ -10449,7 +11077,9 @@
|
|
|
10449
11077
|
exports.eases = eases;
|
|
10450
11078
|
exports.easings = index$3;
|
|
10451
11079
|
exports.engine = engine;
|
|
11080
|
+
exports.forEachChildren = forEachChildren;
|
|
10452
11081
|
exports.get = get;
|
|
11082
|
+
exports.globals = globals;
|
|
10453
11083
|
exports.irregular = irregular;
|
|
10454
11084
|
exports.keepTime = keepTime;
|
|
10455
11085
|
exports.lerp = lerp;
|
|
@@ -10463,8 +11093,10 @@
|
|
|
10463
11093
|
exports.random = random;
|
|
10464
11094
|
exports.randomPick = randomPick;
|
|
10465
11095
|
exports.remove = remove;
|
|
11096
|
+
exports.removeChild = removeChild;
|
|
10466
11097
|
exports.round = round;
|
|
10467
11098
|
exports.roundPad = roundPad;
|
|
11099
|
+
exports.scrambleText = scrambleText;
|
|
10468
11100
|
exports.scrollContainers = scrollContainers;
|
|
10469
11101
|
exports.set = set;
|
|
10470
11102
|
exports.shuffle = shuffle;
|