animejs 4.4.1 → 4.5.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 +2 -3
- package/dist/bundles/anime.esm.js +462 -213
- package/dist/bundles/anime.esm.min.js +2 -2
- package/dist/bundles/anime.umd.js +462 -213
- package/dist/bundles/anime.umd.min.js +2 -2
- package/dist/modules/adapters/index.cjs +14 -0
- package/dist/modules/adapters/index.d.ts +1 -0
- package/dist/modules/adapters/index.js +8 -0
- package/dist/modules/adapters/registry.cjs +149 -0
- package/dist/modules/adapters/registry.d.ts +65 -0
- package/dist/modules/adapters/registry.js +146 -0
- package/dist/modules/adapters/three/adapter.cjs +26 -0
- package/dist/modules/adapters/three/adapter.d.ts +15 -0
- package/dist/modules/adapters/three/adapter.js +24 -0
- package/dist/modules/adapters/three/helpers.cjs +297 -0
- package/dist/modules/adapters/three/helpers.d.ts +89 -0
- package/dist/modules/adapters/three/helpers.js +280 -0
- package/dist/modules/adapters/three/index.cjs +20 -0
- package/dist/modules/adapters/three/index.d.ts +2 -0
- package/dist/modules/adapters/three/index.js +12 -0
- package/dist/modules/adapters/three/instance.cjs +368 -0
- package/dist/modules/adapters/three/instance.d.ts +133 -0
- package/dist/modules/adapters/three/instance.js +365 -0
- package/dist/modules/adapters/three/object3d.cjs +214 -0
- package/dist/modules/adapters/three/object3d.d.ts +1 -0
- package/dist/modules/adapters/three/object3d.js +212 -0
- package/dist/modules/adapters/three/resolvers.cjs +105 -0
- package/dist/modules/adapters/three/resolvers.d.ts +1 -0
- package/dist/modules/adapters/three/resolvers.js +103 -0
- package/dist/modules/adapters/three/uniform.cjs +41 -0
- package/dist/modules/adapters/three/uniform.d.ts +1 -0
- package/dist/modules/adapters/three/uniform.js +39 -0
- package/dist/modules/animatable/animatable.cjs +2 -1
- package/dist/modules/animatable/animatable.d.ts +2 -1
- package/dist/modules/animatable/animatable.js +2 -1
- 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 +43 -16
- package/dist/modules/animation/animation.d.ts +5 -0
- package/dist/modules/animation/animation.js +45 -18
- package/dist/modules/animation/composition.cjs +38 -35
- package/dist/modules/animation/composition.js +38 -35
- package/dist/modules/animation/index.cjs +1 -1
- package/dist/modules/animation/index.js +1 -1
- package/dist/modules/core/clock.cjs +11 -15
- package/dist/modules/core/clock.d.ts +0 -2
- package/dist/modules/core/clock.js +11 -15
- package/dist/modules/core/colors.cjs +1 -1
- package/dist/modules/core/colors.js +1 -1
- package/dist/modules/core/consts.cjs +15 -1
- package/dist/modules/core/consts.d.ts +2 -0
- package/dist/modules/core/consts.js +14 -2
- package/dist/modules/core/globals.cjs +7 -4
- package/dist/modules/core/globals.d.ts +8 -2
- package/dist/modules/core/globals.js +8 -5
- package/dist/modules/core/helpers.cjs +2 -2
- package/dist/modules/core/helpers.js +3 -3
- package/dist/modules/core/render.cjs +64 -14
- package/dist/modules/core/render.js +65 -15
- package/dist/modules/core/styles.cjs +16 -2
- package/dist/modules/core/styles.js +16 -2
- package/dist/modules/core/targets.cjs +11 -13
- package/dist/modules/core/targets.js +11 -13
- package/dist/modules/core/transforms.cjs +1 -1
- package/dist/modules/core/transforms.js +1 -1
- package/dist/modules/core/units.cjs +1 -1
- package/dist/modules/core/units.js +1 -1
- package/dist/modules/core/values.cjs +73 -82
- package/dist/modules/core/values.d.ts +1 -2
- package/dist/modules/core/values.js +76 -84
- 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 +3 -3
- package/dist/modules/easings/eases/parser.d.ts +4 -5
- package/dist/modules/easings/eases/parser.js +3 -3
- 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 +4 -2
- package/dist/modules/engine/engine.js +4 -2
- 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 +3 -1
- package/dist/modules/events/scroll.js +3 -1
- package/dist/modules/index.cjs +1 -1
- package/dist/modules/index.js +1 -1
- package/dist/modules/layout/index.cjs +1 -1
- package/dist/modules/layout/index.js +1 -1
- package/dist/modules/layout/layout.cjs +1 -1
- package/dist/modules/layout/layout.js +1 -1
- 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 +1 -1
- package/dist/modules/svg/morphto.js +1 -1
- package/dist/modules/svg/motionpath.cjs +1 -1
- package/dist/modules/svg/motionpath.js +1 -1
- package/dist/modules/text/index.cjs +1 -1
- package/dist/modules/text/index.js +1 -1
- package/dist/modules/text/scramble.cjs +12 -2
- package/dist/modules/text/scramble.d.ts +9 -1
- package/dist/modules/text/scramble.js +12 -2
- package/dist/modules/text/split.cjs +2 -1
- package/dist/modules/text/split.js +2 -1
- 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 +14 -5
- package/dist/modules/timeline/timeline.d.ts +3 -3
- package/dist/modules/timeline/timeline.js +14 -5
- package/dist/modules/timer/index.cjs +1 -1
- package/dist/modules/timer/index.js +1 -1
- package/dist/modules/timer/timer.cjs +1 -1
- package/dist/modules/timer/timer.js +1 -1
- package/dist/modules/types/index.d.ts +36 -11
- package/dist/modules/utils/chainable.cjs +1 -1
- package/dist/modules/utils/chainable.js +1 -1
- package/dist/modules/utils/index.cjs +1 -1
- package/dist/modules/utils/index.js +1 -1
- package/dist/modules/utils/number.cjs +1 -1
- package/dist/modules/utils/number.js +1 -1
- package/dist/modules/utils/random.cjs +4 -3
- package/dist/modules/utils/random.d.ts +1 -1
- package/dist/modules/utils/random.js +4 -3
- package/dist/modules/utils/stagger.cjs +67 -13
- package/dist/modules/utils/stagger.js +69 -15
- package/dist/modules/utils/target.cjs +4 -1
- package/dist/modules/utils/target.js +4 -1
- package/dist/modules/utils/time.cjs +6 -5
- package/dist/modules/utils/time.d.ts +1 -1
- package/dist/modules/utils/time.js +6 -5
- 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 +1 -1
- package/dist/modules/waapi/waapi.js +1 -1
- package/package.json +38 -5
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Anime.js - ESM bundle
|
|
3
|
-
* @version v4.
|
|
3
|
+
* @version v4.5.0
|
|
4
4
|
* @license MIT
|
|
5
5
|
* @copyright 2026 - Julian Garnier
|
|
6
6
|
*/
|
|
@@ -39,6 +39,12 @@
|
|
|
39
39
|
/** @typedef {Timer&JSAnimation&Timeline} CallbackArgument */
|
|
40
40
|
/** @typedef {Animatable|Tickable|WAAPIAnimation|Draggable|ScrollObserver|TextSplitter|Scope|AutoLayout} Revertible */
|
|
41
41
|
|
|
42
|
+
/**
|
|
43
|
+
* @typedef {Object} TweakRegister
|
|
44
|
+
* @property {String} type
|
|
45
|
+
* @property {*} defaultValue
|
|
46
|
+
*/
|
|
47
|
+
|
|
42
48
|
// Stagger types
|
|
43
49
|
|
|
44
50
|
/**
|
|
@@ -58,11 +64,18 @@
|
|
|
58
64
|
* @property {Number|'first'|'center'|'last'|'random'|Array.<Number>} [from]
|
|
59
65
|
* @property {Boolean} [reversed]
|
|
60
66
|
* @property {Array.<Number>|Boolean} [grid]
|
|
61
|
-
* @property {('x'|'y')} [axis]
|
|
62
|
-
* @property {String|(
|
|
67
|
+
* @property {('x'|'y'|'z')} [axis]
|
|
68
|
+
* @property {String | { method(target: Target, i: Number, length: Number): Number }['method']} [use]
|
|
63
69
|
* @property {Number} [total]
|
|
64
70
|
* @property {EasingParam} [ease]
|
|
65
71
|
* @property {TweenModifier} [modifier]
|
|
72
|
+
* @property {Number|[Number, Number]} [jitter] Additive uniform noise on the
|
|
73
|
+
* computed stagger value. Number form gives flat `+/-jitter`; tuple form
|
|
74
|
+
* ramps the magnitude `start -> end` across the from/axis/grid ordering
|
|
75
|
+
* and respects `ease`.
|
|
76
|
+
* @property {Boolean|Number} [seed] Seed for jitter draws and `from: 'random'`
|
|
77
|
+
* shuffling. `false` (default) uses Math.random. `true` seeds with `0`. A
|
|
78
|
+
* number is used directly as the seed.
|
|
66
79
|
*/
|
|
67
80
|
|
|
68
81
|
// Targets types
|
|
@@ -138,10 +151,7 @@
|
|
|
138
151
|
|
|
139
152
|
/**
|
|
140
153
|
* @template T
|
|
141
|
-
* @
|
|
142
|
-
* @param {T} self - Returns itself
|
|
143
|
-
* @param {PointerEvent} [e]
|
|
144
|
-
* @return {*}
|
|
154
|
+
* @typedef {{ method(self: T): * }['method']} Callback
|
|
145
155
|
*/
|
|
146
156
|
|
|
147
157
|
/**
|
|
@@ -185,12 +195,17 @@
|
|
|
185
195
|
// Tween types
|
|
186
196
|
|
|
187
197
|
/**
|
|
198
|
+
* @typedef {Number|String|TweenKeyValue|EasingParam|Array.<Number|String|TweenKeyValue>} FunctionValueReturn
|
|
199
|
+
*/
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* @template [T=FunctionValueReturn]
|
|
188
203
|
* @callback FunctionValue
|
|
189
204
|
* @param {Target} [target] - The animated target
|
|
190
205
|
* @param {Number} [index] - The target index
|
|
191
206
|
* @param {TargetsArray} [targets] - The array of all animated targets
|
|
192
207
|
* @param {Tween|null} [prevTween] - The previous sibling tween for the same target and property
|
|
193
|
-
* @return {
|
|
208
|
+
* @return {T}
|
|
194
209
|
*/
|
|
195
210
|
|
|
196
211
|
/**
|
|
@@ -207,7 +222,7 @@
|
|
|
207
222
|
* @property {JSAnimation} parent
|
|
208
223
|
* @property {String} property
|
|
209
224
|
* @property {Target} target
|
|
210
|
-
* @property {String|Number} _value
|
|
225
|
+
* @property {String|Number|Object} _value
|
|
211
226
|
* @property {Function|null} _toFunc
|
|
212
227
|
* @property {Function|null} _fromFunc
|
|
213
228
|
* @property {EasingFunction} _ease
|
|
@@ -226,7 +241,11 @@
|
|
|
226
241
|
* @property {Number} _startTime
|
|
227
242
|
* @property {Number} _changeDuration
|
|
228
243
|
* @property {Number} _absoluteStartTime
|
|
244
|
+
* @property {Number} _absoluteUpdateStartTime
|
|
245
|
+
* @property {Number} _absoluteEndTime
|
|
246
|
+
* @property {Number} _hasFromValue
|
|
229
247
|
* @property {tweenTypes} _tweenType
|
|
248
|
+
* @property {((target: any, value: number, tween: Tween) => void) | null} _setter
|
|
230
249
|
* @property {valueTypes} _valueType
|
|
231
250
|
* @property {Number} _composition
|
|
232
251
|
* @property {Number} _isOverlapped
|
|
@@ -247,8 +266,8 @@
|
|
|
247
266
|
* @property {Number} n - Single number value
|
|
248
267
|
* @property {String} u - Value unit
|
|
249
268
|
* @property {String} o - Value operator
|
|
250
|
-
* @property {Array.<Number>} d - Array of Numbers (
|
|
251
|
-
* @property {Array.<String>} s - Strings (
|
|
269
|
+
* @property {Array.<Number>} d - Array of Numbers (complex / color value type)
|
|
270
|
+
* @property {Array.<String>} s - Strings (complex value type)
|
|
252
271
|
*/
|
|
253
272
|
|
|
254
273
|
/** @typedef {{_head: null|Tween, _tail: null|Tween}} TweenPropertySiblings */
|
|
@@ -259,7 +278,7 @@
|
|
|
259
278
|
// JSAnimation types
|
|
260
279
|
|
|
261
280
|
/**
|
|
262
|
-
* @typedef {Number|String|FunctionValue|EasingParam} TweenParamValue
|
|
281
|
+
* @typedef {Number|String|FunctionValue|EasingParam|TweakRegister} TweenParamValue
|
|
263
282
|
*/
|
|
264
283
|
|
|
265
284
|
/**
|
|
@@ -452,7 +471,7 @@
|
|
|
452
471
|
*/
|
|
453
472
|
|
|
454
473
|
/**
|
|
455
|
-
* @typedef {Record<String, TweenParamValue | EasingParam | TweenModifier | TweenComposition | AnimatablePropertyParamsOptions> &
|
|
474
|
+
* @typedef {Record<String, TweenParamValue | EasingParam | TweenModifier | TweenComposition | AnimatablePropertyParamsOptions | Callback<JSAnimation>> & AnimatablePropertyParamsOptions & TickableCallbacks<JSAnimation> & RenderableCallbacks<JSAnimation>} AnimatableParams
|
|
456
475
|
*/
|
|
457
476
|
|
|
458
477
|
// Scope types
|
|
@@ -495,7 +514,7 @@
|
|
|
495
514
|
/**
|
|
496
515
|
* @callback ScopeMethod
|
|
497
516
|
* @param {...*} args
|
|
498
|
-
* @return {
|
|
517
|
+
* @return {*}
|
|
499
518
|
*/
|
|
500
519
|
|
|
501
520
|
// Scroll types
|
|
@@ -725,6 +744,11 @@ const maxFps = 240;
|
|
|
725
744
|
const emptyString = '';
|
|
726
745
|
const cssVarPrefix = 'var(';
|
|
727
746
|
|
|
747
|
+
// Arrays
|
|
748
|
+
|
|
749
|
+
// Shared sentinel for tween slots that don't hold array data. Never mutated, only read; COMPLEX and COLOR tweens always replace the slot before writing.
|
|
750
|
+
const emptyArray = [];
|
|
751
|
+
|
|
728
752
|
const shortTransforms = /*#__PURE__*/ (() => {
|
|
729
753
|
const map = new Map();
|
|
730
754
|
map.set('x', 'translateX');
|
|
@@ -758,6 +782,13 @@ const transformsFragmentStrings = /*#__PURE__*/ validTransforms.reduce((a, v) =>
|
|
|
758
782
|
/** @return {void} */
|
|
759
783
|
const noop = () => {};
|
|
760
784
|
|
|
785
|
+
/**
|
|
786
|
+
* @template T
|
|
787
|
+
* @param {T} v
|
|
788
|
+
* @return {T}
|
|
789
|
+
*/
|
|
790
|
+
const noopModifier = v => v;
|
|
791
|
+
|
|
761
792
|
// Regex
|
|
762
793
|
|
|
763
794
|
const validRgbHslRgx = /\)\s*[-.\d]/;
|
|
@@ -779,10 +810,13 @@ const cssVariableMatchRgx = /var\(\s*(--[\w-]+)(?:\s*,\s*([^)]+))?\s*\)/;
|
|
|
779
810
|
/**
|
|
780
811
|
* @typedef {Object} EditorGlobals
|
|
781
812
|
* @property {boolean} showPanel
|
|
782
|
-
* @property {boolean} synced
|
|
783
813
|
* @property {Function} addAnimation
|
|
814
|
+
* @property {Function} addSet
|
|
784
815
|
* @property {Function} addTimeline
|
|
785
816
|
* @property {Function} addTimelineChild
|
|
817
|
+
* @property {Function} addTimelineLabel
|
|
818
|
+
* @property {Function} addTimelineCall
|
|
819
|
+
* @property {Function} addTimelineSync
|
|
786
820
|
* @property {Function} resolveStagger
|
|
787
821
|
* @property {Object|null} _head
|
|
788
822
|
* @property {Object|null} _tail
|
|
@@ -805,7 +839,7 @@ const defaults = {
|
|
|
805
839
|
loopDelay: 0,
|
|
806
840
|
ease: 'out(2)',
|
|
807
841
|
composition: compositionTypes.replace,
|
|
808
|
-
modifier:
|
|
842
|
+
modifier: noopModifier,
|
|
809
843
|
onBegin: noop,
|
|
810
844
|
onBeforeUpdate: noop,
|
|
811
845
|
onUpdate: noop,
|
|
@@ -835,7 +869,7 @@ const globals = {
|
|
|
835
869
|
editor: null,
|
|
836
870
|
};
|
|
837
871
|
|
|
838
|
-
const globalVersions = { version: '4.
|
|
872
|
+
const globalVersions = { version: '4.5.0', engine: null };
|
|
839
873
|
|
|
840
874
|
if (isBrowser) {
|
|
841
875
|
if (!win.AnimeJS) win.AnimeJS = [];
|
|
@@ -982,7 +1016,7 @@ const snap$1 = (v, increment) => isArr(increment) ? increment.reduce((closest, c
|
|
|
982
1016
|
* @param {Number} factor - Interpolation factor in the range [0, 1]
|
|
983
1017
|
* @return {Number} The interpolated value
|
|
984
1018
|
*/
|
|
985
|
-
const lerp$1 = (start, end, factor) => start + (end - start) * factor;
|
|
1019
|
+
const lerp$1 = (start, end, factor) => factor === 1 ? end : factor === 0 ? start : start + (end - start) * factor;
|
|
986
1020
|
|
|
987
1021
|
/**
|
|
988
1022
|
* Replaces infinity with maximum safe value
|
|
@@ -1231,6 +1265,61 @@ const buildTransformString = (props) => {
|
|
|
1231
1265
|
return str;
|
|
1232
1266
|
};
|
|
1233
1267
|
|
|
1268
|
+
/**
|
|
1269
|
+
* Anime.js adapter API. Each library or class group that wants to extend `animate()` and `utils.set()` calls `registerAdapter()` to create its own `Adapter`. The returned `Adapter` exposes `registerTargetAdapter(detect)` for per-class detection and `registerPropertyResolver(fn)` for global Color / Vector / pattern-based fallbacks.
|
|
1270
|
+
*
|
|
1271
|
+
* import { registerAdapter } from 'animejs/adapters';
|
|
1272
|
+
*
|
|
1273
|
+
* const myAdapter = registerAdapter();
|
|
1274
|
+
* const widget = myAdapter.registerTargetAdapter((t) => t instanceof MyWidget);
|
|
1275
|
+
* widget.registerProperty('value',
|
|
1276
|
+
* (t) => t.getValue(),
|
|
1277
|
+
* (target, value) => target.setValue(value),
|
|
1278
|
+
* );
|
|
1279
|
+
*
|
|
1280
|
+
* For scalar tweens, `value` is the interpolated number. For color and complex tweens it is `undefined`; read `tween._numbers` instead. `gate(target)` scopes the prop to a subset of matching targets.
|
|
1281
|
+
*
|
|
1282
|
+
* Resolution order: every Adapter's target adapters in registration order (first match wins) then every Adapter's property resolvers (first non-null wins) then engine direct property path.
|
|
1283
|
+
*/
|
|
1284
|
+
|
|
1285
|
+
|
|
1286
|
+
const adapters = /** @type {Adapter[]} */([]);
|
|
1287
|
+
|
|
1288
|
+
/**
|
|
1289
|
+
* Internal resolution. Tries every Adapter's target adapters first (in registration order, first match wins), then every Adapter's property resolvers.
|
|
1290
|
+
*
|
|
1291
|
+
* @param {any} target
|
|
1292
|
+
* @param {string} name
|
|
1293
|
+
* @return {TargetAdapterEntry | null}
|
|
1294
|
+
*/
|
|
1295
|
+
function resolveAdapterEntry(target, name) {
|
|
1296
|
+
if (!target) return null;
|
|
1297
|
+
const al = adapters.length;
|
|
1298
|
+
outer: for (let i = 0; i < al; i++) {
|
|
1299
|
+
const a = adapters[i];
|
|
1300
|
+
if (a.detect && !a.detect(target)) continue;
|
|
1301
|
+
const tas = a.targetAdapters;
|
|
1302
|
+
for (let j = 0, m = tas.length; j < m; j++) {
|
|
1303
|
+
const ta = tas[j];
|
|
1304
|
+
if (ta.detect(target)) {
|
|
1305
|
+
const entry = ta.props[name];
|
|
1306
|
+
if (entry && (!entry.gate || entry.gate(target))) return entry;
|
|
1307
|
+
break outer;
|
|
1308
|
+
}
|
|
1309
|
+
}
|
|
1310
|
+
}
|
|
1311
|
+
for (let i = 0; i < al; i++) {
|
|
1312
|
+
const a = adapters[i];
|
|
1313
|
+
if (a.detect && !a.detect(target)) continue;
|
|
1314
|
+
const rs = a.propertyResolvers;
|
|
1315
|
+
for (let j = 0, m = rs.length; j < m; j++) {
|
|
1316
|
+
const entry = rs[j](target, name);
|
|
1317
|
+
if (entry) return entry;
|
|
1318
|
+
}
|
|
1319
|
+
}
|
|
1320
|
+
return null;
|
|
1321
|
+
}
|
|
1322
|
+
|
|
1234
1323
|
|
|
1235
1324
|
|
|
1236
1325
|
/**
|
|
@@ -1328,6 +1417,21 @@ const setValue = (targetValue, defaultValue) => {
|
|
|
1328
1417
|
return isUnd(targetValue) ? defaultValue : targetValue;
|
|
1329
1418
|
};
|
|
1330
1419
|
|
|
1420
|
+
/**
|
|
1421
|
+
* Resolve against the target when it's a DOM element, otherwise fall back to :root so non-DOM targets like three.js meshes and custom adapters still pick up CSS variables defined on the document.
|
|
1422
|
+
*
|
|
1423
|
+
* @param {String} value
|
|
1424
|
+
* @param {Target} target
|
|
1425
|
+
* @return {String|Number}
|
|
1426
|
+
*/
|
|
1427
|
+
const resolveCssVar = (value, target) => {
|
|
1428
|
+
const match = value.match(cssVariableMatchRgx);
|
|
1429
|
+
const el = target[isDomSymbol] ? target : document.documentElement;
|
|
1430
|
+
let computed = getComputedStyle(/** @type {HTMLElement} */(el))?.getPropertyValue(match[1]);
|
|
1431
|
+
if ((!computed || computed.trim() === emptyString) && match[2]) computed = match[2].trim();
|
|
1432
|
+
return computed || 0;
|
|
1433
|
+
};
|
|
1434
|
+
|
|
1331
1435
|
/**
|
|
1332
1436
|
* @param {TweenPropValue} value
|
|
1333
1437
|
* @param {Target} target
|
|
@@ -1338,30 +1442,26 @@ const setValue = (targetValue, defaultValue) => {
|
|
|
1338
1442
|
* @return {any}
|
|
1339
1443
|
*/
|
|
1340
1444
|
const getFunctionValue = (value, target, index, targets, store, prevTween) => {
|
|
1341
|
-
let func;
|
|
1342
1445
|
if (isFnc(value)) {
|
|
1343
|
-
|
|
1446
|
+
if (!store) {
|
|
1447
|
+
const computed = /** @type {Function} */(value)(target, index, targets, prevTween);
|
|
1448
|
+
// Fallback to 0 if the function returns undefined, NaN, null, false or 0
|
|
1449
|
+
return !isNaN(+computed) ? +computed : computed || 0;
|
|
1450
|
+
}
|
|
1451
|
+
const func = () => {
|
|
1344
1452
|
const computed = /** @type {Function} */(value)(target, index, targets, prevTween);
|
|
1345
|
-
// Fallback to 0 if the function returns undefined / NaN / null / false / 0
|
|
1346
1453
|
return !isNaN(+computed) ? +computed : computed || 0;
|
|
1347
1454
|
};
|
|
1348
|
-
|
|
1349
|
-
func
|
|
1350
|
-
const match = value.match(cssVariableMatchRgx);
|
|
1351
|
-
const cssVarName = match[1];
|
|
1352
|
-
const fallbackValue = match[2];
|
|
1353
|
-
let computed = getComputedStyle(/** @type {HTMLElement} */(target))?.getPropertyValue(cssVarName);
|
|
1354
|
-
// Use fallback if CSS variable is not set or empty
|
|
1355
|
-
if ((!computed || computed.trim() === emptyString) && fallbackValue) {
|
|
1356
|
-
computed = fallbackValue.trim();
|
|
1357
|
-
}
|
|
1358
|
-
return computed || 0;
|
|
1359
|
-
};
|
|
1360
|
-
} else {
|
|
1361
|
-
return value;
|
|
1455
|
+
store.func = func;
|
|
1456
|
+
return func();
|
|
1362
1457
|
}
|
|
1363
|
-
if (
|
|
1364
|
-
|
|
1458
|
+
if (isStr(value) && stringStartsWith(value, cssVarPrefix)) {
|
|
1459
|
+
if (!store) return resolveCssVar(/** @type {String} */(value), target);
|
|
1460
|
+
const func = () => resolveCssVar(/** @type {String} */(value), target);
|
|
1461
|
+
store.func = func;
|
|
1462
|
+
return func();
|
|
1463
|
+
}
|
|
1464
|
+
return value;
|
|
1365
1465
|
};
|
|
1366
1466
|
|
|
1367
1467
|
/**
|
|
@@ -1408,6 +1508,12 @@ const getCSSValue = (target, propName, animationInlineStyles) => {
|
|
|
1408
1508
|
*/
|
|
1409
1509
|
const getOriginalAnimatableValue = (target, propName, tweenType, animationInlineStyles) => {
|
|
1410
1510
|
const type = !isUnd(tweenType) ? tweenType : getTweenType(target, propName);
|
|
1511
|
+
const adapterProp = resolveAdapterEntry(target, propName);
|
|
1512
|
+
if (adapterProp) {
|
|
1513
|
+
const value = adapterProp.get(target);
|
|
1514
|
+
if (value && animationInlineStyles) animationInlineStyles[propName] = value;
|
|
1515
|
+
return value == null ? 0 : value;
|
|
1516
|
+
}
|
|
1411
1517
|
if (type === tweenTypes.OBJECT) {
|
|
1412
1518
|
const value = target[propName];
|
|
1413
1519
|
if (value && animationInlineStyles) animationInlineStyles[propName] = value;
|
|
@@ -1449,7 +1555,7 @@ const createDecomposedValueTargetObject = () => {
|
|
|
1449
1555
|
};
|
|
1450
1556
|
|
|
1451
1557
|
/**
|
|
1452
|
-
* @param {String|Number} rawValue
|
|
1558
|
+
* @param {String|Number|Object} rawValue
|
|
1453
1559
|
* @param {TweenDecomposedValue} targetObject
|
|
1454
1560
|
* @return {TweenDecomposedValue}
|
|
1455
1561
|
*/
|
|
@@ -1467,39 +1573,38 @@ const decomposeRawValue = (rawValue, targetObject) => {
|
|
|
1467
1573
|
// It's a number
|
|
1468
1574
|
targetObject.n = num;
|
|
1469
1575
|
return targetObject;
|
|
1576
|
+
}
|
|
1577
|
+
// let str = /** @type {String} */(rawValue).trim();
|
|
1578
|
+
let str = /** @type {String} */(rawValue);
|
|
1579
|
+
// Parsing operators (+=, -=, *=) manually is much faster than using regex here
|
|
1580
|
+
if (str[1] === '=') {
|
|
1581
|
+
targetObject.o = str[0];
|
|
1582
|
+
str = str.slice(2);
|
|
1583
|
+
}
|
|
1584
|
+
// Skip exec regex if the value type is complex or color to avoid long regex backtracking
|
|
1585
|
+
const unitMatch = str.includes(' ') ? false : unitsExecRgx.exec(str);
|
|
1586
|
+
if (unitMatch) {
|
|
1587
|
+
// Has a number and a unit
|
|
1588
|
+
targetObject.t = valueTypes.UNIT;
|
|
1589
|
+
targetObject.n = +unitMatch[1];
|
|
1590
|
+
targetObject.u = unitMatch[2];
|
|
1591
|
+
return targetObject;
|
|
1592
|
+
} else if (targetObject.o) {
|
|
1593
|
+
// Has an operator (+=, -=, *=)
|
|
1594
|
+
targetObject.n = +str;
|
|
1595
|
+
return targetObject;
|
|
1596
|
+
} else if (isCol(str)) {
|
|
1597
|
+
// Color string
|
|
1598
|
+
targetObject.t = valueTypes.COLOR;
|
|
1599
|
+
targetObject.d = convertColorStringValuesToRgbaArray(str);
|
|
1600
|
+
return targetObject;
|
|
1470
1601
|
} else {
|
|
1471
|
-
//
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
}
|
|
1478
|
-
// Skip exec regex if the value type is complex or color to avoid long regex backtracking
|
|
1479
|
-
const unitMatch = str.includes(' ') ? false : unitsExecRgx.exec(str);
|
|
1480
|
-
if (unitMatch) {
|
|
1481
|
-
// Has a number and a unit
|
|
1482
|
-
targetObject.t = valueTypes.UNIT;
|
|
1483
|
-
targetObject.n = +unitMatch[1];
|
|
1484
|
-
targetObject.u = unitMatch[2];
|
|
1485
|
-
return targetObject;
|
|
1486
|
-
} else if (targetObject.o) {
|
|
1487
|
-
// Has an operator (+=, -=, *=)
|
|
1488
|
-
targetObject.n = +str;
|
|
1489
|
-
return targetObject;
|
|
1490
|
-
} else if (isCol(str)) {
|
|
1491
|
-
// Is a color
|
|
1492
|
-
targetObject.t = valueTypes.COLOR;
|
|
1493
|
-
targetObject.d = convertColorStringValuesToRgbaArray(str);
|
|
1494
|
-
return targetObject;
|
|
1495
|
-
} else {
|
|
1496
|
-
// Is a more complex string (generally svg coords, calc() or filters CSS values)
|
|
1497
|
-
const matchedNumbers = str.match(digitWithExponentRgx);
|
|
1498
|
-
targetObject.t = valueTypes.COMPLEX;
|
|
1499
|
-
targetObject.d = matchedNumbers ? matchedNumbers.map(Number) : [];
|
|
1500
|
-
targetObject.s = str.split(digitWithExponentRgx) || [];
|
|
1501
|
-
return targetObject;
|
|
1502
|
-
}
|
|
1602
|
+
// Is a more complex string (generally svg coords, calc() or filters CSS values)
|
|
1603
|
+
const matchedNumbers = str.match(digitWithExponentRgx);
|
|
1604
|
+
targetObject.t = valueTypes.COMPLEX;
|
|
1605
|
+
targetObject.d = matchedNumbers ? matchedNumbers.map(Number) : [];
|
|
1606
|
+
targetObject.s = str.split(digitWithExponentRgx) || [];
|
|
1607
|
+
return targetObject;
|
|
1503
1608
|
}
|
|
1504
1609
|
};
|
|
1505
1610
|
|
|
@@ -1520,30 +1625,6 @@ const decomposeTweenValue = (tween, targetObject) => {
|
|
|
1520
1625
|
|
|
1521
1626
|
const decomposedOriginalValue = createDecomposedValueTargetObject();
|
|
1522
1627
|
|
|
1523
|
-
/**
|
|
1524
|
-
* @param {Tween} tween
|
|
1525
|
-
* @param {Number} progress
|
|
1526
|
-
* @param {Number} precision
|
|
1527
|
-
* @return {String}
|
|
1528
|
-
*/
|
|
1529
|
-
const composeColorValue = (tween, progress, precision) => {
|
|
1530
|
-
const mod = tween._modifier;
|
|
1531
|
-
const fn = tween._fromNumbers;
|
|
1532
|
-
const tn = tween._toNumbers;
|
|
1533
|
-
const r = round$1(clamp$1(/** @type {Number} */(mod(lerp$1(fn[0], tn[0], progress))), 0, 255), 0);
|
|
1534
|
-
const g = round$1(clamp$1(/** @type {Number} */(mod(lerp$1(fn[1], tn[1], progress))), 0, 255), 0);
|
|
1535
|
-
const b = round$1(clamp$1(/** @type {Number} */(mod(lerp$1(fn[2], tn[2], progress))), 0, 255), 0);
|
|
1536
|
-
const a = clamp$1(/** @type {Number} */(mod(round$1(lerp$1(fn[3], tn[3], progress), precision))), 0, 1);
|
|
1537
|
-
if (tween._composition !== compositionTypes.none) {
|
|
1538
|
-
const ns = tween._numbers;
|
|
1539
|
-
ns[0] = r;
|
|
1540
|
-
ns[1] = g;
|
|
1541
|
-
ns[2] = b;
|
|
1542
|
-
ns[3] = a;
|
|
1543
|
-
}
|
|
1544
|
-
return `rgba(${r},${g},${b},${a})`;
|
|
1545
|
-
};
|
|
1546
|
-
|
|
1547
1628
|
/**
|
|
1548
1629
|
* @param {Tween} tween
|
|
1549
1630
|
* @param {Number} progress
|
|
@@ -1555,15 +1636,14 @@ const composeComplexValue = (tween, progress, precision) => {
|
|
|
1555
1636
|
const fn = tween._fromNumbers;
|
|
1556
1637
|
const tn = tween._toNumbers;
|
|
1557
1638
|
const ts = tween._strings;
|
|
1558
|
-
const hasComposition = tween._composition !== compositionTypes.none;
|
|
1559
1639
|
let v = ts[0];
|
|
1560
1640
|
for (let j = 0, l = tn.length; j < l; j++) {
|
|
1561
1641
|
const n = /** @type {Number} */(mod(round$1(lerp$1(fn[j], tn[j], progress), precision)));
|
|
1562
1642
|
const s = ts[j + 1];
|
|
1563
1643
|
v += `${s ? n + s : n}`;
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1644
|
+
// Keep _numbers fresh for every tween, not only composed ones, so a non-composition setter that reads the lerped triplet such as three transformOrigin still animates.
|
|
1645
|
+
// Potential optimization, skip the write when nothing reads it: if (hasComposition || tween._setter) tween._numbers[j] = n;
|
|
1646
|
+
tween._numbers[j] = n;
|
|
1567
1647
|
}
|
|
1568
1648
|
return v;
|
|
1569
1649
|
};
|
|
@@ -1615,12 +1695,14 @@ const render = (tickable, time, muteCallbacks, internalRender, tickMode) => {
|
|
|
1615
1695
|
// Execute the "expensive" iterations calculations only when necessary
|
|
1616
1696
|
if (iterationCount > 1) {
|
|
1617
1697
|
// bitwise NOT operator seems to be generally faster than Math.floor() across browsers
|
|
1618
|
-
const
|
|
1698
|
+
const period = iterationDuration + (isCurrentTimeEqualOrAboveDuration ? 0 : _loopDelay);
|
|
1699
|
+
const currentIteration = ~~(tickableCurrentTime / period);
|
|
1619
1700
|
tickable._currentIteration = clamp$1(currentIteration, 0, iterationCount);
|
|
1620
1701
|
// Prevent the iteration count to go above the max iterations when reaching the end of the animation
|
|
1621
1702
|
if (isCurrentTimeEqualOrAboveDuration) tickable._currentIteration--;
|
|
1622
1703
|
isOdd = tickable._currentIteration % 2;
|
|
1623
|
-
|
|
1704
|
+
// Derive elapsed from the same `~~` truncation that gave currentIteration. Using `% period` here can disagree with `~~(/period)` under float drift at iteration boundaries and write the wrong end of the tween for one frame.
|
|
1705
|
+
iterationElapsedTime = tickableCurrentTime - currentIteration * period || 0;
|
|
1624
1706
|
}
|
|
1625
1707
|
|
|
1626
1708
|
// Checks if exactly one of _reversed and (_alternate && isOdd) is true
|
|
@@ -1652,12 +1734,14 @@ const render = (tickable, time, muteCallbacks, internalRender, tickMode) => {
|
|
|
1652
1734
|
if (
|
|
1653
1735
|
forcedTick ||
|
|
1654
1736
|
tickMode === tickModes.AUTO && (
|
|
1655
|
-
|
|
1737
|
+
// Timeline children render from their offset instead of their delay so the gap left by a truncated sibling is covered on seek.
|
|
1738
|
+
time >= (parent && tickableDelay > 0 ? 0 : tickableDelay) && time <= tickableEndTime || // Normal render
|
|
1656
1739
|
time <= tickableDelay && tickablePrevTime > tickableDelay || // Playhead is before the animation start time so make sure the animation is at its initial state
|
|
1657
1740
|
time >= tickableEndTime && tickablePrevTime !== duration // Playhead is after the animation end time so make sure the animation is at its end state
|
|
1658
1741
|
) ||
|
|
1659
1742
|
iterationTime >= tickableEndTime && tickablePrevTime !== duration ||
|
|
1660
|
-
iterationTime
|
|
1743
|
+
// iterationTime is per-iteration, compared to the delay to catch a backward seek into a looped iteration's delay region. Exclude the final settled end, where iterationTime clamps to duration and would falsely match the delay region when the delay exceeds the duration.
|
|
1744
|
+
iterationTime <= tickableDelay && tickablePrevTime > 0 && !isCurrentTimeEqualOrAboveDuration ||
|
|
1661
1745
|
time <= tickablePrevTime && tickablePrevTime === duration && completed || // Force a render if a seek occurs on an completed animation
|
|
1662
1746
|
isCurrentTimeEqualOrAboveDuration && !completed && isSetter // This prevents 0 duration tickables to be skipped
|
|
1663
1747
|
) {
|
|
@@ -1673,7 +1757,8 @@ const render = (tickable, time, muteCallbacks, internalRender, tickMode) => {
|
|
|
1673
1757
|
|
|
1674
1758
|
// Time has jumped more than globals.tickThreshold so consider this tick manual
|
|
1675
1759
|
const forcedRender = forcedTick || (isRunningBackwards ? deltaTime * -1 : deltaTime) >= globals.tickThreshold;
|
|
1676
|
-
|
|
1760
|
+
// Round to match the precision of tween._absoluteStartTime so equal-time boundary checks compare cleanly without floating point drift from the unrounded _offset.
|
|
1761
|
+
const absoluteTime = round$1(tickable._offset + (parent ? parent._offset : 0) + tickableDelay + iterationTime, 12);
|
|
1677
1762
|
|
|
1678
1763
|
// Only Animation can have tweens, Timer returns undefined
|
|
1679
1764
|
let tween = /** @type {Tween} */(/** @type {JSAnimation} */(tickable)._head);
|
|
@@ -1692,15 +1777,38 @@ const render = (tickable, time, muteCallbacks, internalRender, tickMode) => {
|
|
|
1692
1777
|
const tweenNextRep = tween._nextRep;
|
|
1693
1778
|
const tweenPrevRep = tween._prevRep;
|
|
1694
1779
|
const tweenHasComposition = tweenComposition !== compositionTypes.none;
|
|
1780
|
+
// The previous sibling stops writing at its truncated end, so this tween takes over the hold from that point.
|
|
1781
|
+
const tweenPrevRepEndTime = tweenPrevRep ? tweenPrevRep._absoluteStartTime + tweenPrevRep._changeDuration : 0;
|
|
1782
|
+
const tweenPrevRepIsCrossParent = tweenPrevRep && tweenPrevRep.parent !== tween.parent;
|
|
1783
|
+
// Same parent keyframes take over at their own start, end plus delay equals the next start by construction.
|
|
1784
|
+
// Cross parent siblings take over at their update start.
|
|
1785
|
+
// Negative delay siblings take over at their own start instead.
|
|
1786
|
+
const tweenNextRepTakeover = !tweenNextRep || tweenNextRep._isOverridden ? tweenAbsEndTime :
|
|
1787
|
+
tweenNextRep.parent === tween.parent ? tweenAbsEndTime + tweenNextRep._delay :
|
|
1788
|
+
tweenNextRep._absoluteStartTime < tweenNextRep._absoluteUpdateStartTime ? tweenNextRep._absoluteStartTime : tweenNextRep._absoluteUpdateStartTime;
|
|
1695
1789
|
|
|
1696
1790
|
if ((forcedRender || (
|
|
1697
|
-
|
|
1698
|
-
(tweenCurrentTime !==
|
|
1699
|
-
|
|
1791
|
+
// Tail keyframes always re-evaluate the gate so an earlier keyframe cannot leave the target stale by writing past its own range after a backward seek.
|
|
1792
|
+
(tweenCurrentTime !== tweenChangeDuration || absoluteTime <= tweenNextRepTakeover ||
|
|
1793
|
+
(tweenPrevRep && !tweenPrevRepIsCrossParent && (!tweenNextRep || tweenNextRep.parent !== tween.parent))) &&
|
|
1794
|
+
// A cross parent tween re-renders its from value from the previous sibling truncated end so the handoff gap holds.
|
|
1795
|
+
// A keyframe re-renders its from revert while the next keyframe time is stale so a backward jump over its range cannot leave the next value in place.
|
|
1796
|
+
(tweenCurrentTime !== 0 || absoluteTime >= tween._absoluteStartTime ||
|
|
1797
|
+
(tweenPrevRepIsCrossParent && !tween._hasFromValue && !tweenPrevRep._isOverridden && absoluteTime >= tweenPrevRepEndTime) ||
|
|
1798
|
+
(tweenNextRep && !tweenNextRep._isOverridden && tweenNextRep.parent === tween.parent && tweenNextRep._currentTime !== 0 && iterationTime < tweenNextRep._startTime))
|
|
1799
|
+
)) &&
|
|
1800
|
+
// Non-first keyframes wait until the iteration reaches their own start before rendering, so the previous keyframe can handle the from-revert when scrubbed backward past this tween's range.
|
|
1801
|
+
(!tweenPrevRep || tweenPrevRepIsCrossParent || iterationTime >= tween._startTime) &&
|
|
1802
|
+
(!tweenHasComposition || (
|
|
1700
1803
|
!tween._isOverridden &&
|
|
1701
1804
|
(!tween._isOverlapped || absoluteTime <= tweenAbsEndTime) &&
|
|
1702
|
-
|
|
1703
|
-
(!
|
|
1805
|
+
// The next sibling owns the value past its takeover point, so yielding there keeps writes single owner in both directions.
|
|
1806
|
+
(!tweenNextRep || tweenNextRep._isOverridden || absoluteTime <= tweenNextRepTakeover) &&
|
|
1807
|
+
// The previous sibling owns the value up to its truncated end.
|
|
1808
|
+
// Cross parent tweens take over the hold from that point, explicit from values wait for their own start.
|
|
1809
|
+
(!tweenPrevRep || (tweenPrevRep._isOverridden || (!tweenPrevRepIsCrossParent ?
|
|
1810
|
+
absoluteTime >= tweenPrevRepEndTime + tween._delay :
|
|
1811
|
+
absoluteTime >= tween._absoluteStartTime || (!tween._hasFromValue && absoluteTime >= tweenPrevRepEndTime))))
|
|
1704
1812
|
))
|
|
1705
1813
|
) {
|
|
1706
1814
|
|
|
@@ -1711,7 +1819,7 @@ const render = (tickable, time, muteCallbacks, internalRender, tickMode) => {
|
|
|
1711
1819
|
const tweenType = tween._tweenType;
|
|
1712
1820
|
const tweenIsObject = tweenType === tweenTypes.OBJECT;
|
|
1713
1821
|
const tweenIsNumber = tweenValueType === valueTypes.NUMBER;
|
|
1714
|
-
// Only round the in-between frames values if the final value is a string
|
|
1822
|
+
// Only round the in-between frames values if the final value is a string. Object targets consume raw numbers, so rounding is dead work there.
|
|
1715
1823
|
const tweenPrecision = (tweenIsNumber && tweenIsObject) || tweenProgress === 0 || tweenProgress === 1 ? -1 : globals.precision;
|
|
1716
1824
|
|
|
1717
1825
|
// Recompose tween value
|
|
@@ -1727,7 +1835,22 @@ const render = (tickable, time, muteCallbacks, internalRender, tickMode) => {
|
|
|
1727
1835
|
number = /** @type {Number} */(tweenModifier(round$1(lerp$1(tween._fromNumber, tween._toNumber, tweenProgress), tweenPrecision)));
|
|
1728
1836
|
value = `${number}${tween._unit}`;
|
|
1729
1837
|
} else if (tweenValueType === valueTypes.COLOR) {
|
|
1730
|
-
|
|
1838
|
+
const ns = tween._numbers;
|
|
1839
|
+
const fn = tween._fromNumbers;
|
|
1840
|
+
const tn = tween._toNumbers;
|
|
1841
|
+
const omt = 1 - tweenProgress;
|
|
1842
|
+
const fr = fn[0], fg = fn[1], fb = fn[2];
|
|
1843
|
+
const tr = tn[0], tg = tn[1], tb = tn[2];
|
|
1844
|
+
// RGB channels lerp in pseudo-linear space (square inputs, sqrt result) to approximate gamma-correct blending.
|
|
1845
|
+
// See https://developer.nvidia.com/gpugems/gpugems3/part-iv-image-effects/chapter-24-importance-being-linear.
|
|
1846
|
+
ns[0] = /** @type {Number} */(tweenModifier(Math.sqrt(fr * fr * omt + tr * tr * tweenProgress)));
|
|
1847
|
+
ns[1] = /** @type {Number} */(tweenModifier(Math.sqrt(fg * fg * omt + tg * tg * tweenProgress)));
|
|
1848
|
+
ns[2] = /** @type {Number} */(tweenModifier(Math.sqrt(fb * fb * omt + tb * tb * tweenProgress)));
|
|
1849
|
+
ns[3] = /** @type {Number} */(tweenModifier(lerp$1(fn[3], tn[3], tweenProgress)));
|
|
1850
|
+
// The rgba string is built only for the dispatch path or the internalRender composition tick (setters handles the color comp)
|
|
1851
|
+
if (!tween._setter || internalRender) {
|
|
1852
|
+
value = `rgba(${round$1(ns[0], 0)},${round$1(ns[1], 0)},${round$1(ns[2], 0)},${ns[3]})`;
|
|
1853
|
+
}
|
|
1731
1854
|
} else if (tweenValueType === valueTypes.COMPLEX) {
|
|
1732
1855
|
value = composeComplexValue(tween, tweenProgress, tweenPrecision);
|
|
1733
1856
|
}
|
|
@@ -1742,7 +1865,9 @@ const render = (tickable, time, muteCallbacks, internalRender, tickMode) => {
|
|
|
1742
1865
|
const tweenProperty = tween.property;
|
|
1743
1866
|
tweenTarget = tween.target;
|
|
1744
1867
|
|
|
1745
|
-
if (
|
|
1868
|
+
if (tween._setter) {
|
|
1869
|
+
tween._setter(tweenTarget, number, tween);
|
|
1870
|
+
} else if (tweenIsObject) {
|
|
1746
1871
|
tweenTarget[tweenProperty] = value;
|
|
1747
1872
|
} else if (tweenType === tweenTypes.ATTRIBUTE) {
|
|
1748
1873
|
/** @type {DOMTarget} */(tweenTarget).setAttribute(tweenProperty, /** @type {String} */(value));
|
|
@@ -1770,6 +1895,9 @@ const render = (tickable, time, muteCallbacks, internalRender, tickMode) => {
|
|
|
1770
1895
|
tween._value = value;
|
|
1771
1896
|
}
|
|
1772
1897
|
|
|
1898
|
+
} else if (tweenCurrentTime && tweenPrevRep && !tweenPrevRepIsCrossParent && iterationTime < tween._startTime) {
|
|
1899
|
+
// Mark the keyframe as reverted when the playhead moves before its start, the previous keyframe owns the from revert and writes it once.
|
|
1900
|
+
tween._currentTime = 0;
|
|
1773
1901
|
}
|
|
1774
1902
|
|
|
1775
1903
|
if (tweenTransformsNeedUpdate && tween._renderTransforms) {
|
|
@@ -1877,6 +2005,8 @@ const tick = (tickable, time, muteCallbacks, internalRender, tickMode) => {
|
|
|
1877
2005
|
|
|
1878
2006
|
forEachChildren(tl, (/** @type {JSAnimation} */child) => {
|
|
1879
2007
|
const childTime = round$1((tlChildrenTime - child._offset) * child._speed, 12); // Rounding is needed when using seconds
|
|
2008
|
+
// Skip past-end siblings on backward iteration so their progress=1 to-values don't render last and overwrite the active sibling's write. Compare against _delay + duration so children with a normalized delay are not skipped while still inside their active range.
|
|
2009
|
+
if (tlIsRunningBackwards && childTime > child._delay + child.duration) return;
|
|
1880
2010
|
const childTickMode = child._fps < tl._fps ? child.requestTick(tlCildrenTickTime) : tickMode;
|
|
1881
2011
|
tlChildrenHasRendered += render(child, childTime, muteCallbacks, internalRender, childTickMode);
|
|
1882
2012
|
if (!child.completed && tlChildrenHaveCompleted) tlChildrenHaveCompleted = false;
|
|
@@ -1953,7 +2083,20 @@ const revertValues = (renderable, inlineStylesOnly = false) => {
|
|
|
1953
2083
|
const tweenType = tween._tweenType;
|
|
1954
2084
|
const originalInlinedValue = tween._inlineValue;
|
|
1955
2085
|
const tweenHadNoInlineValue = isNil(originalInlinedValue) || originalInlinedValue === emptyString;
|
|
1956
|
-
if (
|
|
2086
|
+
if (tween._setter) {
|
|
2087
|
+
if (!inlineStylesOnly && !tweenHadNoInlineValue) {
|
|
2088
|
+
// Re-seed the original value to the _number / _numbers props so the setter can write the original state instead of re-applying the current frame.
|
|
2089
|
+
decomposeRawValue(originalInlinedValue, decomposedOriginalValue);
|
|
2090
|
+
if (decomposedOriginalValue.d) {
|
|
2091
|
+
const src = decomposedOriginalValue.d;
|
|
2092
|
+
const dst = tween._numbers;
|
|
2093
|
+
for (let i = 0, l = src.length; i < l; i++) dst[i] = src[i];
|
|
2094
|
+
} else {
|
|
2095
|
+
tween._number = decomposedOriginalValue.n;
|
|
2096
|
+
}
|
|
2097
|
+
tween._setter(tween.target, tween._number, tween);
|
|
2098
|
+
}
|
|
2099
|
+
} else if (tweenType === tweenTypes.OBJECT) {
|
|
1957
2100
|
if (!inlineStylesOnly && !tweenHadNoInlineValue) {
|
|
1958
2101
|
tweenTarget[tweenProperty] = originalInlinedValue;
|
|
1959
2102
|
}
|
|
@@ -2030,8 +2173,6 @@ class Clock {
|
|
|
2030
2173
|
/** @type {Number} */
|
|
2031
2174
|
this._lastTime = initTime;
|
|
2032
2175
|
/** @type {Number} */
|
|
2033
|
-
this._scheduledTime = 0;
|
|
2034
|
-
/** @type {Number} */
|
|
2035
2176
|
this._frameDuration = K / maxFps;
|
|
2036
2177
|
/** @type {Number} */
|
|
2037
2178
|
this._fps = maxFps;
|
|
@@ -2050,14 +2191,12 @@ class Clock {
|
|
|
2050
2191
|
}
|
|
2051
2192
|
|
|
2052
2193
|
set fps(frameRate) {
|
|
2053
|
-
const previousFrameDuration = this._frameDuration;
|
|
2054
2194
|
const fr = +frameRate;
|
|
2055
2195
|
const fps = fr < minValue ? minValue : fr;
|
|
2056
2196
|
const frameDuration = K / fps;
|
|
2057
2197
|
if (fps > defaults.frameRate) defaults.frameRate = fps;
|
|
2058
2198
|
this._fps = fps;
|
|
2059
2199
|
this._frameDuration = frameDuration;
|
|
2060
|
-
this._scheduledTime += frameDuration - previousFrameDuration;
|
|
2061
2200
|
}
|
|
2062
2201
|
|
|
2063
2202
|
get speed() {
|
|
@@ -2074,17 +2213,17 @@ class Clock {
|
|
|
2074
2213
|
* @return {tickModes}
|
|
2075
2214
|
*/
|
|
2076
2215
|
requestTick(time) {
|
|
2077
|
-
const scheduledTime = this._scheduledTime;
|
|
2078
|
-
this._lastTickTime = time;
|
|
2079
|
-
// If the current time is lower than the scheduled time
|
|
2080
|
-
// this means not enough time has passed to hit one frameDuration
|
|
2081
|
-
// so skip that frame
|
|
2082
|
-
if (time < scheduledTime) return tickModes.NONE;
|
|
2083
2216
|
const frameDuration = this._frameDuration;
|
|
2084
|
-
const
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2217
|
+
const elapsed = time - this._lastTickTime;
|
|
2218
|
+
const scaled = frameDuration * .25;
|
|
2219
|
+
const tolerance = scaled < 4 ? scaled : 4;
|
|
2220
|
+
// Tolerance prevents dropping frames that arrive a bit early due to RAF jitter
|
|
2221
|
+
// typically <= ~25% of frame duration and capped at 4ms so it doesn't dominate at high fps.
|
|
2222
|
+
// e.g. at 60fps (frameDuration=16.667ms) a frame arriving after 15ms:
|
|
2223
|
+
// - without tolerance: 15 < 16.667 -> skip
|
|
2224
|
+
// - with tolerance: 15 + 4 >= 16.667 -> tick
|
|
2225
|
+
if (elapsed + tolerance < frameDuration) return tickModes.NONE;
|
|
2226
|
+
this._lastTickTime = elapsed >= frameDuration ? time - (elapsed % frameDuration) : time;
|
|
2088
2227
|
return tickModes.AUTO;
|
|
2089
2228
|
}
|
|
2090
2229
|
|
|
@@ -2244,7 +2383,9 @@ class Engine extends Clock {
|
|
|
2244
2383
|
}
|
|
2245
2384
|
|
|
2246
2385
|
set speed(playbackRate) {
|
|
2247
|
-
|
|
2386
|
+
const speed = playbackRate * globals.timeScale;
|
|
2387
|
+
if (this._speed === speed) return;
|
|
2388
|
+
this._speed = speed;
|
|
2248
2389
|
forEachChildren(this, (/** @type {Tickable} */child) => child.speed = child._speed);
|
|
2249
2390
|
}
|
|
2250
2391
|
|
|
@@ -2377,7 +2518,7 @@ const composeTween = (tween, siblings) => {
|
|
|
2377
2518
|
if (prevSibling) {
|
|
2378
2519
|
|
|
2379
2520
|
const prevParent = prevSibling.parent;
|
|
2380
|
-
const prevAbsEndTime = prevSibling.
|
|
2521
|
+
const prevAbsEndTime = prevSibling._absoluteEndTime;
|
|
2381
2522
|
|
|
2382
2523
|
// Handle looped animations tween
|
|
2383
2524
|
|
|
@@ -2403,7 +2544,8 @@ const composeTween = (tween, siblings) => {
|
|
|
2403
2544
|
|
|
2404
2545
|
}
|
|
2405
2546
|
|
|
2406
|
-
|
|
2547
|
+
// Read the precision-matched update-start instead of subtracting tween._delay live so sequential keyframes touching at a boundary don't trigger a phantom overlap from float drift.
|
|
2548
|
+
const absoluteUpdateStartTime = tween._absoluteUpdateStartTime;
|
|
2407
2549
|
|
|
2408
2550
|
if (prevAbsEndTime > absoluteUpdateStartTime) {
|
|
2409
2551
|
|
|
@@ -2423,37 +2565,41 @@ const composeTween = (tween, siblings) => {
|
|
|
2423
2565
|
}
|
|
2424
2566
|
}
|
|
2425
2567
|
|
|
2426
|
-
//
|
|
2568
|
+
// Skip the cancel cascade when both tweens share the same parent timeline, a timeline cannot replace itself.
|
|
2569
|
+
const tweenParentTL = tween.parent.parent;
|
|
2570
|
+
if (!tweenParentTL || tweenParentTL !== prevParent.parent) {
|
|
2427
2571
|
|
|
2428
|
-
|
|
2572
|
+
let pausePrevParentAnimation = true;
|
|
2429
2573
|
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2574
|
+
forEachChildren(prevParent, (/** @type Tween */t) => {
|
|
2575
|
+
if (!t._isOverlapped) pausePrevParentAnimation = false;
|
|
2576
|
+
});
|
|
2433
2577
|
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2578
|
+
if (pausePrevParentAnimation) {
|
|
2579
|
+
const prevParentTL = prevParent.parent;
|
|
2580
|
+
if (prevParentTL) {
|
|
2581
|
+
let pausePrevParentTL = true;
|
|
2582
|
+
forEachChildren(prevParentTL, (/** @type JSAnimation */a) => {
|
|
2583
|
+
if (a !== prevParent) {
|
|
2584
|
+
forEachChildren(a, (/** @type Tween */t) => {
|
|
2585
|
+
if (!t._isOverlapped) pausePrevParentTL = false;
|
|
2586
|
+
});
|
|
2587
|
+
}
|
|
2588
|
+
});
|
|
2589
|
+
if (pausePrevParentTL) {
|
|
2590
|
+
prevParentTL.cancel();
|
|
2443
2591
|
}
|
|
2444
|
-
}
|
|
2445
|
-
|
|
2446
|
-
|
|
2592
|
+
} else {
|
|
2593
|
+
prevParent.cancel();
|
|
2594
|
+
// Previously, calling .cancel() on a timeline child would affect the render order of other children
|
|
2595
|
+
// Worked around this by marking it as .completed and using .pause() for safe removal in the engine loop
|
|
2596
|
+
// This is no longer needed since timeline tween composition is now handled separately
|
|
2597
|
+
// Keeping this here for reference
|
|
2598
|
+
// prevParent.completed = true;
|
|
2599
|
+
// prevParent.pause();
|
|
2447
2600
|
}
|
|
2448
|
-
} else {
|
|
2449
|
-
prevParent.cancel();
|
|
2450
|
-
// Previously, calling .cancel() on a timeline child would affect the render order of other children
|
|
2451
|
-
// Worked around this by marking it as .completed and using .pause() for safe removal in the engine loop
|
|
2452
|
-
// This is no longer needed since timeline tween composition is now handled separately
|
|
2453
|
-
// Keeping this here for reference
|
|
2454
|
-
// prevParent.completed = true;
|
|
2455
|
-
// prevParent.pause();
|
|
2456
2601
|
}
|
|
2602
|
+
|
|
2457
2603
|
}
|
|
2458
2604
|
|
|
2459
2605
|
}
|
|
@@ -2508,14 +2654,12 @@ const composeTween = (tween, siblings) => {
|
|
|
2508
2654
|
tween._number = 0;
|
|
2509
2655
|
lookupTween._fromNumber = toNumber;
|
|
2510
2656
|
|
|
2511
|
-
if (tween._toNumbers) {
|
|
2657
|
+
if (tween._toNumbers.length) {
|
|
2512
2658
|
const toNumbers = cloneArray(tween._toNumbers);
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
});
|
|
2518
|
-
}
|
|
2659
|
+
toNumbers.forEach((value, i) => {
|
|
2660
|
+
tween._fromNumbers[i] = lookupTween._fromNumbers[i] - value;
|
|
2661
|
+
tween._toNumbers[i] = 0;
|
|
2662
|
+
});
|
|
2519
2663
|
lookupTween._fromNumbers = toNumbers;
|
|
2520
2664
|
}
|
|
2521
2665
|
|
|
@@ -3216,18 +3360,16 @@ function parseTargets(targets) {
|
|
|
3216
3360
|
function registerTargets(targets) {
|
|
3217
3361
|
const parsedTargetsArray = parseTargets(targets);
|
|
3218
3362
|
const parsedTargetsLength = parsedTargetsArray.length;
|
|
3219
|
-
|
|
3220
|
-
|
|
3221
|
-
|
|
3222
|
-
|
|
3223
|
-
|
|
3224
|
-
|
|
3225
|
-
|
|
3226
|
-
|
|
3227
|
-
|
|
3228
|
-
|
|
3229
|
-
target[transformsSymbol] = {};
|
|
3230
|
-
}
|
|
3363
|
+
for (let i = 0; i < parsedTargetsLength; i++) {
|
|
3364
|
+
const target = parsedTargetsArray[i];
|
|
3365
|
+
if (!target[isRegisteredTargetSymbol]) {
|
|
3366
|
+
target[isRegisteredTargetSymbol] = true;
|
|
3367
|
+
const isSvgType = isSvg(target);
|
|
3368
|
+
const isDom = /** @type {DOMTarget} */(target).nodeType || isSvgType;
|
|
3369
|
+
if (isDom) {
|
|
3370
|
+
target[isDomSymbol] = true;
|
|
3371
|
+
target[isSvgSymbol] = isSvgType;
|
|
3372
|
+
target[transformsSymbol] = {};
|
|
3231
3373
|
}
|
|
3232
3374
|
}
|
|
3233
3375
|
}
|
|
@@ -3349,8 +3491,8 @@ const easeInFunctions = {
|
|
|
3349
3491
|
|
|
3350
3492
|
/**
|
|
3351
3493
|
* @typedef {Object} EasesFunctions
|
|
3352
|
-
* @property {
|
|
3353
|
-
* @property {
|
|
3494
|
+
* @property {EasingFunction} linear
|
|
3495
|
+
* @property {EasingFunction} none
|
|
3354
3496
|
* @property {PowerEasing} in
|
|
3355
3497
|
* @property {PowerEasing} out
|
|
3356
3498
|
* @property {PowerEasing} inOut
|
|
@@ -3582,6 +3724,11 @@ class JSAnimation extends Timer {
|
|
|
3582
3724
|
|
|
3583
3725
|
super(/** @type {TimerParams & AnimationParams} */(parameters), parent, parentPosition);
|
|
3584
3726
|
|
|
3727
|
+
/** @type {Tween} */
|
|
3728
|
+
this._head;
|
|
3729
|
+
/** @type {Tween} */
|
|
3730
|
+
this._tail;
|
|
3731
|
+
|
|
3585
3732
|
++JSAnimationId;
|
|
3586
3733
|
|
|
3587
3734
|
const parsedTargets = registerTargets(targets);
|
|
@@ -3638,6 +3785,7 @@ class JSAnimation extends Timer {
|
|
|
3638
3785
|
if (isKey(p)) {
|
|
3639
3786
|
|
|
3640
3787
|
const tweenType = getTweenType(target, p);
|
|
3788
|
+
const adapterProp = resolveAdapterEntry(target, p);
|
|
3641
3789
|
|
|
3642
3790
|
const propName = sanitizePropertyName(p, target, tweenType);
|
|
3643
3791
|
|
|
@@ -3721,7 +3869,7 @@ class JSAnimation extends Timer {
|
|
|
3721
3869
|
} else {
|
|
3722
3870
|
tweenToValue = computedToValue;
|
|
3723
3871
|
}
|
|
3724
|
-
const tweenFromValue = getFunctionValue(key.from, target, ti, tl,
|
|
3872
|
+
const tweenFromValue = getFunctionValue(key.from, target, ti, tl, fromFunctionStore, prevSiblingTween);
|
|
3725
3873
|
const easeToParse = key.ease || tEasing;
|
|
3726
3874
|
|
|
3727
3875
|
const easeFunctionResult = getFunctionValue(easeToParse, target, ti, tl, null, prevSiblingTween);
|
|
@@ -3739,9 +3887,13 @@ class JSAnimation extends Timer {
|
|
|
3739
3887
|
const hasToValue = !isUnd(tweenToValue);
|
|
3740
3888
|
const isFromToArray = isArr(tweenToValue);
|
|
3741
3889
|
const isFromToValue = isFromToArray || (hasFromvalue && hasToValue);
|
|
3890
|
+
// Capture the update-start in local time, the previous sibling's end for keyframes after the first, zero for the first keyframe. Used to derive a precision-matched _absoluteUpdateStartTime below.
|
|
3891
|
+
const tweenUpdateStartLocal = prevTween ? lastTweenChangeEndTime : 0;
|
|
3742
3892
|
const tweenStartTime = prevTween ? lastTweenChangeEndTime + tweenDelay : tweenDelay;
|
|
3743
3893
|
// Rounding is necessary here to minimize floating point errors when working in seconds
|
|
3744
3894
|
const absoluteStartTime = round$1(absoluteOffsetTime + tweenStartTime, 12);
|
|
3895
|
+
// Match the rounding pattern of prevSibling._absoluteEndTime so the composition overlap check compares cleanly when keyframes touch at a boundary.
|
|
3896
|
+
const absoluteUpdateStartTime = round$1(absoluteOffsetTime + tweenUpdateStartLocal, 12);
|
|
3745
3897
|
|
|
3746
3898
|
// Force a onRender callback if the animation contains at least one from value and autoplay is set to false
|
|
3747
3899
|
if (!shouldTriggerRender && (hasFromvalue || isFromToArray)) shouldTriggerRender = 1;
|
|
@@ -3750,9 +3902,9 @@ class JSAnimation extends Timer {
|
|
|
3750
3902
|
|
|
3751
3903
|
if (tweenComposition !== compositionTypes.none) {
|
|
3752
3904
|
let nextSibling = siblings._head;
|
|
3753
|
-
//
|
|
3754
|
-
while (nextSibling &&
|
|
3755
|
-
prevSibling = nextSibling;
|
|
3905
|
+
// Walk prior siblings up to the new tween, skipping overridden ones so the chain resolves to the latest live value instead of stopping at the first override.
|
|
3906
|
+
while (nextSibling && nextSibling._absoluteStartTime <= absoluteStartTime) {
|
|
3907
|
+
if (!nextSibling._isOverridden) prevSibling = nextSibling;
|
|
3756
3908
|
nextSibling = nextSibling._nextRep;
|
|
3757
3909
|
// Overrides all the next siblings if the next sibling starts at the same time of after as the new tween start time
|
|
3758
3910
|
if (nextSibling && nextSibling._absoluteStartTime >= absoluteStartTime) {
|
|
@@ -3806,8 +3958,8 @@ class JSAnimation extends Timer {
|
|
|
3806
3958
|
if (prevTween) {
|
|
3807
3959
|
decomposeTweenValue(prevTween, fromTargetObject);
|
|
3808
3960
|
} else {
|
|
3809
|
-
decomposeRawValue(parent && prevSibling && prevSibling.parent.parent === parent ? prevSibling._value :
|
|
3810
3961
|
// No need to get and parse the original value if the tween is part of a timeline and has a previous sibling part of the same timeline
|
|
3962
|
+
decomposeRawValue(parent && prevSibling && prevSibling.parent.parent === parent ? prevSibling._value :
|
|
3811
3963
|
getOriginalAnimatableValue(target, propName, tweenType, inlineStylesStore), fromTargetObject);
|
|
3812
3964
|
}
|
|
3813
3965
|
}
|
|
@@ -3846,8 +3998,7 @@ class JSAnimation extends Timer {
|
|
|
3846
3998
|
const colorValue = fromTargetObject.t === valueTypes.COLOR ? fromTargetObject : toTargetObject;
|
|
3847
3999
|
const notColorValue = fromTargetObject.t === valueTypes.COLOR ? toTargetObject : fromTargetObject;
|
|
3848
4000
|
notColorValue.t = valueTypes.COLOR;
|
|
3849
|
-
notColorValue.
|
|
3850
|
-
notColorValue.d = [0, 0, 0, 1];
|
|
4001
|
+
notColorValue.d = colorValue.d.map(() => 0);
|
|
3851
4002
|
}
|
|
3852
4003
|
}
|
|
3853
4004
|
|
|
@@ -3877,6 +4028,16 @@ class JSAnimation extends Timer {
|
|
|
3877
4028
|
let inlineValue = inlineStylesStore[propName];
|
|
3878
4029
|
if (!isNil(inlineValue)) inlineStylesStore[propName] = null;
|
|
3879
4030
|
|
|
4031
|
+
// Resolve the adapter setter once so render skips the lookup per frame.
|
|
4032
|
+
const tweenSetter = adapterProp ? adapterProp.set : null;
|
|
4033
|
+
|
|
4034
|
+
// Rounding is necessary here to minimize floating point errors when working in seconds
|
|
4035
|
+
lastTweenChangeEndTime = round$1(tweenStartTime + tweenUpdateDuration, 12);
|
|
4036
|
+
|
|
4037
|
+
const fromD = fromTargetObject.d;
|
|
4038
|
+
const toD = toTargetObject.d;
|
|
4039
|
+
const toS = toTargetObject.s;
|
|
4040
|
+
|
|
3880
4041
|
/** @type {Tween} */
|
|
3881
4042
|
const tween = {
|
|
3882
4043
|
parent: this,
|
|
@@ -3887,12 +4048,12 @@ class JSAnimation extends Timer {
|
|
|
3887
4048
|
_toFunc: toFunctionStore.func,
|
|
3888
4049
|
_fromFunc: fromFunctionStore.func,
|
|
3889
4050
|
_ease: parseEase(tweenEasing),
|
|
3890
|
-
_fromNumbers: cloneArray(
|
|
3891
|
-
_toNumbers: cloneArray(
|
|
3892
|
-
_strings: cloneArray(
|
|
4051
|
+
_fromNumbers: fromD ? cloneArray(fromD) : emptyArray,
|
|
4052
|
+
_toNumbers: toD ? cloneArray(toD) : emptyArray,
|
|
4053
|
+
_strings: toS ? cloneArray(toS) : emptyArray,
|
|
3893
4054
|
_fromNumber: fromTargetObject.n,
|
|
3894
4055
|
_toNumber: toTargetObject.n,
|
|
3895
|
-
_numbers: cloneArray(
|
|
4056
|
+
_numbers: fromD ? cloneArray(fromD) : emptyArray, // For additive tween and animatables
|
|
3896
4057
|
_number: fromTargetObject.n, // For additive tween and animatables
|
|
3897
4058
|
_unit: toTargetObject.u,
|
|
3898
4059
|
_modifier: tweenModifier,
|
|
@@ -3902,8 +4063,12 @@ class JSAnimation extends Timer {
|
|
|
3902
4063
|
_updateDuration: tweenUpdateDuration,
|
|
3903
4064
|
_changeDuration: tweenUpdateDuration,
|
|
3904
4065
|
_absoluteStartTime: absoluteStartTime,
|
|
4066
|
+
_absoluteUpdateStartTime: absoluteUpdateStartTime,
|
|
4067
|
+
_absoluteEndTime: round$1(absoluteOffsetTime + lastTweenChangeEndTime, 12),
|
|
4068
|
+
_hasFromValue: hasFromvalue || isFromToArray ? 1 : 0,
|
|
3905
4069
|
// NOTE: Investigate bit packing to stores ENUM / BOOL
|
|
3906
4070
|
_tweenType: tweenType,
|
|
4071
|
+
_setter: tweenSetter,
|
|
3907
4072
|
_valueType: toTargetObject.t,
|
|
3908
4073
|
_composition: tweenComposition,
|
|
3909
4074
|
_isOverlapped: 0,
|
|
@@ -3926,10 +4091,11 @@ class JSAnimation extends Timer {
|
|
|
3926
4091
|
const vt = tween._valueType;
|
|
3927
4092
|
if (vt === valueTypes.COMPLEX) {
|
|
3928
4093
|
tween._value = composeComplexValue(tween, 1, -1);
|
|
3929
|
-
} else if (vt === valueTypes.COLOR) {
|
|
3930
|
-
tween._value = composeColorValue(tween, 1, -1);
|
|
3931
4094
|
} else if (vt === valueTypes.UNIT) {
|
|
3932
4095
|
tween._value = `${tweenModifier(tween._toNumber)}${tween._unit}`;
|
|
4096
|
+
} else if (vt === valueTypes.COLOR) {
|
|
4097
|
+
const d = toTargetObject.d;
|
|
4098
|
+
tween._value = `rgba(${round$1(d[0], 0)},${round$1(d[1], 0)},${round$1(d[2], 0)},${d[3]})`;
|
|
3933
4099
|
} else {
|
|
3934
4100
|
tween._value = tweenModifier(tween._toNumber);
|
|
3935
4101
|
}
|
|
@@ -3937,8 +4103,7 @@ class JSAnimation extends Timer {
|
|
|
3937
4103
|
if (isNaN(firstTweenChangeStartTime)) {
|
|
3938
4104
|
firstTweenChangeStartTime = tween._startTime;
|
|
3939
4105
|
}
|
|
3940
|
-
|
|
3941
|
-
lastTweenChangeEndTime = round$1(tweenStartTime + tweenUpdateDuration, 12);
|
|
4106
|
+
|
|
3942
4107
|
prevTween = tween;
|
|
3943
4108
|
animationAnimationLength++;
|
|
3944
4109
|
|
|
@@ -4044,8 +4209,11 @@ class JSAnimation extends Timer {
|
|
|
4044
4209
|
tween._updateDuration = normalizeTime(tween._updateDuration * timeScale);
|
|
4045
4210
|
tween._changeDuration = normalizeTime(tween._changeDuration * timeScale);
|
|
4046
4211
|
tween._currentTime *= timeScale;
|
|
4212
|
+
tween._delay *= timeScale;
|
|
4047
4213
|
tween._startTime *= timeScale;
|
|
4048
4214
|
tween._absoluteStartTime *= timeScale;
|
|
4215
|
+
tween._absoluteUpdateStartTime *= timeScale;
|
|
4216
|
+
tween._absoluteEndTime *= timeScale;
|
|
4049
4217
|
});
|
|
4050
4218
|
return super.stretch(newDuration);
|
|
4051
4219
|
}
|
|
@@ -4174,8 +4342,6 @@ const parseTimelinePosition = (timeline, timePosition) => {
|
|
|
4174
4342
|
|
|
4175
4343
|
|
|
4176
4344
|
|
|
4177
|
-
|
|
4178
|
-
|
|
4179
4345
|
/**
|
|
4180
4346
|
* @param {Timeline} tl
|
|
4181
4347
|
* @return {Number}
|
|
@@ -4368,13 +4534,21 @@ class Timeline extends Timer {
|
|
|
4368
4534
|
if (!isUnd(synced) && !isUnd(/** @type {WAAPIAnimation} */(synced).persist)) {
|
|
4369
4535
|
/** @type {WAAPIAnimation} */(synced).persist = true;
|
|
4370
4536
|
}
|
|
4371
|
-
|
|
4537
|
+
const editor = globals.editor;
|
|
4538
|
+
const childHook = editor && editor.addTimelineChild;
|
|
4539
|
+
if (editor && editor.addTimelineSync) {
|
|
4540
|
+
position = editor.addTimelineSync(synced, position, this.id);
|
|
4541
|
+
editor.addTimelineChild = null; // Suppress the per-child hook for the internal .add, sync already registered.
|
|
4542
|
+
}
|
|
4543
|
+
const result = this.add(synced, { currentTime: [0, duration], duration, delay: 0, ease: 'linear', playbackEase: 'linear' }, position);
|
|
4544
|
+
if (editor) editor.addTimelineChild = childHook;
|
|
4545
|
+
return result;
|
|
4372
4546
|
}
|
|
4373
4547
|
|
|
4374
4548
|
/**
|
|
4375
4549
|
* @param {TargetsParam} targets
|
|
4376
4550
|
* @param {AnimationParams} parameters
|
|
4377
|
-
* @param {TimelinePosition} [position]
|
|
4551
|
+
* @param {TimelinePosition|StaggerFunction<Number|String>|TweakRegister} [position]
|
|
4378
4552
|
* @return {this}
|
|
4379
4553
|
*/
|
|
4380
4554
|
set(targets, parameters, position) {
|
|
@@ -4391,6 +4565,7 @@ class Timeline extends Timer {
|
|
|
4391
4565
|
*/
|
|
4392
4566
|
call(callback, position) {
|
|
4393
4567
|
if (isUnd(callback) || callback && !isFnc(callback)) return this;
|
|
4568
|
+
if (globals.editor && globals.editor.addTimelineCall) position = globals.editor.addTimelineCall(callback, position, this.id);
|
|
4394
4569
|
return this.add({ duration: 0, delay: 0, onComplete: () => callback(this) }, position);
|
|
4395
4570
|
}
|
|
4396
4571
|
|
|
@@ -4402,6 +4577,7 @@ class Timeline extends Timer {
|
|
|
4402
4577
|
*/
|
|
4403
4578
|
label(labelName, position) {
|
|
4404
4579
|
if (isUnd(labelName) || labelName && !isStr(labelName)) return this;
|
|
4580
|
+
if (globals.editor && globals.editor.addTimelineLabel) position = globals.editor.addTimelineLabel(labelName, position, this.id);
|
|
4405
4581
|
this.labels[labelName] = parseTimelinePosition(this, position);
|
|
4406
4582
|
return this;
|
|
4407
4583
|
}
|
|
@@ -4510,6 +4686,7 @@ class Animatable {
|
|
|
4510
4686
|
const callbacksAnimationParams = { v: 1, autoplay: false };
|
|
4511
4687
|
const properties = {};
|
|
4512
4688
|
this.targets = [];
|
|
4689
|
+
/** @type {Record<String, JSAnimation>} */
|
|
4513
4690
|
this.animations = {};
|
|
4514
4691
|
/** @type {JSAnimation|null} */
|
|
4515
4692
|
this.callbacks = null;
|
|
@@ -5048,6 +5225,9 @@ function get(targetSelector, propName, unit) {
|
|
|
5048
5225
|
*/
|
|
5049
5226
|
const set = (targets, parameters) => {
|
|
5050
5227
|
if (isUnd(parameters)) return;
|
|
5228
|
+
if (globals.editor && globals.editor.addSet) {
|
|
5229
|
+
return globals.editor.addSet(targets, parameters);
|
|
5230
|
+
}
|
|
5051
5231
|
parameters.duration = minValue;
|
|
5052
5232
|
// Do not overrides currently active tweens by default
|
|
5053
5233
|
parameters.composition = setValue(parameters.composition, compositionTypes.none);
|
|
@@ -6284,13 +6464,14 @@ const sync = (callback = noop) => {
|
|
|
6284
6464
|
};
|
|
6285
6465
|
|
|
6286
6466
|
/**
|
|
6287
|
-
* @
|
|
6288
|
-
* @
|
|
6467
|
+
* @template {Tickable | ((...args: any[]) => void) | void} T
|
|
6468
|
+
* @param {(...args: any[]) => T} constructor
|
|
6469
|
+
* @return {(...args: any[]) => T extends void ? () => void : T}
|
|
6289
6470
|
*/
|
|
6290
6471
|
const keepTime = constructor => {
|
|
6291
6472
|
/** @type {Tickable} */
|
|
6292
6473
|
let tracked;
|
|
6293
|
-
return (...args) => {
|
|
6474
|
+
return /** @type {(...args: any[]) => T extends void ? () => void : T} */(/** @type {*} */((...args) => {
|
|
6294
6475
|
let currentIteration, currentIterationProgress, reversed, alternate, startTime;
|
|
6295
6476
|
if (tracked) {
|
|
6296
6477
|
currentIteration = tracked.currentIteration;
|
|
@@ -6308,7 +6489,7 @@ const keepTime = constructor => {
|
|
|
6308
6489
|
/** @type {Tickable} */(tracked)._startTime = startTime;
|
|
6309
6490
|
}
|
|
6310
6491
|
return cleanup || noop;
|
|
6311
|
-
}
|
|
6492
|
+
}));
|
|
6312
6493
|
};
|
|
6313
6494
|
|
|
6314
6495
|
|
|
@@ -6706,12 +6887,14 @@ class ScrollContainer {
|
|
|
6706
6887
|
|
|
6707
6888
|
refreshScrollObservers() {
|
|
6708
6889
|
forEachChildren(this, (/** @type {ScrollObserver} */child) => {
|
|
6890
|
+
if (!child.ready) return;
|
|
6709
6891
|
if (child._debug) {
|
|
6710
6892
|
child.removeDebug();
|
|
6711
6893
|
}
|
|
6712
6894
|
});
|
|
6713
6895
|
this.updateBounds();
|
|
6714
6896
|
forEachChildren(this, (/** @type {ScrollObserver} */child) => {
|
|
6897
|
+
if (!child.ready) return;
|
|
6715
6898
|
child.refresh();
|
|
6716
6899
|
child.onResize(child);
|
|
6717
6900
|
if (child._debug) {
|
|
@@ -9809,11 +9992,12 @@ const randomPick = items => items[random(0, items.length - 1)];
|
|
|
9809
9992
|
* Adapted from https://bost.ocks.org/mike/shuffle/
|
|
9810
9993
|
*
|
|
9811
9994
|
* @param {Array} items - The array to shuffle (will be modified in-place)
|
|
9995
|
+
* @param {RandomNumberGenerator} [rnd] - Optional RNG matching the random() signature (defaults to random)
|
|
9812
9996
|
* @return {Array} The same array reference, now shuffled
|
|
9813
9997
|
*/
|
|
9814
|
-
const shuffle = items => {
|
|
9998
|
+
const shuffle = (items, rnd = random) => {
|
|
9815
9999
|
let m = items.length, t, i;
|
|
9816
|
-
while (m) { i =
|
|
10000
|
+
while (m) { i = rnd(0, --m); t = items[m]; items[m] = items[i]; items[i] = t; }
|
|
9817
10001
|
return items;
|
|
9818
10002
|
};
|
|
9819
10003
|
|
|
@@ -9858,6 +10042,7 @@ const stagger = (val, params = {}) => {
|
|
|
9858
10042
|
let values = [];
|
|
9859
10043
|
let maxValue = 0;
|
|
9860
10044
|
let cachedOffset;
|
|
10045
|
+
let jitterSamples = null;
|
|
9861
10046
|
const from = params.from;
|
|
9862
10047
|
const reversed = params.reversed;
|
|
9863
10048
|
const ease = params.ease;
|
|
@@ -9879,27 +10064,42 @@ const stagger = (val, params = {}) => {
|
|
|
9879
10064
|
const val2 = isRange ? parseNumber(val[1]) : 0;
|
|
9880
10065
|
const unitMatch = unitsExecRgx.exec((isRange ? val[1] : val) + emptyString);
|
|
9881
10066
|
const start = params.start || 0 + (isRange ? val1 : 0);
|
|
10067
|
+
const seed = params.seed;
|
|
10068
|
+
const hasSeed = !isUnd(seed) && seed !== false;
|
|
10069
|
+
const rng = hasSeed ? createSeededRandom(seed === true ? 0 : /** @type {Number} */(seed)) : random;
|
|
10070
|
+
const jitter = params.jitter;
|
|
10071
|
+
const hasJitter = !isUnd(jitter);
|
|
10072
|
+
const jitterIsArr = isArr(jitter);
|
|
10073
|
+
const jitterStart = jitterIsArr ? /** @type {[Number,Number]} */(jitter)[0] : /** @type {Number} */(jitter) || 0;
|
|
10074
|
+
const jitterEnd = jitterIsArr ? /** @type {[Number,Number]} */(jitter)[1] : /** @type {Number} */(jitter) || 0;
|
|
9882
10075
|
let fromIndex = fromFirst ? 0 : isNum(from) ? from : 0;
|
|
9883
10076
|
return (target, i, t, _, tl) => {
|
|
9884
10077
|
const [ registeredTarget ] = registerTargets(target);
|
|
9885
10078
|
const total = isUnd(customTotal) ? t.length : customTotal;
|
|
9886
10079
|
const customIndex = !isUnd(useProp) ? isFnc(useProp) ? useProp(registeredTarget, i, total) : getOriginalAnimatableValue(registeredTarget, useProp) : false;
|
|
9887
|
-
const
|
|
10080
|
+
const customIdx = isNum(customIndex) || isStr(customIndex) && isNum(+customIndex) ? +customIndex : i;
|
|
10081
|
+
// Fall back to the natural index when the resolved value lands outside [0, total) so values[staggerIndex] never reads undefined.
|
|
10082
|
+
const staggerIndex = customIdx >= 0 && customIdx < total ? customIdx : i;
|
|
9888
10083
|
if (fromCenter) fromIndex = (total - 1) / 2;
|
|
9889
10084
|
if (fromLast) fromIndex = total - 1;
|
|
9890
10085
|
if (!values.length) {
|
|
9891
10086
|
if (autoGrid) {
|
|
9892
10087
|
let hasPositions = true;
|
|
10088
|
+
let has3D = false;
|
|
9893
10089
|
let minPosX = Infinity;
|
|
9894
10090
|
let minPosY = Infinity;
|
|
10091
|
+
let minPosZ = Infinity;
|
|
9895
10092
|
let maxPosX = -Infinity;
|
|
9896
10093
|
let maxPosY = -Infinity;
|
|
10094
|
+
let maxPosZ = -Infinity;
|
|
9897
10095
|
const pxArr = [];
|
|
9898
10096
|
const pyArr = [];
|
|
10097
|
+
const pzArr = [];
|
|
9899
10098
|
for (let index = 0; index < total; index++) {
|
|
9900
10099
|
const el = t[index];
|
|
9901
10100
|
let px = 0;
|
|
9902
10101
|
let py = 0;
|
|
10102
|
+
let pz = 0;
|
|
9903
10103
|
let found = false;
|
|
9904
10104
|
if (el && isFnc(el.getBoundingClientRect)) {
|
|
9905
10105
|
const rect = el.getBoundingClientRect();
|
|
@@ -9911,6 +10111,10 @@ const stagger = (val, params = {}) => {
|
|
|
9911
10111
|
if (obj && isNum(obj.x) && isNum(obj.y)) {
|
|
9912
10112
|
px = obj.x;
|
|
9913
10113
|
py = obj.y;
|
|
10114
|
+
if (isNum(obj.z)) {
|
|
10115
|
+
pz = obj.z;
|
|
10116
|
+
has3D = true;
|
|
10117
|
+
}
|
|
9914
10118
|
found = true;
|
|
9915
10119
|
}
|
|
9916
10120
|
}
|
|
@@ -9920,42 +10124,52 @@ const stagger = (val, params = {}) => {
|
|
|
9920
10124
|
}
|
|
9921
10125
|
pxArr.push(px);
|
|
9922
10126
|
pyArr.push(py);
|
|
10127
|
+
pzArr.push(pz);
|
|
9923
10128
|
if (px < minPosX) minPosX = px;
|
|
9924
10129
|
if (py < minPosY) minPosY = py;
|
|
10130
|
+
if (pz < minPosZ) minPosZ = pz;
|
|
9925
10131
|
if (px > maxPosX) maxPosX = px;
|
|
9926
10132
|
if (py > maxPosY) maxPosY = py;
|
|
10133
|
+
if (pz > maxPosZ) maxPosZ = pz;
|
|
9927
10134
|
}
|
|
9928
10135
|
if (hasPositions) {
|
|
9929
10136
|
let fX = pxArr[0];
|
|
9930
10137
|
let fY = pyArr[0];
|
|
10138
|
+
let fZ = pzArr[0];
|
|
9931
10139
|
if (fromArr) {
|
|
9932
10140
|
fX = minPosX + from[0] * (maxPosX - minPosX);
|
|
9933
10141
|
fY = minPosY + from[1] * (maxPosY - minPosY);
|
|
10142
|
+
fZ = has3D ? minPosZ + (from.length >= 3 ? from[2] : 0.5) * (maxPosZ - minPosZ) : 0;
|
|
9934
10143
|
} else if (fromCenter) {
|
|
9935
10144
|
fX = (minPosX + maxPosX) / 2;
|
|
9936
10145
|
fY = (minPosY + maxPosY) / 2;
|
|
10146
|
+
fZ = (minPosZ + maxPosZ) / 2;
|
|
9937
10147
|
} else if (fromLast) {
|
|
9938
10148
|
fX = pxArr[total - 1];
|
|
9939
10149
|
fY = pyArr[total - 1];
|
|
10150
|
+
fZ = pzArr[total - 1];
|
|
9940
10151
|
} else if (isNum(from)) {
|
|
9941
10152
|
fX = pxArr[from];
|
|
9942
10153
|
fY = pyArr[from];
|
|
10154
|
+
fZ = pzArr[from];
|
|
9943
10155
|
}
|
|
9944
10156
|
for (let index = 0; index < total; index++) {
|
|
9945
10157
|
const distanceX = fX - pxArr[index];
|
|
9946
10158
|
const distanceY = fY - pyArr[index];
|
|
9947
|
-
|
|
10159
|
+
const distanceZ = fZ - pzArr[index];
|
|
10160
|
+
let value = sqrt(distanceX * distanceX + distanceY * distanceY + (has3D ? distanceZ * distanceZ : 0));
|
|
9948
10161
|
if (axis === 'x') value = -distanceX;
|
|
9949
10162
|
if (axis === 'y') value = -distanceY;
|
|
10163
|
+
if (axis === 'z') value = -distanceZ;
|
|
9950
10164
|
values.push(value);
|
|
9951
10165
|
}
|
|
9952
10166
|
let minDist = Infinity;
|
|
9953
|
-
for (let index = 0
|
|
10167
|
+
for (let index = 0; index < total; index++) {
|
|
9954
10168
|
const absVal = abs(values[index]);
|
|
9955
10169
|
if (absVal > 0 && absVal < minDist) minDist = absVal;
|
|
9956
10170
|
}
|
|
9957
10171
|
if (minDist > 0 && minDist < Infinity) {
|
|
9958
|
-
for (let index = 0
|
|
10172
|
+
for (let index = 0; index < total; index++) {
|
|
9959
10173
|
values[index] = values[index] / minDist;
|
|
9960
10174
|
}
|
|
9961
10175
|
}
|
|
@@ -9969,32 +10183,51 @@ const stagger = (val, params = {}) => {
|
|
|
9969
10183
|
if (!grid) {
|
|
9970
10184
|
values.push(abs(fromIndex - index));
|
|
9971
10185
|
} else {
|
|
9972
|
-
|
|
10186
|
+
const dims = grid.length;
|
|
10187
|
+
const wh = grid[0] * grid[1];
|
|
10188
|
+
let fromX, fromY, fromZ;
|
|
9973
10189
|
if (fromArr) {
|
|
9974
10190
|
fromX = from[0] * (grid[0] - 1);
|
|
9975
10191
|
fromY = from[1] * (grid[1] - 1);
|
|
10192
|
+
fromZ = dims === 3 ? (from.length >= 3 ? from[2] : 0.5) * (grid[2] - 1) : 0;
|
|
9976
10193
|
} else if (fromCenter) {
|
|
9977
10194
|
fromX = (grid[0] - 1) / 2;
|
|
9978
10195
|
fromY = (grid[1] - 1) / 2;
|
|
10196
|
+
fromZ = dims === 3 ? (grid[2] - 1) / 2 : 0;
|
|
9979
10197
|
} else {
|
|
9980
10198
|
fromX = fromIndex % grid[0];
|
|
9981
|
-
fromY = floor(fromIndex / grid[0]);
|
|
10199
|
+
fromY = floor(fromIndex / grid[0]) % grid[1];
|
|
10200
|
+
fromZ = dims === 3 ? floor(fromIndex / wh) : 0;
|
|
9982
10201
|
}
|
|
9983
10202
|
const toX = index % grid[0];
|
|
9984
|
-
const toY = floor(index / grid[0]);
|
|
10203
|
+
const toY = floor(index / grid[0]) % grid[1];
|
|
10204
|
+
const toZ = dims === 3 ? floor(index / wh) : 0;
|
|
9985
10205
|
const distanceX = fromX - toX;
|
|
9986
10206
|
const distanceY = fromY - toY;
|
|
9987
|
-
|
|
10207
|
+
const distanceZ = fromZ - toZ;
|
|
10208
|
+
let value = sqrt(distanceX * distanceX + distanceY * distanceY + (dims === 3 ? distanceZ * distanceZ : 0));
|
|
9988
10209
|
if (axis === 'x') value = -distanceX;
|
|
9989
10210
|
if (axis === 'y') value = -distanceY;
|
|
10211
|
+
if (axis === 'z') value = -distanceZ;
|
|
9990
10212
|
values.push(value);
|
|
9991
10213
|
}
|
|
9992
10214
|
}
|
|
9993
10215
|
}
|
|
9994
|
-
maxValue =
|
|
9995
|
-
|
|
9996
|
-
if (
|
|
9997
|
-
|
|
10216
|
+
maxValue = values[0];
|
|
10217
|
+
for (let k = 1; k < total; k++) if (values[k] > maxValue) maxValue = values[k];
|
|
10218
|
+
if (staggerEase || reversed) {
|
|
10219
|
+
for (let k = 0; k < total; k++) {
|
|
10220
|
+
let v = values[k];
|
|
10221
|
+
if (staggerEase) v = staggerEase(v / maxValue) * maxValue;
|
|
10222
|
+
if (reversed) v = axis ? -v : abs(maxValue - v);
|
|
10223
|
+
values[k] = v;
|
|
10224
|
+
}
|
|
10225
|
+
}
|
|
10226
|
+
if (hasJitter) {
|
|
10227
|
+
jitterSamples = new Array(total);
|
|
10228
|
+
for (let k = 0; k < total; k++) jitterSamples[k] = rng(-1, 1, 4);
|
|
10229
|
+
}
|
|
10230
|
+
if (fromRandom) values = shuffle(values, rng);
|
|
9998
10231
|
}
|
|
9999
10232
|
const spacing = isRange ? (val2 - val1) / maxValue : val1;
|
|
10000
10233
|
if (isUnd(cachedOffset)) {
|
|
@@ -10002,6 +10235,11 @@ const stagger = (val, params = {}) => {
|
|
|
10002
10235
|
}
|
|
10003
10236
|
/** @type {String|Number} */
|
|
10004
10237
|
let output = cachedOffset + ((spacing * round$1(values[staggerIndex], 2)) || 0);
|
|
10238
|
+
if (hasJitter) {
|
|
10239
|
+
const progress = maxValue ? values[staggerIndex] / maxValue : 0;
|
|
10240
|
+
const mag = jitterStart + (jitterEnd - jitterStart) * progress;
|
|
10241
|
+
output = /** @type {Number} */(output) + jitterSamples[staggerIndex] * mag;
|
|
10242
|
+
}
|
|
10005
10243
|
if (params.modifier) output = params.modifier(/** @type {Number} */(output));
|
|
10006
10244
|
if (unitMatch) output = `${output}${unitMatch[2]}`;
|
|
10007
10245
|
return output;
|
|
@@ -10371,6 +10609,7 @@ const filterLineElements = ($el, lineIndex, bin) => {
|
|
|
10371
10609
|
*/
|
|
10372
10610
|
const generateTemplate = (type, params = {}) => {
|
|
10373
10611
|
let template = ``;
|
|
10612
|
+
if (!params) params = {};
|
|
10374
10613
|
const classString = isStr(params.class) ? ` class="${params.class}"` : '';
|
|
10375
10614
|
const cloneType = setValue(params.clone, false);
|
|
10376
10615
|
const wrapType = setValue(params.wrap, false);
|
|
@@ -10752,6 +10991,16 @@ const split = (target, parameters) => {
|
|
|
10752
10991
|
|
|
10753
10992
|
|
|
10754
10993
|
|
|
10994
|
+
/**
|
|
10995
|
+
* @typedef {Object} ScrambleTextTween
|
|
10996
|
+
* @property {Number} from
|
|
10997
|
+
* @property {Number} to
|
|
10998
|
+
* @property {Number} duration
|
|
10999
|
+
* @property {Number} delay
|
|
11000
|
+
* @property {String} ease
|
|
11001
|
+
* @property {(v: Number) => String} modifier
|
|
11002
|
+
*/
|
|
11003
|
+
|
|
10755
11004
|
/**
|
|
10756
11005
|
* '-' 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-')
|
|
10757
11006
|
* @param {String} str
|
|
@@ -10789,7 +11038,7 @@ const originalTexts = new WeakMap();
|
|
|
10789
11038
|
* progressively revealing the original text.
|
|
10790
11039
|
*
|
|
10791
11040
|
* @param {ScrambleTextParams} [params]
|
|
10792
|
-
* @return {FunctionValue}
|
|
11041
|
+
* @return {FunctionValue<ScrambleTextTween>}
|
|
10793
11042
|
*/
|
|
10794
11043
|
const scrambleText = (params = {}) => {
|
|
10795
11044
|
if (!params) params = {};
|