animejs 4.4.0 → 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 +4 -5
- package/dist/bundles/anime.esm.js +491 -272
- package/dist/bundles/anime.esm.min.js +2 -2
- package/dist/bundles/anime.umd.js +491 -272
- 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 +93 -73
- package/dist/modules/core/render.js +96 -76
- 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 - UMD 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
|
|
@@ -731,6 +750,11 @@
|
|
|
731
750
|
const emptyString = '';
|
|
732
751
|
const cssVarPrefix = 'var(';
|
|
733
752
|
|
|
753
|
+
// Arrays
|
|
754
|
+
|
|
755
|
+
// 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.
|
|
756
|
+
const emptyArray = [];
|
|
757
|
+
|
|
734
758
|
const shortTransforms = /*#__PURE__*/ (() => {
|
|
735
759
|
const map = new Map();
|
|
736
760
|
map.set('x', 'translateX');
|
|
@@ -764,6 +788,13 @@
|
|
|
764
788
|
/** @return {void} */
|
|
765
789
|
const noop = () => {};
|
|
766
790
|
|
|
791
|
+
/**
|
|
792
|
+
* @template T
|
|
793
|
+
* @param {T} v
|
|
794
|
+
* @return {T}
|
|
795
|
+
*/
|
|
796
|
+
const noopModifier = v => v;
|
|
797
|
+
|
|
767
798
|
// Regex
|
|
768
799
|
|
|
769
800
|
const validRgbHslRgx = /\)\s*[-.\d]/;
|
|
@@ -785,10 +816,13 @@
|
|
|
785
816
|
/**
|
|
786
817
|
* @typedef {Object} EditorGlobals
|
|
787
818
|
* @property {boolean} showPanel
|
|
788
|
-
* @property {boolean} synced
|
|
789
819
|
* @property {Function} addAnimation
|
|
820
|
+
* @property {Function} addSet
|
|
790
821
|
* @property {Function} addTimeline
|
|
791
822
|
* @property {Function} addTimelineChild
|
|
823
|
+
* @property {Function} addTimelineLabel
|
|
824
|
+
* @property {Function} addTimelineCall
|
|
825
|
+
* @property {Function} addTimelineSync
|
|
792
826
|
* @property {Function} resolveStagger
|
|
793
827
|
* @property {Object|null} _head
|
|
794
828
|
* @property {Object|null} _tail
|
|
@@ -811,7 +845,7 @@
|
|
|
811
845
|
loopDelay: 0,
|
|
812
846
|
ease: 'out(2)',
|
|
813
847
|
composition: compositionTypes.replace,
|
|
814
|
-
modifier:
|
|
848
|
+
modifier: noopModifier,
|
|
815
849
|
onBegin: noop,
|
|
816
850
|
onBeforeUpdate: noop,
|
|
817
851
|
onUpdate: noop,
|
|
@@ -841,7 +875,7 @@
|
|
|
841
875
|
editor: null,
|
|
842
876
|
};
|
|
843
877
|
|
|
844
|
-
const globalVersions = { version: '4.
|
|
878
|
+
const globalVersions = { version: '4.5.0', engine: null };
|
|
845
879
|
|
|
846
880
|
if (isBrowser) {
|
|
847
881
|
if (!win.AnimeJS) win.AnimeJS = [];
|
|
@@ -988,7 +1022,7 @@
|
|
|
988
1022
|
* @param {Number} factor - Interpolation factor in the range [0, 1]
|
|
989
1023
|
* @return {Number} The interpolated value
|
|
990
1024
|
*/
|
|
991
|
-
const lerp$1 = (start, end, factor) => start + (end - start) * factor;
|
|
1025
|
+
const lerp$1 = (start, end, factor) => factor === 1 ? end : factor === 0 ? start : start + (end - start) * factor;
|
|
992
1026
|
|
|
993
1027
|
/**
|
|
994
1028
|
* Replaces infinity with maximum safe value
|
|
@@ -1237,6 +1271,61 @@
|
|
|
1237
1271
|
return str;
|
|
1238
1272
|
};
|
|
1239
1273
|
|
|
1274
|
+
/**
|
|
1275
|
+
* 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.
|
|
1276
|
+
*
|
|
1277
|
+
* import { registerAdapter } from 'animejs/adapters';
|
|
1278
|
+
*
|
|
1279
|
+
* const myAdapter = registerAdapter();
|
|
1280
|
+
* const widget = myAdapter.registerTargetAdapter((t) => t instanceof MyWidget);
|
|
1281
|
+
* widget.registerProperty('value',
|
|
1282
|
+
* (t) => t.getValue(),
|
|
1283
|
+
* (target, value) => target.setValue(value),
|
|
1284
|
+
* );
|
|
1285
|
+
*
|
|
1286
|
+
* 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.
|
|
1287
|
+
*
|
|
1288
|
+
* 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.
|
|
1289
|
+
*/
|
|
1290
|
+
|
|
1291
|
+
|
|
1292
|
+
const adapters = /** @type {Adapter[]} */([]);
|
|
1293
|
+
|
|
1294
|
+
/**
|
|
1295
|
+
* Internal resolution. Tries every Adapter's target adapters first (in registration order, first match wins), then every Adapter's property resolvers.
|
|
1296
|
+
*
|
|
1297
|
+
* @param {any} target
|
|
1298
|
+
* @param {string} name
|
|
1299
|
+
* @return {TargetAdapterEntry | null}
|
|
1300
|
+
*/
|
|
1301
|
+
function resolveAdapterEntry(target, name) {
|
|
1302
|
+
if (!target) return null;
|
|
1303
|
+
const al = adapters.length;
|
|
1304
|
+
outer: for (let i = 0; i < al; i++) {
|
|
1305
|
+
const a = adapters[i];
|
|
1306
|
+
if (a.detect && !a.detect(target)) continue;
|
|
1307
|
+
const tas = a.targetAdapters;
|
|
1308
|
+
for (let j = 0, m = tas.length; j < m; j++) {
|
|
1309
|
+
const ta = tas[j];
|
|
1310
|
+
if (ta.detect(target)) {
|
|
1311
|
+
const entry = ta.props[name];
|
|
1312
|
+
if (entry && (!entry.gate || entry.gate(target))) return entry;
|
|
1313
|
+
break outer;
|
|
1314
|
+
}
|
|
1315
|
+
}
|
|
1316
|
+
}
|
|
1317
|
+
for (let i = 0; i < al; i++) {
|
|
1318
|
+
const a = adapters[i];
|
|
1319
|
+
if (a.detect && !a.detect(target)) continue;
|
|
1320
|
+
const rs = a.propertyResolvers;
|
|
1321
|
+
for (let j = 0, m = rs.length; j < m; j++) {
|
|
1322
|
+
const entry = rs[j](target, name);
|
|
1323
|
+
if (entry) return entry;
|
|
1324
|
+
}
|
|
1325
|
+
}
|
|
1326
|
+
return null;
|
|
1327
|
+
}
|
|
1328
|
+
|
|
1240
1329
|
|
|
1241
1330
|
|
|
1242
1331
|
/**
|
|
@@ -1334,6 +1423,21 @@
|
|
|
1334
1423
|
return isUnd(targetValue) ? defaultValue : targetValue;
|
|
1335
1424
|
};
|
|
1336
1425
|
|
|
1426
|
+
/**
|
|
1427
|
+
* 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.
|
|
1428
|
+
*
|
|
1429
|
+
* @param {String} value
|
|
1430
|
+
* @param {Target} target
|
|
1431
|
+
* @return {String|Number}
|
|
1432
|
+
*/
|
|
1433
|
+
const resolveCssVar = (value, target) => {
|
|
1434
|
+
const match = value.match(cssVariableMatchRgx);
|
|
1435
|
+
const el = target[isDomSymbol] ? target : document.documentElement;
|
|
1436
|
+
let computed = getComputedStyle(/** @type {HTMLElement} */(el))?.getPropertyValue(match[1]);
|
|
1437
|
+
if ((!computed || computed.trim() === emptyString) && match[2]) computed = match[2].trim();
|
|
1438
|
+
return computed || 0;
|
|
1439
|
+
};
|
|
1440
|
+
|
|
1337
1441
|
/**
|
|
1338
1442
|
* @param {TweenPropValue} value
|
|
1339
1443
|
* @param {Target} target
|
|
@@ -1344,30 +1448,26 @@
|
|
|
1344
1448
|
* @return {any}
|
|
1345
1449
|
*/
|
|
1346
1450
|
const getFunctionValue = (value, target, index, targets, store, prevTween) => {
|
|
1347
|
-
let func;
|
|
1348
1451
|
if (isFnc(value)) {
|
|
1349
|
-
|
|
1452
|
+
if (!store) {
|
|
1453
|
+
const computed = /** @type {Function} */(value)(target, index, targets, prevTween);
|
|
1454
|
+
// Fallback to 0 if the function returns undefined, NaN, null, false or 0
|
|
1455
|
+
return !isNaN(+computed) ? +computed : computed || 0;
|
|
1456
|
+
}
|
|
1457
|
+
const func = () => {
|
|
1350
1458
|
const computed = /** @type {Function} */(value)(target, index, targets, prevTween);
|
|
1351
|
-
// Fallback to 0 if the function returns undefined / NaN / null / false / 0
|
|
1352
1459
|
return !isNaN(+computed) ? +computed : computed || 0;
|
|
1353
1460
|
};
|
|
1354
|
-
|
|
1355
|
-
func
|
|
1356
|
-
const match = value.match(cssVariableMatchRgx);
|
|
1357
|
-
const cssVarName = match[1];
|
|
1358
|
-
const fallbackValue = match[2];
|
|
1359
|
-
let computed = getComputedStyle(/** @type {HTMLElement} */(target))?.getPropertyValue(cssVarName);
|
|
1360
|
-
// Use fallback if CSS variable is not set or empty
|
|
1361
|
-
if ((!computed || computed.trim() === emptyString) && fallbackValue) {
|
|
1362
|
-
computed = fallbackValue.trim();
|
|
1363
|
-
}
|
|
1364
|
-
return computed || 0;
|
|
1365
|
-
};
|
|
1366
|
-
} else {
|
|
1367
|
-
return value;
|
|
1461
|
+
store.func = func;
|
|
1462
|
+
return func();
|
|
1368
1463
|
}
|
|
1369
|
-
if (
|
|
1370
|
-
|
|
1464
|
+
if (isStr(value) && stringStartsWith(value, cssVarPrefix)) {
|
|
1465
|
+
if (!store) return resolveCssVar(/** @type {String} */(value), target);
|
|
1466
|
+
const func = () => resolveCssVar(/** @type {String} */(value), target);
|
|
1467
|
+
store.func = func;
|
|
1468
|
+
return func();
|
|
1469
|
+
}
|
|
1470
|
+
return value;
|
|
1371
1471
|
};
|
|
1372
1472
|
|
|
1373
1473
|
/**
|
|
@@ -1414,6 +1514,12 @@
|
|
|
1414
1514
|
*/
|
|
1415
1515
|
const getOriginalAnimatableValue = (target, propName, tweenType, animationInlineStyles) => {
|
|
1416
1516
|
const type = !isUnd(tweenType) ? tweenType : getTweenType(target, propName);
|
|
1517
|
+
const adapterProp = resolveAdapterEntry(target, propName);
|
|
1518
|
+
if (adapterProp) {
|
|
1519
|
+
const value = adapterProp.get(target);
|
|
1520
|
+
if (value && animationInlineStyles) animationInlineStyles[propName] = value;
|
|
1521
|
+
return value == null ? 0 : value;
|
|
1522
|
+
}
|
|
1417
1523
|
if (type === tweenTypes.OBJECT) {
|
|
1418
1524
|
const value = target[propName];
|
|
1419
1525
|
if (value && animationInlineStyles) animationInlineStyles[propName] = value;
|
|
@@ -1455,7 +1561,7 @@
|
|
|
1455
1561
|
};
|
|
1456
1562
|
|
|
1457
1563
|
/**
|
|
1458
|
-
* @param {String|Number} rawValue
|
|
1564
|
+
* @param {String|Number|Object} rawValue
|
|
1459
1565
|
* @param {TweenDecomposedValue} targetObject
|
|
1460
1566
|
* @return {TweenDecomposedValue}
|
|
1461
1567
|
*/
|
|
@@ -1473,39 +1579,38 @@
|
|
|
1473
1579
|
// It's a number
|
|
1474
1580
|
targetObject.n = num;
|
|
1475
1581
|
return targetObject;
|
|
1582
|
+
}
|
|
1583
|
+
// let str = /** @type {String} */(rawValue).trim();
|
|
1584
|
+
let str = /** @type {String} */(rawValue);
|
|
1585
|
+
// Parsing operators (+=, -=, *=) manually is much faster than using regex here
|
|
1586
|
+
if (str[1] === '=') {
|
|
1587
|
+
targetObject.o = str[0];
|
|
1588
|
+
str = str.slice(2);
|
|
1589
|
+
}
|
|
1590
|
+
// Skip exec regex if the value type is complex or color to avoid long regex backtracking
|
|
1591
|
+
const unitMatch = str.includes(' ') ? false : unitsExecRgx.exec(str);
|
|
1592
|
+
if (unitMatch) {
|
|
1593
|
+
// Has a number and a unit
|
|
1594
|
+
targetObject.t = valueTypes.UNIT;
|
|
1595
|
+
targetObject.n = +unitMatch[1];
|
|
1596
|
+
targetObject.u = unitMatch[2];
|
|
1597
|
+
return targetObject;
|
|
1598
|
+
} else if (targetObject.o) {
|
|
1599
|
+
// Has an operator (+=, -=, *=)
|
|
1600
|
+
targetObject.n = +str;
|
|
1601
|
+
return targetObject;
|
|
1602
|
+
} else if (isCol(str)) {
|
|
1603
|
+
// Color string
|
|
1604
|
+
targetObject.t = valueTypes.COLOR;
|
|
1605
|
+
targetObject.d = convertColorStringValuesToRgbaArray(str);
|
|
1606
|
+
return targetObject;
|
|
1476
1607
|
} else {
|
|
1477
|
-
//
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
}
|
|
1484
|
-
// Skip exec regex if the value type is complex or color to avoid long regex backtracking
|
|
1485
|
-
const unitMatch = str.includes(' ') ? false : unitsExecRgx.exec(str);
|
|
1486
|
-
if (unitMatch) {
|
|
1487
|
-
// Has a number and a unit
|
|
1488
|
-
targetObject.t = valueTypes.UNIT;
|
|
1489
|
-
targetObject.n = +unitMatch[1];
|
|
1490
|
-
targetObject.u = unitMatch[2];
|
|
1491
|
-
return targetObject;
|
|
1492
|
-
} else if (targetObject.o) {
|
|
1493
|
-
// Has an operator (+=, -=, *=)
|
|
1494
|
-
targetObject.n = +str;
|
|
1495
|
-
return targetObject;
|
|
1496
|
-
} else if (isCol(str)) {
|
|
1497
|
-
// Is a color
|
|
1498
|
-
targetObject.t = valueTypes.COLOR;
|
|
1499
|
-
targetObject.d = convertColorStringValuesToRgbaArray(str);
|
|
1500
|
-
return targetObject;
|
|
1501
|
-
} else {
|
|
1502
|
-
// Is a more complex string (generally svg coords, calc() or filters CSS values)
|
|
1503
|
-
const matchedNumbers = str.match(digitWithExponentRgx);
|
|
1504
|
-
targetObject.t = valueTypes.COMPLEX;
|
|
1505
|
-
targetObject.d = matchedNumbers ? matchedNumbers.map(Number) : [];
|
|
1506
|
-
targetObject.s = str.split(digitWithExponentRgx) || [];
|
|
1507
|
-
return targetObject;
|
|
1508
|
-
}
|
|
1608
|
+
// Is a more complex string (generally svg coords, calc() or filters CSS values)
|
|
1609
|
+
const matchedNumbers = str.match(digitWithExponentRgx);
|
|
1610
|
+
targetObject.t = valueTypes.COMPLEX;
|
|
1611
|
+
targetObject.d = matchedNumbers ? matchedNumbers.map(Number) : [];
|
|
1612
|
+
targetObject.s = str.split(digitWithExponentRgx) || [];
|
|
1613
|
+
return targetObject;
|
|
1509
1614
|
}
|
|
1510
1615
|
};
|
|
1511
1616
|
|
|
@@ -1526,30 +1631,6 @@
|
|
|
1526
1631
|
|
|
1527
1632
|
const decomposedOriginalValue = createDecomposedValueTargetObject();
|
|
1528
1633
|
|
|
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
1634
|
/**
|
|
1554
1635
|
* @param {Tween} tween
|
|
1555
1636
|
* @param {Number} progress
|
|
@@ -1561,15 +1642,14 @@
|
|
|
1561
1642
|
const fn = tween._fromNumbers;
|
|
1562
1643
|
const tn = tween._toNumbers;
|
|
1563
1644
|
const ts = tween._strings;
|
|
1564
|
-
const hasComposition = tween._composition !== compositionTypes.none;
|
|
1565
1645
|
let v = ts[0];
|
|
1566
1646
|
for (let j = 0, l = tn.length; j < l; j++) {
|
|
1567
1647
|
const n = /** @type {Number} */(mod(round$1(lerp$1(fn[j], tn[j], progress), precision)));
|
|
1568
1648
|
const s = ts[j + 1];
|
|
1569
1649
|
v += `${s ? n + s : n}`;
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1650
|
+
// 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.
|
|
1651
|
+
// Potential optimization, skip the write when nothing reads it: if (hasComposition || tween._setter) tween._numbers[j] = n;
|
|
1652
|
+
tween._numbers[j] = n;
|
|
1573
1653
|
}
|
|
1574
1654
|
return v;
|
|
1575
1655
|
};
|
|
@@ -1621,12 +1701,14 @@
|
|
|
1621
1701
|
// Execute the "expensive" iterations calculations only when necessary
|
|
1622
1702
|
if (iterationCount > 1) {
|
|
1623
1703
|
// bitwise NOT operator seems to be generally faster than Math.floor() across browsers
|
|
1624
|
-
const
|
|
1704
|
+
const period = iterationDuration + (isCurrentTimeEqualOrAboveDuration ? 0 : _loopDelay);
|
|
1705
|
+
const currentIteration = ~~(tickableCurrentTime / period);
|
|
1625
1706
|
tickable._currentIteration = clamp$1(currentIteration, 0, iterationCount);
|
|
1626
1707
|
// Prevent the iteration count to go above the max iterations when reaching the end of the animation
|
|
1627
1708
|
if (isCurrentTimeEqualOrAboveDuration) tickable._currentIteration--;
|
|
1628
1709
|
isOdd = tickable._currentIteration % 2;
|
|
1629
|
-
|
|
1710
|
+
// 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.
|
|
1711
|
+
iterationElapsedTime = tickableCurrentTime - currentIteration * period || 0;
|
|
1630
1712
|
}
|
|
1631
1713
|
|
|
1632
1714
|
// Checks if exactly one of _reversed and (_alternate && isOdd) is true
|
|
@@ -1658,12 +1740,14 @@
|
|
|
1658
1740
|
if (
|
|
1659
1741
|
forcedTick ||
|
|
1660
1742
|
tickMode === tickModes.AUTO && (
|
|
1661
|
-
|
|
1743
|
+
// Timeline children render from their offset instead of their delay so the gap left by a truncated sibling is covered on seek.
|
|
1744
|
+
time >= (parent && tickableDelay > 0 ? 0 : tickableDelay) && time <= tickableEndTime || // Normal render
|
|
1662
1745
|
time <= tickableDelay && tickablePrevTime > tickableDelay || // Playhead is before the animation start time so make sure the animation is at its initial state
|
|
1663
1746
|
time >= tickableEndTime && tickablePrevTime !== duration // Playhead is after the animation end time so make sure the animation is at its end state
|
|
1664
1747
|
) ||
|
|
1665
1748
|
iterationTime >= tickableEndTime && tickablePrevTime !== duration ||
|
|
1666
|
-
iterationTime
|
|
1749
|
+
// 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.
|
|
1750
|
+
iterationTime <= tickableDelay && tickablePrevTime > 0 && !isCurrentTimeEqualOrAboveDuration ||
|
|
1667
1751
|
time <= tickablePrevTime && tickablePrevTime === duration && completed || // Force a render if a seek occurs on an completed animation
|
|
1668
1752
|
isCurrentTimeEqualOrAboveDuration && !completed && isSetter // This prevents 0 duration tickables to be skipped
|
|
1669
1753
|
) {
|
|
@@ -1679,7 +1763,8 @@
|
|
|
1679
1763
|
|
|
1680
1764
|
// Time has jumped more than globals.tickThreshold so consider this tick manual
|
|
1681
1765
|
const forcedRender = forcedTick || (isRunningBackwards ? deltaTime * -1 : deltaTime) >= globals.tickThreshold;
|
|
1682
|
-
|
|
1766
|
+
// Round to match the precision of tween._absoluteStartTime so equal-time boundary checks compare cleanly without floating point drift from the unrounded _offset.
|
|
1767
|
+
const absoluteTime = round$1(tickable._offset + (parent ? parent._offset : 0) + tickableDelay + iterationTime, 12);
|
|
1683
1768
|
|
|
1684
1769
|
// Only Animation can have tweens, Timer returns undefined
|
|
1685
1770
|
let tween = /** @type {Tween} */(/** @type {JSAnimation} */(tickable)._head);
|
|
@@ -1698,15 +1783,38 @@
|
|
|
1698
1783
|
const tweenNextRep = tween._nextRep;
|
|
1699
1784
|
const tweenPrevRep = tween._prevRep;
|
|
1700
1785
|
const tweenHasComposition = tweenComposition !== compositionTypes.none;
|
|
1786
|
+
// The previous sibling stops writing at its truncated end, so this tween takes over the hold from that point.
|
|
1787
|
+
const tweenPrevRepEndTime = tweenPrevRep ? tweenPrevRep._absoluteStartTime + tweenPrevRep._changeDuration : 0;
|
|
1788
|
+
const tweenPrevRepIsCrossParent = tweenPrevRep && tweenPrevRep.parent !== tween.parent;
|
|
1789
|
+
// Same parent keyframes take over at their own start, end plus delay equals the next start by construction.
|
|
1790
|
+
// Cross parent siblings take over at their update start.
|
|
1791
|
+
// Negative delay siblings take over at their own start instead.
|
|
1792
|
+
const tweenNextRepTakeover = !tweenNextRep || tweenNextRep._isOverridden ? tweenAbsEndTime :
|
|
1793
|
+
tweenNextRep.parent === tween.parent ? tweenAbsEndTime + tweenNextRep._delay :
|
|
1794
|
+
tweenNextRep._absoluteStartTime < tweenNextRep._absoluteUpdateStartTime ? tweenNextRep._absoluteStartTime : tweenNextRep._absoluteUpdateStartTime;
|
|
1701
1795
|
|
|
1702
1796
|
if ((forcedRender || (
|
|
1703
|
-
|
|
1704
|
-
(tweenCurrentTime !==
|
|
1705
|
-
|
|
1797
|
+
// 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.
|
|
1798
|
+
(tweenCurrentTime !== tweenChangeDuration || absoluteTime <= tweenNextRepTakeover ||
|
|
1799
|
+
(tweenPrevRep && !tweenPrevRepIsCrossParent && (!tweenNextRep || tweenNextRep.parent !== tween.parent))) &&
|
|
1800
|
+
// A cross parent tween re-renders its from value from the previous sibling truncated end so the handoff gap holds.
|
|
1801
|
+
// 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.
|
|
1802
|
+
(tweenCurrentTime !== 0 || absoluteTime >= tween._absoluteStartTime ||
|
|
1803
|
+
(tweenPrevRepIsCrossParent && !tween._hasFromValue && !tweenPrevRep._isOverridden && absoluteTime >= tweenPrevRepEndTime) ||
|
|
1804
|
+
(tweenNextRep && !tweenNextRep._isOverridden && tweenNextRep.parent === tween.parent && tweenNextRep._currentTime !== 0 && iterationTime < tweenNextRep._startTime))
|
|
1805
|
+
)) &&
|
|
1806
|
+
// 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.
|
|
1807
|
+
(!tweenPrevRep || tweenPrevRepIsCrossParent || iterationTime >= tween._startTime) &&
|
|
1808
|
+
(!tweenHasComposition || (
|
|
1706
1809
|
!tween._isOverridden &&
|
|
1707
1810
|
(!tween._isOverlapped || absoluteTime <= tweenAbsEndTime) &&
|
|
1708
|
-
|
|
1709
|
-
(!
|
|
1811
|
+
// The next sibling owns the value past its takeover point, so yielding there keeps writes single owner in both directions.
|
|
1812
|
+
(!tweenNextRep || tweenNextRep._isOverridden || absoluteTime <= tweenNextRepTakeover) &&
|
|
1813
|
+
// The previous sibling owns the value up to its truncated end.
|
|
1814
|
+
// Cross parent tweens take over the hold from that point, explicit from values wait for their own start.
|
|
1815
|
+
(!tweenPrevRep || (tweenPrevRep._isOverridden || (!tweenPrevRepIsCrossParent ?
|
|
1816
|
+
absoluteTime >= tweenPrevRepEndTime + tween._delay :
|
|
1817
|
+
absoluteTime >= tween._absoluteStartTime || (!tween._hasFromValue && absoluteTime >= tweenPrevRepEndTime))))
|
|
1710
1818
|
))
|
|
1711
1819
|
) {
|
|
1712
1820
|
|
|
@@ -1717,7 +1825,7 @@
|
|
|
1717
1825
|
const tweenType = tween._tweenType;
|
|
1718
1826
|
const tweenIsObject = tweenType === tweenTypes.OBJECT;
|
|
1719
1827
|
const tweenIsNumber = tweenValueType === valueTypes.NUMBER;
|
|
1720
|
-
// Only round the in-between frames values if the final value is a string
|
|
1828
|
+
// 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.
|
|
1721
1829
|
const tweenPrecision = (tweenIsNumber && tweenIsObject) || tweenProgress === 0 || tweenProgress === 1 ? -1 : globals.precision;
|
|
1722
1830
|
|
|
1723
1831
|
// Recompose tween value
|
|
@@ -1733,7 +1841,22 @@
|
|
|
1733
1841
|
number = /** @type {Number} */(tweenModifier(round$1(lerp$1(tween._fromNumber, tween._toNumber, tweenProgress), tweenPrecision)));
|
|
1734
1842
|
value = `${number}${tween._unit}`;
|
|
1735
1843
|
} else if (tweenValueType === valueTypes.COLOR) {
|
|
1736
|
-
|
|
1844
|
+
const ns = tween._numbers;
|
|
1845
|
+
const fn = tween._fromNumbers;
|
|
1846
|
+
const tn = tween._toNumbers;
|
|
1847
|
+
const omt = 1 - tweenProgress;
|
|
1848
|
+
const fr = fn[0], fg = fn[1], fb = fn[2];
|
|
1849
|
+
const tr = tn[0], tg = tn[1], tb = tn[2];
|
|
1850
|
+
// RGB channels lerp in pseudo-linear space (square inputs, sqrt result) to approximate gamma-correct blending.
|
|
1851
|
+
// See https://developer.nvidia.com/gpugems/gpugems3/part-iv-image-effects/chapter-24-importance-being-linear.
|
|
1852
|
+
ns[0] = /** @type {Number} */(tweenModifier(Math.sqrt(fr * fr * omt + tr * tr * tweenProgress)));
|
|
1853
|
+
ns[1] = /** @type {Number} */(tweenModifier(Math.sqrt(fg * fg * omt + tg * tg * tweenProgress)));
|
|
1854
|
+
ns[2] = /** @type {Number} */(tweenModifier(Math.sqrt(fb * fb * omt + tb * tb * tweenProgress)));
|
|
1855
|
+
ns[3] = /** @type {Number} */(tweenModifier(lerp$1(fn[3], tn[3], tweenProgress)));
|
|
1856
|
+
// The rgba string is built only for the dispatch path or the internalRender composition tick (setters handles the color comp)
|
|
1857
|
+
if (!tween._setter || internalRender) {
|
|
1858
|
+
value = `rgba(${round$1(ns[0], 0)},${round$1(ns[1], 0)},${round$1(ns[2], 0)},${ns[3]})`;
|
|
1859
|
+
}
|
|
1737
1860
|
} else if (tweenValueType === valueTypes.COMPLEX) {
|
|
1738
1861
|
value = composeComplexValue(tween, tweenProgress, tweenPrecision);
|
|
1739
1862
|
}
|
|
@@ -1748,7 +1871,9 @@
|
|
|
1748
1871
|
const tweenProperty = tween.property;
|
|
1749
1872
|
tweenTarget = tween.target;
|
|
1750
1873
|
|
|
1751
|
-
if (
|
|
1874
|
+
if (tween._setter) {
|
|
1875
|
+
tween._setter(tweenTarget, number, tween);
|
|
1876
|
+
} else if (tweenIsObject) {
|
|
1752
1877
|
tweenTarget[tweenProperty] = value;
|
|
1753
1878
|
} else if (tweenType === tweenTypes.ATTRIBUTE) {
|
|
1754
1879
|
/** @type {DOMTarget} */(tweenTarget).setAttribute(tweenProperty, /** @type {String} */(value));
|
|
@@ -1776,6 +1901,9 @@
|
|
|
1776
1901
|
tween._value = value;
|
|
1777
1902
|
}
|
|
1778
1903
|
|
|
1904
|
+
} else if (tweenCurrentTime && tweenPrevRep && !tweenPrevRepIsCrossParent && iterationTime < tween._startTime) {
|
|
1905
|
+
// Mark the keyframe as reverted when the playhead moves before its start, the previous keyframe owns the from revert and writes it once.
|
|
1906
|
+
tween._currentTime = 0;
|
|
1779
1907
|
}
|
|
1780
1908
|
|
|
1781
1909
|
if (tweenTransformsNeedUpdate && tween._renderTransforms) {
|
|
@@ -1836,50 +1964,6 @@
|
|
|
1836
1964
|
return hasRendered;
|
|
1837
1965
|
};
|
|
1838
1966
|
|
|
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
|
-
|
|
1883
1967
|
/**
|
|
1884
1968
|
* @param {Tickable} tickable
|
|
1885
1969
|
* @param {Number} time
|
|
@@ -1896,28 +1980,44 @@
|
|
|
1896
1980
|
const tlIsRunningBackwards = tl.backwards;
|
|
1897
1981
|
const tlChildrenTime = internalRender ? time : tl._iterationTime;
|
|
1898
1982
|
const tlCildrenTickTime = now();
|
|
1983
|
+
|
|
1899
1984
|
let tlChildrenHasRendered = 0;
|
|
1900
1985
|
let tlChildrenHaveCompleted = true;
|
|
1986
|
+
|
|
1901
1987
|
// If the timeline has looped forward, we need to manually triggers children skipped callbacks
|
|
1902
1988
|
if (!internalRender && tl._currentIteration !== _currentIteration) {
|
|
1903
1989
|
const tlIterationDuration = tl.iterationDuration;
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1990
|
+
forEachChildren(tl, (/** @type {JSAnimation} */child) => {
|
|
1991
|
+
if (!tlIsRunningBackwards) {
|
|
1992
|
+
// Force an internal render to trigger the callbacks if the child has not completed on loop
|
|
1993
|
+
if (!child.completed && !child.backwards && child._currentTime < child.iterationDuration) {
|
|
1994
|
+
render(child, tlIterationDuration, muteCallbacks, 1, tickModes.FORCE);
|
|
1995
|
+
}
|
|
1996
|
+
// Reset their began and completed flags to allow retrigering callbacks on the next iteration
|
|
1997
|
+
child.began = false;
|
|
1998
|
+
child.completed = false;
|
|
1999
|
+
} else {
|
|
2000
|
+
const childDuration = child.duration;
|
|
2001
|
+
const childStartTime = child._offset + child._delay;
|
|
2002
|
+
const childEndTime = childStartTime + childDuration;
|
|
2003
|
+
// Triggers the onComplete callback on reverse for children on the edges of the timeline
|
|
2004
|
+
if (!muteCallbacks && childDuration <= minValue && (!childStartTime || childEndTime === tlIterationDuration)) {
|
|
2005
|
+
child.onComplete(child);
|
|
2006
|
+
}
|
|
2007
|
+
}
|
|
2008
|
+
});
|
|
1908
2009
|
if (!muteCallbacks) tl.onLoop(/** @type {CallbackArgument} */(tl));
|
|
1909
2010
|
}
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
tlChildrenHaveCompleted = renderCtxChildrenHaveCompleted;
|
|
2011
|
+
|
|
2012
|
+
forEachChildren(tl, (/** @type {JSAnimation} */child) => {
|
|
2013
|
+
const childTime = round$1((tlChildrenTime - child._offset) * child._speed, 12); // Rounding is needed when using seconds
|
|
2014
|
+
// 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.
|
|
2015
|
+
if (tlIsRunningBackwards && childTime > child._delay + child.duration) return;
|
|
2016
|
+
const childTickMode = child._fps < tl._fps ? child.requestTick(tlCildrenTickTime) : tickMode;
|
|
2017
|
+
tlChildrenHasRendered += render(child, childTime, muteCallbacks, internalRender, childTickMode);
|
|
2018
|
+
if (!child.completed && tlChildrenHaveCompleted) tlChildrenHaveCompleted = false;
|
|
2019
|
+
}, tlIsRunningBackwards);
|
|
2020
|
+
|
|
1921
2021
|
// Renders on timeline are triggered by its children so it needs to be set after rendering the children
|
|
1922
2022
|
if (!muteCallbacks && tlChildrenHasRendered) tl.onRender(/** @type {CallbackArgument} */(tl));
|
|
1923
2023
|
// Triggers the timeline onComplete() once all chindren all completed and the current time has reached the end
|
|
@@ -1989,7 +2089,20 @@
|
|
|
1989
2089
|
const tweenType = tween._tweenType;
|
|
1990
2090
|
const originalInlinedValue = tween._inlineValue;
|
|
1991
2091
|
const tweenHadNoInlineValue = isNil(originalInlinedValue) || originalInlinedValue === emptyString;
|
|
1992
|
-
if (
|
|
2092
|
+
if (tween._setter) {
|
|
2093
|
+
if (!inlineStylesOnly && !tweenHadNoInlineValue) {
|
|
2094
|
+
// 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.
|
|
2095
|
+
decomposeRawValue(originalInlinedValue, decomposedOriginalValue);
|
|
2096
|
+
if (decomposedOriginalValue.d) {
|
|
2097
|
+
const src = decomposedOriginalValue.d;
|
|
2098
|
+
const dst = tween._numbers;
|
|
2099
|
+
for (let i = 0, l = src.length; i < l; i++) dst[i] = src[i];
|
|
2100
|
+
} else {
|
|
2101
|
+
tween._number = decomposedOriginalValue.n;
|
|
2102
|
+
}
|
|
2103
|
+
tween._setter(tween.target, tween._number, tween);
|
|
2104
|
+
}
|
|
2105
|
+
} else if (tweenType === tweenTypes.OBJECT) {
|
|
1993
2106
|
if (!inlineStylesOnly && !tweenHadNoInlineValue) {
|
|
1994
2107
|
tweenTarget[tweenProperty] = originalInlinedValue;
|
|
1995
2108
|
}
|
|
@@ -2066,8 +2179,6 @@
|
|
|
2066
2179
|
/** @type {Number} */
|
|
2067
2180
|
this._lastTime = initTime;
|
|
2068
2181
|
/** @type {Number} */
|
|
2069
|
-
this._scheduledTime = 0;
|
|
2070
|
-
/** @type {Number} */
|
|
2071
2182
|
this._frameDuration = K / maxFps;
|
|
2072
2183
|
/** @type {Number} */
|
|
2073
2184
|
this._fps = maxFps;
|
|
@@ -2086,14 +2197,12 @@
|
|
|
2086
2197
|
}
|
|
2087
2198
|
|
|
2088
2199
|
set fps(frameRate) {
|
|
2089
|
-
const previousFrameDuration = this._frameDuration;
|
|
2090
2200
|
const fr = +frameRate;
|
|
2091
2201
|
const fps = fr < minValue ? minValue : fr;
|
|
2092
2202
|
const frameDuration = K / fps;
|
|
2093
2203
|
if (fps > defaults.frameRate) defaults.frameRate = fps;
|
|
2094
2204
|
this._fps = fps;
|
|
2095
2205
|
this._frameDuration = frameDuration;
|
|
2096
|
-
this._scheduledTime += frameDuration - previousFrameDuration;
|
|
2097
2206
|
}
|
|
2098
2207
|
|
|
2099
2208
|
get speed() {
|
|
@@ -2110,17 +2219,17 @@
|
|
|
2110
2219
|
* @return {tickModes}
|
|
2111
2220
|
*/
|
|
2112
2221
|
requestTick(time) {
|
|
2113
|
-
const scheduledTime = this._scheduledTime;
|
|
2114
|
-
this._lastTickTime = time;
|
|
2115
|
-
// If the current time is lower than the scheduled time
|
|
2116
|
-
// this means not enough time has passed to hit one frameDuration
|
|
2117
|
-
// so skip that frame
|
|
2118
|
-
if (time < scheduledTime) return tickModes.NONE;
|
|
2119
2222
|
const frameDuration = this._frameDuration;
|
|
2120
|
-
const
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2223
|
+
const elapsed = time - this._lastTickTime;
|
|
2224
|
+
const scaled = frameDuration * .25;
|
|
2225
|
+
const tolerance = scaled < 4 ? scaled : 4;
|
|
2226
|
+
// Tolerance prevents dropping frames that arrive a bit early due to RAF jitter
|
|
2227
|
+
// typically <= ~25% of frame duration and capped at 4ms so it doesn't dominate at high fps.
|
|
2228
|
+
// e.g. at 60fps (frameDuration=16.667ms) a frame arriving after 15ms:
|
|
2229
|
+
// - without tolerance: 15 < 16.667 -> skip
|
|
2230
|
+
// - with tolerance: 15 + 4 >= 16.667 -> tick
|
|
2231
|
+
if (elapsed + tolerance < frameDuration) return tickModes.NONE;
|
|
2232
|
+
this._lastTickTime = elapsed >= frameDuration ? time - (elapsed % frameDuration) : time;
|
|
2124
2233
|
return tickModes.AUTO;
|
|
2125
2234
|
}
|
|
2126
2235
|
|
|
@@ -2280,7 +2389,9 @@
|
|
|
2280
2389
|
}
|
|
2281
2390
|
|
|
2282
2391
|
set speed(playbackRate) {
|
|
2283
|
-
|
|
2392
|
+
const speed = playbackRate * globals.timeScale;
|
|
2393
|
+
if (this._speed === speed) return;
|
|
2394
|
+
this._speed = speed;
|
|
2284
2395
|
forEachChildren(this, (/** @type {Tickable} */child) => child.speed = child._speed);
|
|
2285
2396
|
}
|
|
2286
2397
|
|
|
@@ -2413,7 +2524,7 @@
|
|
|
2413
2524
|
if (prevSibling) {
|
|
2414
2525
|
|
|
2415
2526
|
const prevParent = prevSibling.parent;
|
|
2416
|
-
const prevAbsEndTime = prevSibling.
|
|
2527
|
+
const prevAbsEndTime = prevSibling._absoluteEndTime;
|
|
2417
2528
|
|
|
2418
2529
|
// Handle looped animations tween
|
|
2419
2530
|
|
|
@@ -2439,7 +2550,8 @@
|
|
|
2439
2550
|
|
|
2440
2551
|
}
|
|
2441
2552
|
|
|
2442
|
-
|
|
2553
|
+
// 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.
|
|
2554
|
+
const absoluteUpdateStartTime = tween._absoluteUpdateStartTime;
|
|
2443
2555
|
|
|
2444
2556
|
if (prevAbsEndTime > absoluteUpdateStartTime) {
|
|
2445
2557
|
|
|
@@ -2459,37 +2571,41 @@
|
|
|
2459
2571
|
}
|
|
2460
2572
|
}
|
|
2461
2573
|
|
|
2462
|
-
//
|
|
2574
|
+
// Skip the cancel cascade when both tweens share the same parent timeline, a timeline cannot replace itself.
|
|
2575
|
+
const tweenParentTL = tween.parent.parent;
|
|
2576
|
+
if (!tweenParentTL || tweenParentTL !== prevParent.parent) {
|
|
2463
2577
|
|
|
2464
|
-
|
|
2578
|
+
let pausePrevParentAnimation = true;
|
|
2465
2579
|
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2580
|
+
forEachChildren(prevParent, (/** @type Tween */t) => {
|
|
2581
|
+
if (!t._isOverlapped) pausePrevParentAnimation = false;
|
|
2582
|
+
});
|
|
2469
2583
|
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2584
|
+
if (pausePrevParentAnimation) {
|
|
2585
|
+
const prevParentTL = prevParent.parent;
|
|
2586
|
+
if (prevParentTL) {
|
|
2587
|
+
let pausePrevParentTL = true;
|
|
2588
|
+
forEachChildren(prevParentTL, (/** @type JSAnimation */a) => {
|
|
2589
|
+
if (a !== prevParent) {
|
|
2590
|
+
forEachChildren(a, (/** @type Tween */t) => {
|
|
2591
|
+
if (!t._isOverlapped) pausePrevParentTL = false;
|
|
2592
|
+
});
|
|
2593
|
+
}
|
|
2594
|
+
});
|
|
2595
|
+
if (pausePrevParentTL) {
|
|
2596
|
+
prevParentTL.cancel();
|
|
2479
2597
|
}
|
|
2480
|
-
}
|
|
2481
|
-
|
|
2482
|
-
|
|
2598
|
+
} else {
|
|
2599
|
+
prevParent.cancel();
|
|
2600
|
+
// Previously, calling .cancel() on a timeline child would affect the render order of other children
|
|
2601
|
+
// Worked around this by marking it as .completed and using .pause() for safe removal in the engine loop
|
|
2602
|
+
// This is no longer needed since timeline tween composition is now handled separately
|
|
2603
|
+
// Keeping this here for reference
|
|
2604
|
+
// prevParent.completed = true;
|
|
2605
|
+
// prevParent.pause();
|
|
2483
2606
|
}
|
|
2484
|
-
} else {
|
|
2485
|
-
prevParent.cancel();
|
|
2486
|
-
// Previously, calling .cancel() on a timeline child would affect the render order of other children
|
|
2487
|
-
// Worked around this by marking it as .completed and using .pause() for safe removal in the engine loop
|
|
2488
|
-
// This is no longer needed since timeline tween composition is now handled separately
|
|
2489
|
-
// Keeping this here for reference
|
|
2490
|
-
// prevParent.completed = true;
|
|
2491
|
-
// prevParent.pause();
|
|
2492
2607
|
}
|
|
2608
|
+
|
|
2493
2609
|
}
|
|
2494
2610
|
|
|
2495
2611
|
}
|
|
@@ -2544,14 +2660,12 @@
|
|
|
2544
2660
|
tween._number = 0;
|
|
2545
2661
|
lookupTween._fromNumber = toNumber;
|
|
2546
2662
|
|
|
2547
|
-
if (tween._toNumbers) {
|
|
2663
|
+
if (tween._toNumbers.length) {
|
|
2548
2664
|
const toNumbers = cloneArray(tween._toNumbers);
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
});
|
|
2554
|
-
}
|
|
2665
|
+
toNumbers.forEach((value, i) => {
|
|
2666
|
+
tween._fromNumbers[i] = lookupTween._fromNumbers[i] - value;
|
|
2667
|
+
tween._toNumbers[i] = 0;
|
|
2668
|
+
});
|
|
2555
2669
|
lookupTween._fromNumbers = toNumbers;
|
|
2556
2670
|
}
|
|
2557
2671
|
|
|
@@ -3252,18 +3366,16 @@
|
|
|
3252
3366
|
function registerTargets(targets) {
|
|
3253
3367
|
const parsedTargetsArray = parseTargets(targets);
|
|
3254
3368
|
const parsedTargetsLength = parsedTargetsArray.length;
|
|
3255
|
-
|
|
3256
|
-
|
|
3257
|
-
|
|
3258
|
-
|
|
3259
|
-
|
|
3260
|
-
|
|
3261
|
-
|
|
3262
|
-
|
|
3263
|
-
|
|
3264
|
-
|
|
3265
|
-
target[transformsSymbol] = {};
|
|
3266
|
-
}
|
|
3369
|
+
for (let i = 0; i < parsedTargetsLength; i++) {
|
|
3370
|
+
const target = parsedTargetsArray[i];
|
|
3371
|
+
if (!target[isRegisteredTargetSymbol]) {
|
|
3372
|
+
target[isRegisteredTargetSymbol] = true;
|
|
3373
|
+
const isSvgType = isSvg(target);
|
|
3374
|
+
const isDom = /** @type {DOMTarget} */(target).nodeType || isSvgType;
|
|
3375
|
+
if (isDom) {
|
|
3376
|
+
target[isDomSymbol] = true;
|
|
3377
|
+
target[isSvgSymbol] = isSvgType;
|
|
3378
|
+
target[transformsSymbol] = {};
|
|
3267
3379
|
}
|
|
3268
3380
|
}
|
|
3269
3381
|
}
|
|
@@ -3385,8 +3497,8 @@
|
|
|
3385
3497
|
|
|
3386
3498
|
/**
|
|
3387
3499
|
* @typedef {Object} EasesFunctions
|
|
3388
|
-
* @property {
|
|
3389
|
-
* @property {
|
|
3500
|
+
* @property {EasingFunction} linear
|
|
3501
|
+
* @property {EasingFunction} none
|
|
3390
3502
|
* @property {PowerEasing} in
|
|
3391
3503
|
* @property {PowerEasing} out
|
|
3392
3504
|
* @property {PowerEasing} inOut
|
|
@@ -3618,6 +3730,11 @@
|
|
|
3618
3730
|
|
|
3619
3731
|
super(/** @type {TimerParams & AnimationParams} */(parameters), parent, parentPosition);
|
|
3620
3732
|
|
|
3733
|
+
/** @type {Tween} */
|
|
3734
|
+
this._head;
|
|
3735
|
+
/** @type {Tween} */
|
|
3736
|
+
this._tail;
|
|
3737
|
+
|
|
3621
3738
|
++JSAnimationId;
|
|
3622
3739
|
|
|
3623
3740
|
const parsedTargets = registerTargets(targets);
|
|
@@ -3674,6 +3791,7 @@
|
|
|
3674
3791
|
if (isKey(p)) {
|
|
3675
3792
|
|
|
3676
3793
|
const tweenType = getTweenType(target, p);
|
|
3794
|
+
const adapterProp = resolveAdapterEntry(target, p);
|
|
3677
3795
|
|
|
3678
3796
|
const propName = sanitizePropertyName(p, target, tweenType);
|
|
3679
3797
|
|
|
@@ -3757,7 +3875,7 @@
|
|
|
3757
3875
|
} else {
|
|
3758
3876
|
tweenToValue = computedToValue;
|
|
3759
3877
|
}
|
|
3760
|
-
const tweenFromValue = getFunctionValue(key.from, target, ti, tl,
|
|
3878
|
+
const tweenFromValue = getFunctionValue(key.from, target, ti, tl, fromFunctionStore, prevSiblingTween);
|
|
3761
3879
|
const easeToParse = key.ease || tEasing;
|
|
3762
3880
|
|
|
3763
3881
|
const easeFunctionResult = getFunctionValue(easeToParse, target, ti, tl, null, prevSiblingTween);
|
|
@@ -3775,9 +3893,13 @@
|
|
|
3775
3893
|
const hasToValue = !isUnd(tweenToValue);
|
|
3776
3894
|
const isFromToArray = isArr(tweenToValue);
|
|
3777
3895
|
const isFromToValue = isFromToArray || (hasFromvalue && hasToValue);
|
|
3896
|
+
// 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.
|
|
3897
|
+
const tweenUpdateStartLocal = prevTween ? lastTweenChangeEndTime : 0;
|
|
3778
3898
|
const tweenStartTime = prevTween ? lastTweenChangeEndTime + tweenDelay : tweenDelay;
|
|
3779
3899
|
// Rounding is necessary here to minimize floating point errors when working in seconds
|
|
3780
3900
|
const absoluteStartTime = round$1(absoluteOffsetTime + tweenStartTime, 12);
|
|
3901
|
+
// Match the rounding pattern of prevSibling._absoluteEndTime so the composition overlap check compares cleanly when keyframes touch at a boundary.
|
|
3902
|
+
const absoluteUpdateStartTime = round$1(absoluteOffsetTime + tweenUpdateStartLocal, 12);
|
|
3781
3903
|
|
|
3782
3904
|
// Force a onRender callback if the animation contains at least one from value and autoplay is set to false
|
|
3783
3905
|
if (!shouldTriggerRender && (hasFromvalue || isFromToArray)) shouldTriggerRender = 1;
|
|
@@ -3786,9 +3908,9 @@
|
|
|
3786
3908
|
|
|
3787
3909
|
if (tweenComposition !== compositionTypes.none) {
|
|
3788
3910
|
let nextSibling = siblings._head;
|
|
3789
|
-
//
|
|
3790
|
-
while (nextSibling &&
|
|
3791
|
-
prevSibling = nextSibling;
|
|
3911
|
+
// 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.
|
|
3912
|
+
while (nextSibling && nextSibling._absoluteStartTime <= absoluteStartTime) {
|
|
3913
|
+
if (!nextSibling._isOverridden) prevSibling = nextSibling;
|
|
3792
3914
|
nextSibling = nextSibling._nextRep;
|
|
3793
3915
|
// Overrides all the next siblings if the next sibling starts at the same time of after as the new tween start time
|
|
3794
3916
|
if (nextSibling && nextSibling._absoluteStartTime >= absoluteStartTime) {
|
|
@@ -3842,8 +3964,8 @@
|
|
|
3842
3964
|
if (prevTween) {
|
|
3843
3965
|
decomposeTweenValue(prevTween, fromTargetObject);
|
|
3844
3966
|
} else {
|
|
3845
|
-
decomposeRawValue(parent && prevSibling && prevSibling.parent.parent === parent ? prevSibling._value :
|
|
3846
3967
|
// 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
|
|
3968
|
+
decomposeRawValue(parent && prevSibling && prevSibling.parent.parent === parent ? prevSibling._value :
|
|
3847
3969
|
getOriginalAnimatableValue(target, propName, tweenType, inlineStylesStore), fromTargetObject);
|
|
3848
3970
|
}
|
|
3849
3971
|
}
|
|
@@ -3882,8 +4004,7 @@
|
|
|
3882
4004
|
const colorValue = fromTargetObject.t === valueTypes.COLOR ? fromTargetObject : toTargetObject;
|
|
3883
4005
|
const notColorValue = fromTargetObject.t === valueTypes.COLOR ? toTargetObject : fromTargetObject;
|
|
3884
4006
|
notColorValue.t = valueTypes.COLOR;
|
|
3885
|
-
notColorValue.
|
|
3886
|
-
notColorValue.d = [0, 0, 0, 1];
|
|
4007
|
+
notColorValue.d = colorValue.d.map(() => 0);
|
|
3887
4008
|
}
|
|
3888
4009
|
}
|
|
3889
4010
|
|
|
@@ -3913,6 +4034,16 @@
|
|
|
3913
4034
|
let inlineValue = inlineStylesStore[propName];
|
|
3914
4035
|
if (!isNil(inlineValue)) inlineStylesStore[propName] = null;
|
|
3915
4036
|
|
|
4037
|
+
// Resolve the adapter setter once so render skips the lookup per frame.
|
|
4038
|
+
const tweenSetter = adapterProp ? adapterProp.set : null;
|
|
4039
|
+
|
|
4040
|
+
// Rounding is necessary here to minimize floating point errors when working in seconds
|
|
4041
|
+
lastTweenChangeEndTime = round$1(tweenStartTime + tweenUpdateDuration, 12);
|
|
4042
|
+
|
|
4043
|
+
const fromD = fromTargetObject.d;
|
|
4044
|
+
const toD = toTargetObject.d;
|
|
4045
|
+
const toS = toTargetObject.s;
|
|
4046
|
+
|
|
3916
4047
|
/** @type {Tween} */
|
|
3917
4048
|
const tween = {
|
|
3918
4049
|
parent: this,
|
|
@@ -3923,12 +4054,12 @@
|
|
|
3923
4054
|
_toFunc: toFunctionStore.func,
|
|
3924
4055
|
_fromFunc: fromFunctionStore.func,
|
|
3925
4056
|
_ease: parseEase(tweenEasing),
|
|
3926
|
-
_fromNumbers: cloneArray(
|
|
3927
|
-
_toNumbers: cloneArray(
|
|
3928
|
-
_strings: cloneArray(
|
|
4057
|
+
_fromNumbers: fromD ? cloneArray(fromD) : emptyArray,
|
|
4058
|
+
_toNumbers: toD ? cloneArray(toD) : emptyArray,
|
|
4059
|
+
_strings: toS ? cloneArray(toS) : emptyArray,
|
|
3929
4060
|
_fromNumber: fromTargetObject.n,
|
|
3930
4061
|
_toNumber: toTargetObject.n,
|
|
3931
|
-
_numbers: cloneArray(
|
|
4062
|
+
_numbers: fromD ? cloneArray(fromD) : emptyArray, // For additive tween and animatables
|
|
3932
4063
|
_number: fromTargetObject.n, // For additive tween and animatables
|
|
3933
4064
|
_unit: toTargetObject.u,
|
|
3934
4065
|
_modifier: tweenModifier,
|
|
@@ -3938,8 +4069,12 @@
|
|
|
3938
4069
|
_updateDuration: tweenUpdateDuration,
|
|
3939
4070
|
_changeDuration: tweenUpdateDuration,
|
|
3940
4071
|
_absoluteStartTime: absoluteStartTime,
|
|
4072
|
+
_absoluteUpdateStartTime: absoluteUpdateStartTime,
|
|
4073
|
+
_absoluteEndTime: round$1(absoluteOffsetTime + lastTweenChangeEndTime, 12),
|
|
4074
|
+
_hasFromValue: hasFromvalue || isFromToArray ? 1 : 0,
|
|
3941
4075
|
// NOTE: Investigate bit packing to stores ENUM / BOOL
|
|
3942
4076
|
_tweenType: tweenType,
|
|
4077
|
+
_setter: tweenSetter,
|
|
3943
4078
|
_valueType: toTargetObject.t,
|
|
3944
4079
|
_composition: tweenComposition,
|
|
3945
4080
|
_isOverlapped: 0,
|
|
@@ -3962,10 +4097,11 @@
|
|
|
3962
4097
|
const vt = tween._valueType;
|
|
3963
4098
|
if (vt === valueTypes.COMPLEX) {
|
|
3964
4099
|
tween._value = composeComplexValue(tween, 1, -1);
|
|
3965
|
-
} else if (vt === valueTypes.COLOR) {
|
|
3966
|
-
tween._value = composeColorValue(tween, 1, -1);
|
|
3967
4100
|
} else if (vt === valueTypes.UNIT) {
|
|
3968
4101
|
tween._value = `${tweenModifier(tween._toNumber)}${tween._unit}`;
|
|
4102
|
+
} else if (vt === valueTypes.COLOR) {
|
|
4103
|
+
const d = toTargetObject.d;
|
|
4104
|
+
tween._value = `rgba(${round$1(d[0], 0)},${round$1(d[1], 0)},${round$1(d[2], 0)},${d[3]})`;
|
|
3969
4105
|
} else {
|
|
3970
4106
|
tween._value = tweenModifier(tween._toNumber);
|
|
3971
4107
|
}
|
|
@@ -3973,8 +4109,7 @@
|
|
|
3973
4109
|
if (isNaN(firstTweenChangeStartTime)) {
|
|
3974
4110
|
firstTweenChangeStartTime = tween._startTime;
|
|
3975
4111
|
}
|
|
3976
|
-
|
|
3977
|
-
lastTweenChangeEndTime = round$1(tweenStartTime + tweenUpdateDuration, 12);
|
|
4112
|
+
|
|
3978
4113
|
prevTween = tween;
|
|
3979
4114
|
animationAnimationLength++;
|
|
3980
4115
|
|
|
@@ -4080,8 +4215,11 @@
|
|
|
4080
4215
|
tween._updateDuration = normalizeTime(tween._updateDuration * timeScale);
|
|
4081
4216
|
tween._changeDuration = normalizeTime(tween._changeDuration * timeScale);
|
|
4082
4217
|
tween._currentTime *= timeScale;
|
|
4218
|
+
tween._delay *= timeScale;
|
|
4083
4219
|
tween._startTime *= timeScale;
|
|
4084
4220
|
tween._absoluteStartTime *= timeScale;
|
|
4221
|
+
tween._absoluteUpdateStartTime *= timeScale;
|
|
4222
|
+
tween._absoluteEndTime *= timeScale;
|
|
4085
4223
|
});
|
|
4086
4224
|
return super.stretch(newDuration);
|
|
4087
4225
|
}
|
|
@@ -4210,8 +4348,6 @@
|
|
|
4210
4348
|
|
|
4211
4349
|
|
|
4212
4350
|
|
|
4213
|
-
|
|
4214
|
-
|
|
4215
4351
|
/**
|
|
4216
4352
|
* @param {Timeline} tl
|
|
4217
4353
|
* @return {Number}
|
|
@@ -4404,13 +4540,21 @@
|
|
|
4404
4540
|
if (!isUnd(synced) && !isUnd(/** @type {WAAPIAnimation} */(synced).persist)) {
|
|
4405
4541
|
/** @type {WAAPIAnimation} */(synced).persist = true;
|
|
4406
4542
|
}
|
|
4407
|
-
|
|
4543
|
+
const editor = globals.editor;
|
|
4544
|
+
const childHook = editor && editor.addTimelineChild;
|
|
4545
|
+
if (editor && editor.addTimelineSync) {
|
|
4546
|
+
position = editor.addTimelineSync(synced, position, this.id);
|
|
4547
|
+
editor.addTimelineChild = null; // Suppress the per-child hook for the internal .add, sync already registered.
|
|
4548
|
+
}
|
|
4549
|
+
const result = this.add(synced, { currentTime: [0, duration], duration, delay: 0, ease: 'linear', playbackEase: 'linear' }, position);
|
|
4550
|
+
if (editor) editor.addTimelineChild = childHook;
|
|
4551
|
+
return result;
|
|
4408
4552
|
}
|
|
4409
4553
|
|
|
4410
4554
|
/**
|
|
4411
4555
|
* @param {TargetsParam} targets
|
|
4412
4556
|
* @param {AnimationParams} parameters
|
|
4413
|
-
* @param {TimelinePosition} [position]
|
|
4557
|
+
* @param {TimelinePosition|StaggerFunction<Number|String>|TweakRegister} [position]
|
|
4414
4558
|
* @return {this}
|
|
4415
4559
|
*/
|
|
4416
4560
|
set(targets, parameters, position) {
|
|
@@ -4427,6 +4571,7 @@
|
|
|
4427
4571
|
*/
|
|
4428
4572
|
call(callback, position) {
|
|
4429
4573
|
if (isUnd(callback) || callback && !isFnc(callback)) return this;
|
|
4574
|
+
if (globals.editor && globals.editor.addTimelineCall) position = globals.editor.addTimelineCall(callback, position, this.id);
|
|
4430
4575
|
return this.add({ duration: 0, delay: 0, onComplete: () => callback(this) }, position);
|
|
4431
4576
|
}
|
|
4432
4577
|
|
|
@@ -4438,6 +4583,7 @@
|
|
|
4438
4583
|
*/
|
|
4439
4584
|
label(labelName, position) {
|
|
4440
4585
|
if (isUnd(labelName) || labelName && !isStr(labelName)) return this;
|
|
4586
|
+
if (globals.editor && globals.editor.addTimelineLabel) position = globals.editor.addTimelineLabel(labelName, position, this.id);
|
|
4441
4587
|
this.labels[labelName] = parseTimelinePosition(this, position);
|
|
4442
4588
|
return this;
|
|
4443
4589
|
}
|
|
@@ -4546,6 +4692,7 @@
|
|
|
4546
4692
|
const callbacksAnimationParams = { v: 1, autoplay: false };
|
|
4547
4693
|
const properties = {};
|
|
4548
4694
|
this.targets = [];
|
|
4695
|
+
/** @type {Record<String, JSAnimation>} */
|
|
4549
4696
|
this.animations = {};
|
|
4550
4697
|
/** @type {JSAnimation|null} */
|
|
4551
4698
|
this.callbacks = null;
|
|
@@ -5084,6 +5231,9 @@
|
|
|
5084
5231
|
*/
|
|
5085
5232
|
const set = (targets, parameters) => {
|
|
5086
5233
|
if (isUnd(parameters)) return;
|
|
5234
|
+
if (globals.editor && globals.editor.addSet) {
|
|
5235
|
+
return globals.editor.addSet(targets, parameters);
|
|
5236
|
+
}
|
|
5087
5237
|
parameters.duration = minValue;
|
|
5088
5238
|
// Do not overrides currently active tweens by default
|
|
5089
5239
|
parameters.composition = setValue(parameters.composition, compositionTypes.none);
|
|
@@ -6320,13 +6470,14 @@
|
|
|
6320
6470
|
};
|
|
6321
6471
|
|
|
6322
6472
|
/**
|
|
6323
|
-
* @
|
|
6324
|
-
* @
|
|
6473
|
+
* @template {Tickable | ((...args: any[]) => void) | void} T
|
|
6474
|
+
* @param {(...args: any[]) => T} constructor
|
|
6475
|
+
* @return {(...args: any[]) => T extends void ? () => void : T}
|
|
6325
6476
|
*/
|
|
6326
6477
|
const keepTime = constructor => {
|
|
6327
6478
|
/** @type {Tickable} */
|
|
6328
6479
|
let tracked;
|
|
6329
|
-
return (...args) => {
|
|
6480
|
+
return /** @type {(...args: any[]) => T extends void ? () => void : T} */(/** @type {*} */((...args) => {
|
|
6330
6481
|
let currentIteration, currentIterationProgress, reversed, alternate, startTime;
|
|
6331
6482
|
if (tracked) {
|
|
6332
6483
|
currentIteration = tracked.currentIteration;
|
|
@@ -6344,7 +6495,7 @@
|
|
|
6344
6495
|
/** @type {Tickable} */(tracked)._startTime = startTime;
|
|
6345
6496
|
}
|
|
6346
6497
|
return cleanup || noop;
|
|
6347
|
-
}
|
|
6498
|
+
}));
|
|
6348
6499
|
};
|
|
6349
6500
|
|
|
6350
6501
|
|
|
@@ -6742,12 +6893,14 @@
|
|
|
6742
6893
|
|
|
6743
6894
|
refreshScrollObservers() {
|
|
6744
6895
|
forEachChildren(this, (/** @type {ScrollObserver} */child) => {
|
|
6896
|
+
if (!child.ready) return;
|
|
6745
6897
|
if (child._debug) {
|
|
6746
6898
|
child.removeDebug();
|
|
6747
6899
|
}
|
|
6748
6900
|
});
|
|
6749
6901
|
this.updateBounds();
|
|
6750
6902
|
forEachChildren(this, (/** @type {ScrollObserver} */child) => {
|
|
6903
|
+
if (!child.ready) return;
|
|
6751
6904
|
child.refresh();
|
|
6752
6905
|
child.onResize(child);
|
|
6753
6906
|
if (child._debug) {
|
|
@@ -9845,11 +9998,12 @@
|
|
|
9845
9998
|
* Adapted from https://bost.ocks.org/mike/shuffle/
|
|
9846
9999
|
*
|
|
9847
10000
|
* @param {Array} items - The array to shuffle (will be modified in-place)
|
|
10001
|
+
* @param {RandomNumberGenerator} [rnd] - Optional RNG matching the random() signature (defaults to random)
|
|
9848
10002
|
* @return {Array} The same array reference, now shuffled
|
|
9849
10003
|
*/
|
|
9850
|
-
const shuffle = items => {
|
|
10004
|
+
const shuffle = (items, rnd = random) => {
|
|
9851
10005
|
let m = items.length, t, i;
|
|
9852
|
-
while (m) { i =
|
|
10006
|
+
while (m) { i = rnd(0, --m); t = items[m]; items[m] = items[i]; items[i] = t; }
|
|
9853
10007
|
return items;
|
|
9854
10008
|
};
|
|
9855
10009
|
|
|
@@ -9894,6 +10048,7 @@
|
|
|
9894
10048
|
let values = [];
|
|
9895
10049
|
let maxValue = 0;
|
|
9896
10050
|
let cachedOffset;
|
|
10051
|
+
let jitterSamples = null;
|
|
9897
10052
|
const from = params.from;
|
|
9898
10053
|
const reversed = params.reversed;
|
|
9899
10054
|
const ease = params.ease;
|
|
@@ -9915,27 +10070,42 @@
|
|
|
9915
10070
|
const val2 = isRange ? parseNumber(val[1]) : 0;
|
|
9916
10071
|
const unitMatch = unitsExecRgx.exec((isRange ? val[1] : val) + emptyString);
|
|
9917
10072
|
const start = params.start || 0 + (isRange ? val1 : 0);
|
|
10073
|
+
const seed = params.seed;
|
|
10074
|
+
const hasSeed = !isUnd(seed) && seed !== false;
|
|
10075
|
+
const rng = hasSeed ? createSeededRandom(seed === true ? 0 : /** @type {Number} */(seed)) : random;
|
|
10076
|
+
const jitter = params.jitter;
|
|
10077
|
+
const hasJitter = !isUnd(jitter);
|
|
10078
|
+
const jitterIsArr = isArr(jitter);
|
|
10079
|
+
const jitterStart = jitterIsArr ? /** @type {[Number,Number]} */(jitter)[0] : /** @type {Number} */(jitter) || 0;
|
|
10080
|
+
const jitterEnd = jitterIsArr ? /** @type {[Number,Number]} */(jitter)[1] : /** @type {Number} */(jitter) || 0;
|
|
9918
10081
|
let fromIndex = fromFirst ? 0 : isNum(from) ? from : 0;
|
|
9919
10082
|
return (target, i, t, _, tl) => {
|
|
9920
10083
|
const [ registeredTarget ] = registerTargets(target);
|
|
9921
10084
|
const total = isUnd(customTotal) ? t.length : customTotal;
|
|
9922
10085
|
const customIndex = !isUnd(useProp) ? isFnc(useProp) ? useProp(registeredTarget, i, total) : getOriginalAnimatableValue(registeredTarget, useProp) : false;
|
|
9923
|
-
const
|
|
10086
|
+
const customIdx = isNum(customIndex) || isStr(customIndex) && isNum(+customIndex) ? +customIndex : i;
|
|
10087
|
+
// Fall back to the natural index when the resolved value lands outside [0, total) so values[staggerIndex] never reads undefined.
|
|
10088
|
+
const staggerIndex = customIdx >= 0 && customIdx < total ? customIdx : i;
|
|
9924
10089
|
if (fromCenter) fromIndex = (total - 1) / 2;
|
|
9925
10090
|
if (fromLast) fromIndex = total - 1;
|
|
9926
10091
|
if (!values.length) {
|
|
9927
10092
|
if (autoGrid) {
|
|
9928
10093
|
let hasPositions = true;
|
|
10094
|
+
let has3D = false;
|
|
9929
10095
|
let minPosX = Infinity;
|
|
9930
10096
|
let minPosY = Infinity;
|
|
10097
|
+
let minPosZ = Infinity;
|
|
9931
10098
|
let maxPosX = -Infinity;
|
|
9932
10099
|
let maxPosY = -Infinity;
|
|
10100
|
+
let maxPosZ = -Infinity;
|
|
9933
10101
|
const pxArr = [];
|
|
9934
10102
|
const pyArr = [];
|
|
10103
|
+
const pzArr = [];
|
|
9935
10104
|
for (let index = 0; index < total; index++) {
|
|
9936
10105
|
const el = t[index];
|
|
9937
10106
|
let px = 0;
|
|
9938
10107
|
let py = 0;
|
|
10108
|
+
let pz = 0;
|
|
9939
10109
|
let found = false;
|
|
9940
10110
|
if (el && isFnc(el.getBoundingClientRect)) {
|
|
9941
10111
|
const rect = el.getBoundingClientRect();
|
|
@@ -9947,6 +10117,10 @@
|
|
|
9947
10117
|
if (obj && isNum(obj.x) && isNum(obj.y)) {
|
|
9948
10118
|
px = obj.x;
|
|
9949
10119
|
py = obj.y;
|
|
10120
|
+
if (isNum(obj.z)) {
|
|
10121
|
+
pz = obj.z;
|
|
10122
|
+
has3D = true;
|
|
10123
|
+
}
|
|
9950
10124
|
found = true;
|
|
9951
10125
|
}
|
|
9952
10126
|
}
|
|
@@ -9956,42 +10130,52 @@
|
|
|
9956
10130
|
}
|
|
9957
10131
|
pxArr.push(px);
|
|
9958
10132
|
pyArr.push(py);
|
|
10133
|
+
pzArr.push(pz);
|
|
9959
10134
|
if (px < minPosX) minPosX = px;
|
|
9960
10135
|
if (py < minPosY) minPosY = py;
|
|
10136
|
+
if (pz < minPosZ) minPosZ = pz;
|
|
9961
10137
|
if (px > maxPosX) maxPosX = px;
|
|
9962
10138
|
if (py > maxPosY) maxPosY = py;
|
|
10139
|
+
if (pz > maxPosZ) maxPosZ = pz;
|
|
9963
10140
|
}
|
|
9964
10141
|
if (hasPositions) {
|
|
9965
10142
|
let fX = pxArr[0];
|
|
9966
10143
|
let fY = pyArr[0];
|
|
10144
|
+
let fZ = pzArr[0];
|
|
9967
10145
|
if (fromArr) {
|
|
9968
10146
|
fX = minPosX + from[0] * (maxPosX - minPosX);
|
|
9969
10147
|
fY = minPosY + from[1] * (maxPosY - minPosY);
|
|
10148
|
+
fZ = has3D ? minPosZ + (from.length >= 3 ? from[2] : 0.5) * (maxPosZ - minPosZ) : 0;
|
|
9970
10149
|
} else if (fromCenter) {
|
|
9971
10150
|
fX = (minPosX + maxPosX) / 2;
|
|
9972
10151
|
fY = (minPosY + maxPosY) / 2;
|
|
10152
|
+
fZ = (minPosZ + maxPosZ) / 2;
|
|
9973
10153
|
} else if (fromLast) {
|
|
9974
10154
|
fX = pxArr[total - 1];
|
|
9975
10155
|
fY = pyArr[total - 1];
|
|
10156
|
+
fZ = pzArr[total - 1];
|
|
9976
10157
|
} else if (isNum(from)) {
|
|
9977
10158
|
fX = pxArr[from];
|
|
9978
10159
|
fY = pyArr[from];
|
|
10160
|
+
fZ = pzArr[from];
|
|
9979
10161
|
}
|
|
9980
10162
|
for (let index = 0; index < total; index++) {
|
|
9981
10163
|
const distanceX = fX - pxArr[index];
|
|
9982
10164
|
const distanceY = fY - pyArr[index];
|
|
9983
|
-
|
|
10165
|
+
const distanceZ = fZ - pzArr[index];
|
|
10166
|
+
let value = sqrt(distanceX * distanceX + distanceY * distanceY + (has3D ? distanceZ * distanceZ : 0));
|
|
9984
10167
|
if (axis === 'x') value = -distanceX;
|
|
9985
10168
|
if (axis === 'y') value = -distanceY;
|
|
10169
|
+
if (axis === 'z') value = -distanceZ;
|
|
9986
10170
|
values.push(value);
|
|
9987
10171
|
}
|
|
9988
10172
|
let minDist = Infinity;
|
|
9989
|
-
for (let index = 0
|
|
10173
|
+
for (let index = 0; index < total; index++) {
|
|
9990
10174
|
const absVal = abs(values[index]);
|
|
9991
10175
|
if (absVal > 0 && absVal < minDist) minDist = absVal;
|
|
9992
10176
|
}
|
|
9993
10177
|
if (minDist > 0 && minDist < Infinity) {
|
|
9994
|
-
for (let index = 0
|
|
10178
|
+
for (let index = 0; index < total; index++) {
|
|
9995
10179
|
values[index] = values[index] / minDist;
|
|
9996
10180
|
}
|
|
9997
10181
|
}
|
|
@@ -10005,32 +10189,51 @@
|
|
|
10005
10189
|
if (!grid) {
|
|
10006
10190
|
values.push(abs(fromIndex - index));
|
|
10007
10191
|
} else {
|
|
10008
|
-
|
|
10192
|
+
const dims = grid.length;
|
|
10193
|
+
const wh = grid[0] * grid[1];
|
|
10194
|
+
let fromX, fromY, fromZ;
|
|
10009
10195
|
if (fromArr) {
|
|
10010
10196
|
fromX = from[0] * (grid[0] - 1);
|
|
10011
10197
|
fromY = from[1] * (grid[1] - 1);
|
|
10198
|
+
fromZ = dims === 3 ? (from.length >= 3 ? from[2] : 0.5) * (grid[2] - 1) : 0;
|
|
10012
10199
|
} else if (fromCenter) {
|
|
10013
10200
|
fromX = (grid[0] - 1) / 2;
|
|
10014
10201
|
fromY = (grid[1] - 1) / 2;
|
|
10202
|
+
fromZ = dims === 3 ? (grid[2] - 1) / 2 : 0;
|
|
10015
10203
|
} else {
|
|
10016
10204
|
fromX = fromIndex % grid[0];
|
|
10017
|
-
fromY = floor(fromIndex / grid[0]);
|
|
10205
|
+
fromY = floor(fromIndex / grid[0]) % grid[1];
|
|
10206
|
+
fromZ = dims === 3 ? floor(fromIndex / wh) : 0;
|
|
10018
10207
|
}
|
|
10019
10208
|
const toX = index % grid[0];
|
|
10020
|
-
const toY = floor(index / grid[0]);
|
|
10209
|
+
const toY = floor(index / grid[0]) % grid[1];
|
|
10210
|
+
const toZ = dims === 3 ? floor(index / wh) : 0;
|
|
10021
10211
|
const distanceX = fromX - toX;
|
|
10022
10212
|
const distanceY = fromY - toY;
|
|
10023
|
-
|
|
10213
|
+
const distanceZ = fromZ - toZ;
|
|
10214
|
+
let value = sqrt(distanceX * distanceX + distanceY * distanceY + (dims === 3 ? distanceZ * distanceZ : 0));
|
|
10024
10215
|
if (axis === 'x') value = -distanceX;
|
|
10025
10216
|
if (axis === 'y') value = -distanceY;
|
|
10217
|
+
if (axis === 'z') value = -distanceZ;
|
|
10026
10218
|
values.push(value);
|
|
10027
10219
|
}
|
|
10028
10220
|
}
|
|
10029
10221
|
}
|
|
10030
|
-
maxValue =
|
|
10031
|
-
|
|
10032
|
-
if (
|
|
10033
|
-
|
|
10222
|
+
maxValue = values[0];
|
|
10223
|
+
for (let k = 1; k < total; k++) if (values[k] > maxValue) maxValue = values[k];
|
|
10224
|
+
if (staggerEase || reversed) {
|
|
10225
|
+
for (let k = 0; k < total; k++) {
|
|
10226
|
+
let v = values[k];
|
|
10227
|
+
if (staggerEase) v = staggerEase(v / maxValue) * maxValue;
|
|
10228
|
+
if (reversed) v = axis ? -v : abs(maxValue - v);
|
|
10229
|
+
values[k] = v;
|
|
10230
|
+
}
|
|
10231
|
+
}
|
|
10232
|
+
if (hasJitter) {
|
|
10233
|
+
jitterSamples = new Array(total);
|
|
10234
|
+
for (let k = 0; k < total; k++) jitterSamples[k] = rng(-1, 1, 4);
|
|
10235
|
+
}
|
|
10236
|
+
if (fromRandom) values = shuffle(values, rng);
|
|
10034
10237
|
}
|
|
10035
10238
|
const spacing = isRange ? (val2 - val1) / maxValue : val1;
|
|
10036
10239
|
if (isUnd(cachedOffset)) {
|
|
@@ -10038,6 +10241,11 @@
|
|
|
10038
10241
|
}
|
|
10039
10242
|
/** @type {String|Number} */
|
|
10040
10243
|
let output = cachedOffset + ((spacing * round$1(values[staggerIndex], 2)) || 0);
|
|
10244
|
+
if (hasJitter) {
|
|
10245
|
+
const progress = maxValue ? values[staggerIndex] / maxValue : 0;
|
|
10246
|
+
const mag = jitterStart + (jitterEnd - jitterStart) * progress;
|
|
10247
|
+
output = /** @type {Number} */(output) + jitterSamples[staggerIndex] * mag;
|
|
10248
|
+
}
|
|
10041
10249
|
if (params.modifier) output = params.modifier(/** @type {Number} */(output));
|
|
10042
10250
|
if (unitMatch) output = `${output}${unitMatch[2]}`;
|
|
10043
10251
|
return output;
|
|
@@ -10407,6 +10615,7 @@
|
|
|
10407
10615
|
*/
|
|
10408
10616
|
const generateTemplate = (type, params = {}) => {
|
|
10409
10617
|
let template = ``;
|
|
10618
|
+
if (!params) params = {};
|
|
10410
10619
|
const classString = isStr(params.class) ? ` class="${params.class}"` : '';
|
|
10411
10620
|
const cloneType = setValue(params.clone, false);
|
|
10412
10621
|
const wrapType = setValue(params.wrap, false);
|
|
@@ -10788,6 +10997,16 @@
|
|
|
10788
10997
|
|
|
10789
10998
|
|
|
10790
10999
|
|
|
11000
|
+
/**
|
|
11001
|
+
* @typedef {Object} ScrambleTextTween
|
|
11002
|
+
* @property {Number} from
|
|
11003
|
+
* @property {Number} to
|
|
11004
|
+
* @property {Number} duration
|
|
11005
|
+
* @property {Number} delay
|
|
11006
|
+
* @property {String} ease
|
|
11007
|
+
* @property {(v: Number) => String} modifier
|
|
11008
|
+
*/
|
|
11009
|
+
|
|
10791
11010
|
/**
|
|
10792
11011
|
* '-' 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
11012
|
* @param {String} str
|
|
@@ -10825,7 +11044,7 @@
|
|
|
10825
11044
|
* progressively revealing the original text.
|
|
10826
11045
|
*
|
|
10827
11046
|
* @param {ScrambleTextParams} [params]
|
|
10828
|
-
* @return {FunctionValue}
|
|
11047
|
+
* @return {FunctionValue<ScrambleTextTween>}
|
|
10829
11048
|
*/
|
|
10830
11049
|
const scrambleText = (params = {}) => {
|
|
10831
11050
|
if (!params) params = {};
|