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 - core - ESM
|
|
3
|
-
* @version v4.
|
|
3
|
+
* @version v4.5.0
|
|
4
4
|
* @license MIT
|
|
5
5
|
* @copyright 2026 - Julian Garnier
|
|
6
6
|
*/
|
|
@@ -9,7 +9,7 @@ import { globals } from './globals.js';
|
|
|
9
9
|
import { minValue, tickModes, valueTypes, compositionTypes, tweenTypes, transformsSymbol } from './consts.js';
|
|
10
10
|
import { forEachChildren, round, now, clamp, lerp } from './helpers.js';
|
|
11
11
|
import { buildTransformString } from './transforms.js';
|
|
12
|
-
import {
|
|
12
|
+
import { composeComplexValue } from './values.js';
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* @import {
|
|
@@ -74,12 +74,14 @@ const render = (tickable, time, muteCallbacks, internalRender, tickMode) => {
|
|
|
74
74
|
// Execute the "expensive" iterations calculations only when necessary
|
|
75
75
|
if (iterationCount > 1) {
|
|
76
76
|
// bitwise NOT operator seems to be generally faster than Math.floor() across browsers
|
|
77
|
-
const
|
|
77
|
+
const period = iterationDuration + (isCurrentTimeEqualOrAboveDuration ? 0 : _loopDelay);
|
|
78
|
+
const currentIteration = ~~(tickableCurrentTime / period);
|
|
78
79
|
tickable._currentIteration = clamp(currentIteration, 0, iterationCount);
|
|
79
80
|
// Prevent the iteration count to go above the max iterations when reaching the end of the animation
|
|
80
81
|
if (isCurrentTimeEqualOrAboveDuration) tickable._currentIteration--;
|
|
81
82
|
isOdd = tickable._currentIteration % 2;
|
|
82
|
-
|
|
83
|
+
// 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.
|
|
84
|
+
iterationElapsedTime = tickableCurrentTime - currentIteration * period || 0;
|
|
83
85
|
}
|
|
84
86
|
|
|
85
87
|
// Checks if exactly one of _reversed and (_alternate && isOdd) is true
|
|
@@ -111,12 +113,14 @@ const render = (tickable, time, muteCallbacks, internalRender, tickMode) => {
|
|
|
111
113
|
if (
|
|
112
114
|
forcedTick ||
|
|
113
115
|
tickMode === tickModes.AUTO && (
|
|
114
|
-
|
|
116
|
+
// Timeline children render from their offset instead of their delay so the gap left by a truncated sibling is covered on seek.
|
|
117
|
+
time >= (parent && tickableDelay > 0 ? 0 : tickableDelay) && time <= tickableEndTime || // Normal render
|
|
115
118
|
time <= tickableDelay && tickablePrevTime > tickableDelay || // Playhead is before the animation start time so make sure the animation is at its initial state
|
|
116
119
|
time >= tickableEndTime && tickablePrevTime !== duration // Playhead is after the animation end time so make sure the animation is at its end state
|
|
117
120
|
) ||
|
|
118
121
|
iterationTime >= tickableEndTime && tickablePrevTime !== duration ||
|
|
119
|
-
iterationTime
|
|
122
|
+
// 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.
|
|
123
|
+
iterationTime <= tickableDelay && tickablePrevTime > 0 && !isCurrentTimeEqualOrAboveDuration ||
|
|
120
124
|
time <= tickablePrevTime && tickablePrevTime === duration && completed || // Force a render if a seek occurs on an completed animation
|
|
121
125
|
isCurrentTimeEqualOrAboveDuration && !completed && isSetter // This prevents 0 duration tickables to be skipped
|
|
122
126
|
) {
|
|
@@ -132,7 +136,8 @@ const render = (tickable, time, muteCallbacks, internalRender, tickMode) => {
|
|
|
132
136
|
|
|
133
137
|
// Time has jumped more than globals.tickThreshold so consider this tick manual
|
|
134
138
|
const forcedRender = forcedTick || (isRunningBackwards ? deltaTime * -1 : deltaTime) >= globals.tickThreshold;
|
|
135
|
-
|
|
139
|
+
// Round to match the precision of tween._absoluteStartTime so equal-time boundary checks compare cleanly without floating point drift from the unrounded _offset.
|
|
140
|
+
const absoluteTime = round(tickable._offset + (parent ? parent._offset : 0) + tickableDelay + iterationTime, 12);
|
|
136
141
|
|
|
137
142
|
// Only Animation can have tweens, Timer returns undefined
|
|
138
143
|
let tween = /** @type {Tween} */(/** @type {JSAnimation} */(tickable)._head);
|
|
@@ -151,15 +156,38 @@ const render = (tickable, time, muteCallbacks, internalRender, tickMode) => {
|
|
|
151
156
|
const tweenNextRep = tween._nextRep;
|
|
152
157
|
const tweenPrevRep = tween._prevRep;
|
|
153
158
|
const tweenHasComposition = tweenComposition !== compositionTypes.none;
|
|
159
|
+
// The previous sibling stops writing at its truncated end, so this tween takes over the hold from that point.
|
|
160
|
+
const tweenPrevRepEndTime = tweenPrevRep ? tweenPrevRep._absoluteStartTime + tweenPrevRep._changeDuration : 0;
|
|
161
|
+
const tweenPrevRepIsCrossParent = tweenPrevRep && tweenPrevRep.parent !== tween.parent;
|
|
162
|
+
// Same parent keyframes take over at their own start, end plus delay equals the next start by construction.
|
|
163
|
+
// Cross parent siblings take over at their update start.
|
|
164
|
+
// Negative delay siblings take over at their own start instead.
|
|
165
|
+
const tweenNextRepTakeover = !tweenNextRep || tweenNextRep._isOverridden ? tweenAbsEndTime :
|
|
166
|
+
tweenNextRep.parent === tween.parent ? tweenAbsEndTime + tweenNextRep._delay :
|
|
167
|
+
tweenNextRep._absoluteStartTime < tweenNextRep._absoluteUpdateStartTime ? tweenNextRep._absoluteStartTime : tweenNextRep._absoluteUpdateStartTime;
|
|
154
168
|
|
|
155
169
|
if ((forcedRender || (
|
|
156
|
-
|
|
157
|
-
(tweenCurrentTime !==
|
|
158
|
-
|
|
170
|
+
// 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.
|
|
171
|
+
(tweenCurrentTime !== tweenChangeDuration || absoluteTime <= tweenNextRepTakeover ||
|
|
172
|
+
(tweenPrevRep && !tweenPrevRepIsCrossParent && (!tweenNextRep || tweenNextRep.parent !== tween.parent))) &&
|
|
173
|
+
// A cross parent tween re-renders its from value from the previous sibling truncated end so the handoff gap holds.
|
|
174
|
+
// 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.
|
|
175
|
+
(tweenCurrentTime !== 0 || absoluteTime >= tween._absoluteStartTime ||
|
|
176
|
+
(tweenPrevRepIsCrossParent && !tween._hasFromValue && !tweenPrevRep._isOverridden && absoluteTime >= tweenPrevRepEndTime) ||
|
|
177
|
+
(tweenNextRep && !tweenNextRep._isOverridden && tweenNextRep.parent === tween.parent && tweenNextRep._currentTime !== 0 && iterationTime < tweenNextRep._startTime))
|
|
178
|
+
)) &&
|
|
179
|
+
// 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.
|
|
180
|
+
(!tweenPrevRep || tweenPrevRepIsCrossParent || iterationTime >= tween._startTime) &&
|
|
181
|
+
(!tweenHasComposition || (
|
|
159
182
|
!tween._isOverridden &&
|
|
160
183
|
(!tween._isOverlapped || absoluteTime <= tweenAbsEndTime) &&
|
|
161
|
-
|
|
162
|
-
(!
|
|
184
|
+
// The next sibling owns the value past its takeover point, so yielding there keeps writes single owner in both directions.
|
|
185
|
+
(!tweenNextRep || tweenNextRep._isOverridden || absoluteTime <= tweenNextRepTakeover) &&
|
|
186
|
+
// The previous sibling owns the value up to its truncated end.
|
|
187
|
+
// Cross parent tweens take over the hold from that point, explicit from values wait for their own start.
|
|
188
|
+
(!tweenPrevRep || (tweenPrevRep._isOverridden || (!tweenPrevRepIsCrossParent ?
|
|
189
|
+
absoluteTime >= tweenPrevRepEndTime + tween._delay :
|
|
190
|
+
absoluteTime >= tween._absoluteStartTime || (!tween._hasFromValue && absoluteTime >= tweenPrevRepEndTime))))
|
|
163
191
|
))
|
|
164
192
|
) {
|
|
165
193
|
|
|
@@ -170,7 +198,7 @@ const render = (tickable, time, muteCallbacks, internalRender, tickMode) => {
|
|
|
170
198
|
const tweenType = tween._tweenType;
|
|
171
199
|
const tweenIsObject = tweenType === tweenTypes.OBJECT;
|
|
172
200
|
const tweenIsNumber = tweenValueType === valueTypes.NUMBER;
|
|
173
|
-
// Only round the in-between frames values if the final value is a string
|
|
201
|
+
// 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.
|
|
174
202
|
const tweenPrecision = (tweenIsNumber && tweenIsObject) || tweenProgress === 0 || tweenProgress === 1 ? -1 : globals.precision;
|
|
175
203
|
|
|
176
204
|
// Recompose tween value
|
|
@@ -186,7 +214,22 @@ const render = (tickable, time, muteCallbacks, internalRender, tickMode) => {
|
|
|
186
214
|
number = /** @type {Number} */(tweenModifier(round(lerp(tween._fromNumber, tween._toNumber, tweenProgress), tweenPrecision)));
|
|
187
215
|
value = `${number}${tween._unit}`;
|
|
188
216
|
} else if (tweenValueType === valueTypes.COLOR) {
|
|
189
|
-
|
|
217
|
+
const ns = tween._numbers;
|
|
218
|
+
const fn = tween._fromNumbers;
|
|
219
|
+
const tn = tween._toNumbers;
|
|
220
|
+
const omt = 1 - tweenProgress;
|
|
221
|
+
const fr = fn[0], fg = fn[1], fb = fn[2];
|
|
222
|
+
const tr = tn[0], tg = tn[1], tb = tn[2];
|
|
223
|
+
// RGB channels lerp in pseudo-linear space (square inputs, sqrt result) to approximate gamma-correct blending.
|
|
224
|
+
// See https://developer.nvidia.com/gpugems/gpugems3/part-iv-image-effects/chapter-24-importance-being-linear.
|
|
225
|
+
ns[0] = /** @type {Number} */(tweenModifier(Math.sqrt(fr * fr * omt + tr * tr * tweenProgress)));
|
|
226
|
+
ns[1] = /** @type {Number} */(tweenModifier(Math.sqrt(fg * fg * omt + tg * tg * tweenProgress)));
|
|
227
|
+
ns[2] = /** @type {Number} */(tweenModifier(Math.sqrt(fb * fb * omt + tb * tb * tweenProgress)));
|
|
228
|
+
ns[3] = /** @type {Number} */(tweenModifier(lerp(fn[3], tn[3], tweenProgress)));
|
|
229
|
+
// The rgba string is built only for the dispatch path or the internalRender composition tick (setters handles the color comp)
|
|
230
|
+
if (!tween._setter || internalRender) {
|
|
231
|
+
value = `rgba(${round(ns[0], 0)},${round(ns[1], 0)},${round(ns[2], 0)},${ns[3]})`;
|
|
232
|
+
}
|
|
190
233
|
} else if (tweenValueType === valueTypes.COMPLEX) {
|
|
191
234
|
value = composeComplexValue(tween, tweenProgress, tweenPrecision);
|
|
192
235
|
}
|
|
@@ -201,7 +244,9 @@ const render = (tickable, time, muteCallbacks, internalRender, tickMode) => {
|
|
|
201
244
|
const tweenProperty = tween.property;
|
|
202
245
|
tweenTarget = tween.target;
|
|
203
246
|
|
|
204
|
-
if (
|
|
247
|
+
if (tween._setter) {
|
|
248
|
+
tween._setter(tweenTarget, number, tween);
|
|
249
|
+
} else if (tweenIsObject) {
|
|
205
250
|
tweenTarget[tweenProperty] = value;
|
|
206
251
|
} else if (tweenType === tweenTypes.ATTRIBUTE) {
|
|
207
252
|
/** @type {DOMTarget} */(tweenTarget).setAttribute(tweenProperty, /** @type {String} */(value));
|
|
@@ -229,6 +274,9 @@ const render = (tickable, time, muteCallbacks, internalRender, tickMode) => {
|
|
|
229
274
|
tween._value = value;
|
|
230
275
|
}
|
|
231
276
|
|
|
277
|
+
} else if (tweenCurrentTime && tweenPrevRep && !tweenPrevRepIsCrossParent && iterationTime < tween._startTime) {
|
|
278
|
+
// Mark the keyframe as reverted when the playhead moves before its start, the previous keyframe owns the from revert and writes it once.
|
|
279
|
+
tween._currentTime = 0;
|
|
232
280
|
}
|
|
233
281
|
|
|
234
282
|
if (tweenTransformsNeedUpdate && tween._renderTransforms) {
|
|
@@ -336,6 +384,8 @@ const tick = (tickable, time, muteCallbacks, internalRender, tickMode) => {
|
|
|
336
384
|
|
|
337
385
|
forEachChildren(tl, (/** @type {JSAnimation} */child) => {
|
|
338
386
|
const childTime = round((tlChildrenTime - child._offset) * child._speed, 12); // Rounding is needed when using seconds
|
|
387
|
+
// 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.
|
|
388
|
+
if (tlIsRunningBackwards && childTime > child._delay + child.duration) return;
|
|
339
389
|
const childTickMode = child._fps < tl._fps ? child.requestTick(tlCildrenTickTime) : tickMode;
|
|
340
390
|
tlChildrenHasRendered += render(child, childTime, muteCallbacks, internalRender, childTickMode);
|
|
341
391
|
if (!child.completed && tlChildrenHaveCompleted) tlChildrenHaveCompleted = false;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Anime.js - core - CJS
|
|
3
|
-
* @version v4.
|
|
3
|
+
* @version v4.5.0
|
|
4
4
|
* @license MIT
|
|
5
5
|
* @copyright 2026 - Julian Garnier
|
|
6
6
|
*/
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
var consts = require('./consts.cjs');
|
|
11
11
|
var helpers = require('./helpers.cjs');
|
|
12
12
|
var transforms = require('./transforms.cjs');
|
|
13
|
+
var values = require('./values.cjs');
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* @import {
|
|
@@ -76,7 +77,20 @@ const revertValues = (renderable, inlineStylesOnly = false) => {
|
|
|
76
77
|
const tweenType = tween._tweenType;
|
|
77
78
|
const originalInlinedValue = tween._inlineValue;
|
|
78
79
|
const tweenHadNoInlineValue = helpers.isNil(originalInlinedValue) || originalInlinedValue === consts.emptyString;
|
|
79
|
-
if (
|
|
80
|
+
if (tween._setter) {
|
|
81
|
+
if (!inlineStylesOnly && !tweenHadNoInlineValue) {
|
|
82
|
+
// 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.
|
|
83
|
+
values.decomposeRawValue(originalInlinedValue, values.decomposedOriginalValue);
|
|
84
|
+
if (values.decomposedOriginalValue.d) {
|
|
85
|
+
const src = values.decomposedOriginalValue.d;
|
|
86
|
+
const dst = tween._numbers;
|
|
87
|
+
for (let i = 0, l = src.length; i < l; i++) dst[i] = src[i];
|
|
88
|
+
} else {
|
|
89
|
+
tween._number = values.decomposedOriginalValue.n;
|
|
90
|
+
}
|
|
91
|
+
tween._setter(tween.target, tween._number, tween);
|
|
92
|
+
}
|
|
93
|
+
} else if (tweenType === consts.tweenTypes.OBJECT) {
|
|
80
94
|
if (!inlineStylesOnly && !tweenHadNoInlineValue) {
|
|
81
95
|
tweenTarget[tweenProperty] = originalInlinedValue;
|
|
82
96
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Anime.js - core - ESM
|
|
3
|
-
* @version v4.
|
|
3
|
+
* @version v4.5.0
|
|
4
4
|
* @license MIT
|
|
5
5
|
* @copyright 2026 - Julian Garnier
|
|
6
6
|
*/
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
import { tweenTypes, isDomSymbol, transformsSymbol, emptyString, shortTransforms } from './consts.js';
|
|
9
9
|
import { forEachChildren, toLowerCase, isNil, isSvg } from './helpers.js';
|
|
10
10
|
import { buildTransformString } from './transforms.js';
|
|
11
|
+
import { decomposeRawValue, decomposedOriginalValue } from './values.js';
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* @import {
|
|
@@ -74,7 +75,20 @@ const revertValues = (renderable, inlineStylesOnly = false) => {
|
|
|
74
75
|
const tweenType = tween._tweenType;
|
|
75
76
|
const originalInlinedValue = tween._inlineValue;
|
|
76
77
|
const tweenHadNoInlineValue = isNil(originalInlinedValue) || originalInlinedValue === emptyString;
|
|
77
|
-
if (
|
|
78
|
+
if (tween._setter) {
|
|
79
|
+
if (!inlineStylesOnly && !tweenHadNoInlineValue) {
|
|
80
|
+
// 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.
|
|
81
|
+
decomposeRawValue(originalInlinedValue, decomposedOriginalValue);
|
|
82
|
+
if (decomposedOriginalValue.d) {
|
|
83
|
+
const src = decomposedOriginalValue.d;
|
|
84
|
+
const dst = tween._numbers;
|
|
85
|
+
for (let i = 0, l = src.length; i < l; i++) dst[i] = src[i];
|
|
86
|
+
} else {
|
|
87
|
+
tween._number = decomposedOriginalValue.n;
|
|
88
|
+
}
|
|
89
|
+
tween._setter(tween.target, tween._number, tween);
|
|
90
|
+
}
|
|
91
|
+
} else if (tweenType === tweenTypes.OBJECT) {
|
|
78
92
|
if (!inlineStylesOnly && !tweenHadNoInlineValue) {
|
|
79
93
|
tweenTarget[tweenProperty] = originalInlinedValue;
|
|
80
94
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Anime.js - core - CJS
|
|
3
|
-
* @version v4.
|
|
3
|
+
* @version v4.5.0
|
|
4
4
|
* @license MIT
|
|
5
5
|
* @copyright 2026 - Julian Garnier
|
|
6
6
|
*/
|
|
@@ -113,18 +113,16 @@ function parseTargets(targets) {
|
|
|
113
113
|
function registerTargets(targets) {
|
|
114
114
|
const parsedTargetsArray = parseTargets(targets);
|
|
115
115
|
const parsedTargetsLength = parsedTargetsArray.length;
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
target[consts.transformsSymbol] = {};
|
|
127
|
-
}
|
|
116
|
+
for (let i = 0; i < parsedTargetsLength; i++) {
|
|
117
|
+
const target = parsedTargetsArray[i];
|
|
118
|
+
if (!target[consts.isRegisteredTargetSymbol]) {
|
|
119
|
+
target[consts.isRegisteredTargetSymbol] = true;
|
|
120
|
+
const isSvgType = helpers.isSvg(target);
|
|
121
|
+
const isDom = /** @type {DOMTarget} */(target).nodeType || isSvgType;
|
|
122
|
+
if (isDom) {
|
|
123
|
+
target[consts.isDomSymbol] = true;
|
|
124
|
+
target[consts.isSvgSymbol] = isSvgType;
|
|
125
|
+
target[consts.transformsSymbol] = {};
|
|
128
126
|
}
|
|
129
127
|
}
|
|
130
128
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Anime.js - core - ESM
|
|
3
|
-
* @version v4.
|
|
3
|
+
* @version v4.5.0
|
|
4
4
|
* @license MIT
|
|
5
5
|
* @copyright 2026 - Julian Garnier
|
|
6
6
|
*/
|
|
@@ -111,18 +111,16 @@ function parseTargets(targets) {
|
|
|
111
111
|
function registerTargets(targets) {
|
|
112
112
|
const parsedTargetsArray = parseTargets(targets);
|
|
113
113
|
const parsedTargetsLength = parsedTargetsArray.length;
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
target[transformsSymbol] = {};
|
|
125
|
-
}
|
|
114
|
+
for (let i = 0; i < parsedTargetsLength; i++) {
|
|
115
|
+
const target = parsedTargetsArray[i];
|
|
116
|
+
if (!target[isRegisteredTargetSymbol]) {
|
|
117
|
+
target[isRegisteredTargetSymbol] = true;
|
|
118
|
+
const isSvgType = isSvg(target);
|
|
119
|
+
const isDom = /** @type {DOMTarget} */(target).nodeType || isSvgType;
|
|
120
|
+
if (isDom) {
|
|
121
|
+
target[isDomSymbol] = true;
|
|
122
|
+
target[isSvgSymbol] = isSvgType;
|
|
123
|
+
target[transformsSymbol] = {};
|
|
126
124
|
}
|
|
127
125
|
}
|
|
128
126
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Anime.js - core - CJS
|
|
3
|
-
* @version v4.
|
|
3
|
+
* @version v4.5.0
|
|
4
4
|
* @license MIT
|
|
5
5
|
* @copyright 2026 - Julian Garnier
|
|
6
6
|
*/
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
var consts = require('./consts.cjs');
|
|
11
11
|
var helpers = require('./helpers.cjs');
|
|
12
12
|
var transforms = require('./transforms.cjs');
|
|
13
|
+
var registry = require('../adapters/registry.cjs');
|
|
13
14
|
var colors = require('./colors.cjs');
|
|
14
15
|
|
|
15
16
|
/**
|
|
@@ -33,6 +34,21 @@ const setValue = (targetValue, defaultValue) => {
|
|
|
33
34
|
return helpers.isUnd(targetValue) ? defaultValue : targetValue;
|
|
34
35
|
};
|
|
35
36
|
|
|
37
|
+
/**
|
|
38
|
+
* 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.
|
|
39
|
+
*
|
|
40
|
+
* @param {String} value
|
|
41
|
+
* @param {Target} target
|
|
42
|
+
* @return {String|Number}
|
|
43
|
+
*/
|
|
44
|
+
const resolveCssVar = (value, target) => {
|
|
45
|
+
const match = value.match(consts.cssVariableMatchRgx);
|
|
46
|
+
const el = target[consts.isDomSymbol] ? target : document.documentElement;
|
|
47
|
+
let computed = getComputedStyle(/** @type {HTMLElement} */(el))?.getPropertyValue(match[1]);
|
|
48
|
+
if ((!computed || computed.trim() === consts.emptyString) && match[2]) computed = match[2].trim();
|
|
49
|
+
return computed || 0;
|
|
50
|
+
};
|
|
51
|
+
|
|
36
52
|
/**
|
|
37
53
|
* @param {TweenPropValue} value
|
|
38
54
|
* @param {Target} target
|
|
@@ -43,30 +59,26 @@ const setValue = (targetValue, defaultValue) => {
|
|
|
43
59
|
* @return {any}
|
|
44
60
|
*/
|
|
45
61
|
const getFunctionValue = (value, target, index, targets, store, prevTween) => {
|
|
46
|
-
let func;
|
|
47
62
|
if (helpers.isFnc(value)) {
|
|
48
|
-
|
|
63
|
+
if (!store) {
|
|
64
|
+
const computed = /** @type {Function} */(value)(target, index, targets, prevTween);
|
|
65
|
+
// Fallback to 0 if the function returns undefined, NaN, null, false or 0
|
|
66
|
+
return !isNaN(+computed) ? +computed : computed || 0;
|
|
67
|
+
}
|
|
68
|
+
const func = () => {
|
|
49
69
|
const computed = /** @type {Function} */(value)(target, index, targets, prevTween);
|
|
50
|
-
// Fallback to 0 if the function returns undefined / NaN / null / false / 0
|
|
51
70
|
return !isNaN(+computed) ? +computed : computed || 0;
|
|
52
71
|
};
|
|
53
|
-
|
|
54
|
-
func
|
|
55
|
-
const match = value.match(consts.cssVariableMatchRgx);
|
|
56
|
-
const cssVarName = match[1];
|
|
57
|
-
const fallbackValue = match[2];
|
|
58
|
-
let computed = getComputedStyle(/** @type {HTMLElement} */(target))?.getPropertyValue(cssVarName);
|
|
59
|
-
// Use fallback if CSS variable is not set or empty
|
|
60
|
-
if ((!computed || computed.trim() === consts.emptyString) && fallbackValue) {
|
|
61
|
-
computed = fallbackValue.trim();
|
|
62
|
-
}
|
|
63
|
-
return computed || 0;
|
|
64
|
-
};
|
|
65
|
-
} else {
|
|
66
|
-
return value;
|
|
72
|
+
store.func = func;
|
|
73
|
+
return func();
|
|
67
74
|
}
|
|
68
|
-
if (
|
|
69
|
-
|
|
75
|
+
if (helpers.isStr(value) && helpers.stringStartsWith(value, consts.cssVarPrefix)) {
|
|
76
|
+
if (!store) return resolveCssVar(/** @type {String} */(value), target);
|
|
77
|
+
const func = () => resolveCssVar(/** @type {String} */(value), target);
|
|
78
|
+
store.func = func;
|
|
79
|
+
return func();
|
|
80
|
+
}
|
|
81
|
+
return value;
|
|
70
82
|
};
|
|
71
83
|
|
|
72
84
|
/**
|
|
@@ -113,6 +125,12 @@ const getCSSValue = (target, propName, animationInlineStyles) => {
|
|
|
113
125
|
*/
|
|
114
126
|
const getOriginalAnimatableValue = (target, propName, tweenType, animationInlineStyles) => {
|
|
115
127
|
const type = !helpers.isUnd(tweenType) ? tweenType : getTweenType(target, propName);
|
|
128
|
+
const adapterProp = registry.resolveAdapterEntry(target, propName);
|
|
129
|
+
if (adapterProp) {
|
|
130
|
+
const value = adapterProp.get(target);
|
|
131
|
+
if (value && animationInlineStyles) animationInlineStyles[propName] = value;
|
|
132
|
+
return value == null ? 0 : value;
|
|
133
|
+
}
|
|
116
134
|
if (type === consts.tweenTypes.OBJECT) {
|
|
117
135
|
const value = target[propName];
|
|
118
136
|
if (value && animationInlineStyles) animationInlineStyles[propName] = value;
|
|
@@ -154,7 +172,7 @@ const createDecomposedValueTargetObject = () => {
|
|
|
154
172
|
};
|
|
155
173
|
|
|
156
174
|
/**
|
|
157
|
-
* @param {String|Number} rawValue
|
|
175
|
+
* @param {String|Number|Object} rawValue
|
|
158
176
|
* @param {TweenDecomposedValue} targetObject
|
|
159
177
|
* @return {TweenDecomposedValue}
|
|
160
178
|
*/
|
|
@@ -172,39 +190,38 @@ const decomposeRawValue = (rawValue, targetObject) => {
|
|
|
172
190
|
// It's a number
|
|
173
191
|
targetObject.n = num;
|
|
174
192
|
return targetObject;
|
|
193
|
+
}
|
|
194
|
+
// let str = /** @type {String} */(rawValue).trim();
|
|
195
|
+
let str = /** @type {String} */(rawValue);
|
|
196
|
+
// Parsing operators (+=, -=, *=) manually is much faster than using regex here
|
|
197
|
+
if (str[1] === '=') {
|
|
198
|
+
targetObject.o = str[0];
|
|
199
|
+
str = str.slice(2);
|
|
200
|
+
}
|
|
201
|
+
// Skip exec regex if the value type is complex or color to avoid long regex backtracking
|
|
202
|
+
const unitMatch = str.includes(' ') ? false : consts.unitsExecRgx.exec(str);
|
|
203
|
+
if (unitMatch) {
|
|
204
|
+
// Has a number and a unit
|
|
205
|
+
targetObject.t = consts.valueTypes.UNIT;
|
|
206
|
+
targetObject.n = +unitMatch[1];
|
|
207
|
+
targetObject.u = unitMatch[2];
|
|
208
|
+
return targetObject;
|
|
209
|
+
} else if (targetObject.o) {
|
|
210
|
+
// Has an operator (+=, -=, *=)
|
|
211
|
+
targetObject.n = +str;
|
|
212
|
+
return targetObject;
|
|
213
|
+
} else if (helpers.isCol(str)) {
|
|
214
|
+
// Color string
|
|
215
|
+
targetObject.t = consts.valueTypes.COLOR;
|
|
216
|
+
targetObject.d = colors.convertColorStringValuesToRgbaArray(str);
|
|
217
|
+
return targetObject;
|
|
175
218
|
} else {
|
|
176
|
-
//
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
}
|
|
183
|
-
// Skip exec regex if the value type is complex or color to avoid long regex backtracking
|
|
184
|
-
const unitMatch = str.includes(' ') ? false : consts.unitsExecRgx.exec(str);
|
|
185
|
-
if (unitMatch) {
|
|
186
|
-
// Has a number and a unit
|
|
187
|
-
targetObject.t = consts.valueTypes.UNIT;
|
|
188
|
-
targetObject.n = +unitMatch[1];
|
|
189
|
-
targetObject.u = unitMatch[2];
|
|
190
|
-
return targetObject;
|
|
191
|
-
} else if (targetObject.o) {
|
|
192
|
-
// Has an operator (+=, -=, *=)
|
|
193
|
-
targetObject.n = +str;
|
|
194
|
-
return targetObject;
|
|
195
|
-
} else if (helpers.isCol(str)) {
|
|
196
|
-
// Is a color
|
|
197
|
-
targetObject.t = consts.valueTypes.COLOR;
|
|
198
|
-
targetObject.d = colors.convertColorStringValuesToRgbaArray(str);
|
|
199
|
-
return targetObject;
|
|
200
|
-
} else {
|
|
201
|
-
// Is a more complex string (generally svg coords, calc() or filters CSS values)
|
|
202
|
-
const matchedNumbers = str.match(consts.digitWithExponentRgx);
|
|
203
|
-
targetObject.t = consts.valueTypes.COMPLEX;
|
|
204
|
-
targetObject.d = matchedNumbers ? matchedNumbers.map(Number) : [];
|
|
205
|
-
targetObject.s = str.split(consts.digitWithExponentRgx) || [];
|
|
206
|
-
return targetObject;
|
|
207
|
-
}
|
|
219
|
+
// Is a more complex string (generally svg coords, calc() or filters CSS values)
|
|
220
|
+
const matchedNumbers = str.match(consts.digitWithExponentRgx);
|
|
221
|
+
targetObject.t = consts.valueTypes.COMPLEX;
|
|
222
|
+
targetObject.d = matchedNumbers ? matchedNumbers.map(Number) : [];
|
|
223
|
+
targetObject.s = str.split(consts.digitWithExponentRgx) || [];
|
|
224
|
+
return targetObject;
|
|
208
225
|
}
|
|
209
226
|
};
|
|
210
227
|
|
|
@@ -225,30 +242,6 @@ const decomposeTweenValue = (tween, targetObject) => {
|
|
|
225
242
|
|
|
226
243
|
const decomposedOriginalValue = createDecomposedValueTargetObject();
|
|
227
244
|
|
|
228
|
-
/**
|
|
229
|
-
* @param {Tween} tween
|
|
230
|
-
* @param {Number} progress
|
|
231
|
-
* @param {Number} precision
|
|
232
|
-
* @return {String}
|
|
233
|
-
*/
|
|
234
|
-
const composeColorValue = (tween, progress, precision) => {
|
|
235
|
-
const mod = tween._modifier;
|
|
236
|
-
const fn = tween._fromNumbers;
|
|
237
|
-
const tn = tween._toNumbers;
|
|
238
|
-
const r = helpers.round(helpers.clamp(/** @type {Number} */(mod(helpers.lerp(fn[0], tn[0], progress))), 0, 255), 0);
|
|
239
|
-
const g = helpers.round(helpers.clamp(/** @type {Number} */(mod(helpers.lerp(fn[1], tn[1], progress))), 0, 255), 0);
|
|
240
|
-
const b = helpers.round(helpers.clamp(/** @type {Number} */(mod(helpers.lerp(fn[2], tn[2], progress))), 0, 255), 0);
|
|
241
|
-
const a = helpers.clamp(/** @type {Number} */(mod(helpers.round(helpers.lerp(fn[3], tn[3], progress), precision))), 0, 1);
|
|
242
|
-
if (tween._composition !== consts.compositionTypes.none) {
|
|
243
|
-
const ns = tween._numbers;
|
|
244
|
-
ns[0] = r;
|
|
245
|
-
ns[1] = g;
|
|
246
|
-
ns[2] = b;
|
|
247
|
-
ns[3] = a;
|
|
248
|
-
}
|
|
249
|
-
return `rgba(${r},${g},${b},${a})`;
|
|
250
|
-
};
|
|
251
|
-
|
|
252
245
|
/**
|
|
253
246
|
* @param {Tween} tween
|
|
254
247
|
* @param {Number} progress
|
|
@@ -260,20 +253,18 @@ const composeComplexValue = (tween, progress, precision) => {
|
|
|
260
253
|
const fn = tween._fromNumbers;
|
|
261
254
|
const tn = tween._toNumbers;
|
|
262
255
|
const ts = tween._strings;
|
|
263
|
-
const hasComposition = tween._composition !== consts.compositionTypes.none;
|
|
264
256
|
let v = ts[0];
|
|
265
257
|
for (let j = 0, l = tn.length; j < l; j++) {
|
|
266
258
|
const n = /** @type {Number} */(mod(helpers.round(helpers.lerp(fn[j], tn[j], progress), precision)));
|
|
267
259
|
const s = ts[j + 1];
|
|
268
260
|
v += `${s ? n + s : n}`;
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
261
|
+
// 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.
|
|
262
|
+
// Potential optimization, skip the write when nothing reads it: if (hasComposition || tween._setter) tween._numbers[j] = n;
|
|
263
|
+
tween._numbers[j] = n;
|
|
272
264
|
}
|
|
273
265
|
return v;
|
|
274
266
|
};
|
|
275
267
|
|
|
276
|
-
exports.composeColorValue = composeColorValue;
|
|
277
268
|
exports.composeComplexValue = composeComplexValue;
|
|
278
269
|
exports.createDecomposedValueTargetObject = createDecomposedValueTargetObject;
|
|
279
270
|
exports.decomposeRawValue = decomposeRawValue;
|
|
@@ -4,10 +4,9 @@ export function getTweenType(target: Target, prop: string): tweenTypes;
|
|
|
4
4
|
export function getOriginalAnimatableValue(target: Target, propName: string, tweenType?: tweenTypes, animationInlineStyles?: any | void): string | number;
|
|
5
5
|
export function getRelativeValue(x: number, y: number, operator: string): number;
|
|
6
6
|
export function createDecomposedValueTargetObject(): TweenDecomposedValue;
|
|
7
|
-
export function decomposeRawValue(rawValue: string | number, targetObject: TweenDecomposedValue): TweenDecomposedValue;
|
|
7
|
+
export function decomposeRawValue(rawValue: string | number | any, targetObject: TweenDecomposedValue): TweenDecomposedValue;
|
|
8
8
|
export function decomposeTweenValue(tween: Tween, targetObject: TweenDecomposedValue): TweenDecomposedValue;
|
|
9
9
|
export const decomposedOriginalValue: TweenDecomposedValue;
|
|
10
|
-
export function composeColorValue(tween: Tween, progress: number, precision: number): string;
|
|
11
10
|
export function composeComplexValue(tween: Tween, progress: number, precision: number): string;
|
|
12
11
|
import type { TweenPropValue } from '../types/index.js';
|
|
13
12
|
import type { Target } from '../types/index.js';
|