@hanzogui/animations-reanimated 7.3.1 → 8.0.1
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/dist/cjs/createAnimations.cjs +462 -153
- package/dist/cjs/createAnimations.native.js +620 -220
- package/dist/cjs/createAnimations.native.js.map +1 -1
- package/dist/esm/createAnimations.mjs +462 -153
- package/dist/esm/createAnimations.mjs.map +1 -1
- package/dist/esm/createAnimations.native.js +620 -220
- package/dist/esm/createAnimations.native.js.map +1 -1
- package/package.json +12 -17
- package/src/createAnimations.tsx +803 -226
- package/types/createAnimations.d.ts.map +2 -2
- package/LICENSE +0 -42
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { getEffectiveAnimation, normalizeTransition } from "@hanzogui/animation-helpers";
|
|
2
2
|
import { getSplitStyles, hooks, isWeb, Text, useComposedRefs, useEvent, useIsomorphicLayoutEffect, useThemeWithState, View } from "@hanzogui/core";
|
|
3
3
|
import { ResetPresence, usePresence } from "@hanzogui/use-presence";
|
|
4
|
+
import normalizeColor from "@react-native/normalize-colors";
|
|
4
5
|
import React, { forwardRef, useMemo, useRef } from "react";
|
|
5
6
|
import Animated_, { cancelAnimation, runOnJS, runOnUI, useAnimatedReaction, useAnimatedStyle, useDerivedValue, useSharedValue, withDelay, withSpring, withTiming } from "react-native-reanimated";
|
|
6
7
|
import { jsx } from "react/jsx-runtime";
|
|
@@ -12,6 +13,16 @@ const getDefaultExport = module => {
|
|
|
12
13
|
return mod;
|
|
13
14
|
};
|
|
14
15
|
const Animated = getDefaultExport(Animated_);
|
|
16
|
+
const silenceAnimatedComponentDevCheck = style => {
|
|
17
|
+
if (process.env.NODE_ENV !== "development" || isWeb || !style || typeof style !== "object") {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
Object.defineProperty(style, "_requiresAnimatedComponent", {
|
|
21
|
+
configurable: true,
|
|
22
|
+
enumerable: false,
|
|
23
|
+
value: true
|
|
24
|
+
});
|
|
25
|
+
};
|
|
15
26
|
const resolveDynamicValue = (value, isDark) => {
|
|
16
27
|
if (value !== null && typeof value === "object" && "dynamic" in value && typeof value.dynamic === "object") {
|
|
17
28
|
const dynamic = value.dynamic;
|
|
@@ -19,21 +30,248 @@ const resolveDynamicValue = (value, isDark) => {
|
|
|
19
30
|
}
|
|
20
31
|
return value;
|
|
21
32
|
};
|
|
22
|
-
const
|
|
33
|
+
const updateMapperState = isWeb ? (state, emitted) => {
|
|
34
|
+
state.value.emitted = emitted;
|
|
35
|
+
} : (state, emitted) => {
|
|
36
|
+
"worklet";
|
|
37
|
+
|
|
38
|
+
if (!globalThis._WORKLET) return;
|
|
39
|
+
state.modify(current => {
|
|
40
|
+
current.emitted = emitted;
|
|
41
|
+
return current;
|
|
42
|
+
}, false);
|
|
43
|
+
};
|
|
44
|
+
const cloneAnimationValue = value => {
|
|
45
|
+
if (Array.isArray(value)) {
|
|
46
|
+
return value.map(cloneAnimationValue);
|
|
47
|
+
}
|
|
48
|
+
if (value && typeof value === "object") {
|
|
49
|
+
const next = {};
|
|
50
|
+
for (const key in value) {
|
|
51
|
+
next[key] = cloneAnimationValue(value[key]);
|
|
52
|
+
}
|
|
53
|
+
return next;
|
|
54
|
+
}
|
|
55
|
+
return value;
|
|
56
|
+
};
|
|
57
|
+
const cloneStyleRecord = style => {
|
|
58
|
+
const next = {};
|
|
59
|
+
for (const key in style) {
|
|
60
|
+
next[key] = cloneAnimationValue(style[key]);
|
|
61
|
+
}
|
|
62
|
+
return next;
|
|
63
|
+
};
|
|
64
|
+
const cloneTransitionConfig = config => {
|
|
65
|
+
return cloneAnimationValue(config);
|
|
66
|
+
};
|
|
67
|
+
const getAnimatedTransforms = value => {
|
|
68
|
+
if (!Array.isArray(value)) return [];
|
|
69
|
+
return value.filter(item => item !== null && typeof item === "object" && !Array.isArray(item));
|
|
70
|
+
};
|
|
71
|
+
const getRemovedAnimatedKeys = (current, previous) => {
|
|
72
|
+
const removedKeys = {};
|
|
73
|
+
for (const key of previous) {
|
|
74
|
+
if (!current.has(key)) removedKeys[key] = true;
|
|
75
|
+
}
|
|
76
|
+
return removedKeys;
|
|
77
|
+
};
|
|
78
|
+
const getImplicitDefault = (key, targetValue) => {
|
|
79
|
+
"worklet";
|
|
80
|
+
|
|
81
|
+
const value = key === "opacity" || key === "scale" || key === "scaleX" || key === "scaleY" ? 1 : 0;
|
|
82
|
+
if (typeof targetValue !== "string") return value;
|
|
83
|
+
let suffixIndex = 0;
|
|
84
|
+
while (suffixIndex < targetValue.length) {
|
|
85
|
+
const character = targetValue[suffixIndex];
|
|
86
|
+
const code = character.charCodeAt(0);
|
|
87
|
+
if (code >= 48 && code <= 57 || character === "." || character === "-" || character === "+") {
|
|
88
|
+
suffixIndex++;
|
|
89
|
+
} else {
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return suffixIndex > 0 ? `${value}${targetValue.slice(suffixIndex)}` : value;
|
|
94
|
+
};
|
|
95
|
+
const COLOR_STYLE_KEYS = {
|
|
96
|
+
backgroundColor: true,
|
|
97
|
+
borderColor: true,
|
|
98
|
+
borderLeftColor: true,
|
|
99
|
+
borderRightColor: true,
|
|
100
|
+
borderTopColor: true,
|
|
101
|
+
borderBottomColor: true,
|
|
102
|
+
color: true
|
|
103
|
+
};
|
|
104
|
+
const toReanimatedColor = value => {
|
|
105
|
+
"worklet";
|
|
106
|
+
|
|
107
|
+
if (typeof value === "number") {
|
|
108
|
+
const color = value >>> 0;
|
|
109
|
+
const alpha = (color >>> 24 & 255) / 255;
|
|
110
|
+
const red = color >>> 16 & 255;
|
|
111
|
+
const green = color >>> 8 & 255;
|
|
112
|
+
const blue = color & 255;
|
|
113
|
+
return `rgba(${red}, ${green}, ${blue}, ${alpha})`;
|
|
114
|
+
}
|
|
115
|
+
if (typeof value !== "string") return value;
|
|
116
|
+
const trimmed = value.trim();
|
|
117
|
+
if (trimmed === "transparent") return "rgba(0, 0, 0, 0)";
|
|
118
|
+
return trimmed;
|
|
119
|
+
};
|
|
120
|
+
const isReanimatedColorHistory = value => {
|
|
121
|
+
"worklet";
|
|
122
|
+
|
|
123
|
+
const normalized = toReanimatedColor(value);
|
|
124
|
+
return typeof normalized === "string" && normalized.startsWith("rgba(");
|
|
125
|
+
};
|
|
126
|
+
const normalizeAnimationColor = value => {
|
|
127
|
+
if (typeof value === "number") {
|
|
128
|
+
return toReanimatedColor(value);
|
|
129
|
+
}
|
|
130
|
+
if (typeof value !== "string") return;
|
|
131
|
+
const color = normalizeColor(value);
|
|
132
|
+
if (color == null) return;
|
|
133
|
+
const red = Math.round((color & 4278190080) >>> 24);
|
|
134
|
+
const green = Math.round((color & 16711680) >>> 16);
|
|
135
|
+
const blue = Math.round((color & 65280) >>> 8);
|
|
136
|
+
const alpha = (color & 255) / 255;
|
|
137
|
+
return `rgba(${red}, ${green}, ${blue}, ${alpha})`;
|
|
138
|
+
};
|
|
139
|
+
const buildSnapshot = (animated, statics, transforms, previousKeys, lastPainted) => {
|
|
140
|
+
const snapshotAnimated = {};
|
|
141
|
+
const snapshotStatics = cloneStyleRecord(statics);
|
|
142
|
+
for (const key in snapshotStatics) {
|
|
143
|
+
if (!COLOR_STYLE_KEYS[key]) continue;
|
|
144
|
+
const normalized = normalizeAnimationColor(snapshotStatics[key]);
|
|
145
|
+
if (normalized !== void 0) snapshotStatics[key] = normalized;
|
|
146
|
+
}
|
|
147
|
+
for (const key in animated) {
|
|
148
|
+
if (key === "transform") continue;
|
|
149
|
+
const value = animated[key];
|
|
150
|
+
if (COLOR_STYLE_KEYS[key]) {
|
|
151
|
+
const normalized = normalizeAnimationColor(value);
|
|
152
|
+
if (normalized === void 0) {
|
|
153
|
+
snapshotStatics[key] = cloneAnimationValue(value);
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
snapshotAnimated[key] = normalized;
|
|
157
|
+
} else {
|
|
158
|
+
snapshotAnimated[key] = cloneAnimationValue(value);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
const snapshotTransforms = transforms.map(cloneStyleRecord);
|
|
162
|
+
const keys = new Set(Object.keys(snapshotAnimated));
|
|
163
|
+
for (const transform of snapshotTransforms) {
|
|
164
|
+
const key = Object.keys(transform)[0];
|
|
165
|
+
const value = key ? transform[key] : void 0;
|
|
166
|
+
if (key && (typeof value === "number" || typeof value === "string")) {
|
|
167
|
+
keys.add(`transform:${key}`);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
const seeds = {};
|
|
171
|
+
for (const key of keys) {
|
|
172
|
+
let value = lastPainted[key];
|
|
173
|
+
if (typeof value !== "number" && typeof value !== "string") continue;
|
|
174
|
+
if (value === "auto" || typeof value === "string" && value.startsWith("calc")) {
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
if (COLOR_STYLE_KEYS[key]) value = normalizeAnimationColor(value);
|
|
178
|
+
if (value !== void 0) seeds[key] = value;
|
|
179
|
+
}
|
|
180
|
+
const gatedKeys = {};
|
|
181
|
+
for (const key of keys) gatedKeys[key] = true;
|
|
182
|
+
const removedKeys = getRemovedAnimatedKeys(keys, previousKeys);
|
|
183
|
+
const painted = {
|
|
184
|
+
...snapshotStatics,
|
|
185
|
+
...snapshotAnimated
|
|
186
|
+
};
|
|
187
|
+
const staticTransforms = getAnimatedTransforms(snapshotStatics.transform);
|
|
188
|
+
delete painted.transform;
|
|
189
|
+
for (const transform of staticTransforms) {
|
|
190
|
+
const key = Object.keys(transform)[0];
|
|
191
|
+
if (key) painted[`transform:${key}`] = transform[key];
|
|
192
|
+
}
|
|
193
|
+
for (const transform of snapshotTransforms) {
|
|
194
|
+
const key = Object.keys(transform)[0];
|
|
195
|
+
if (key) painted[`transform:${key}`] = transform[key];
|
|
196
|
+
}
|
|
197
|
+
return {
|
|
198
|
+
value: {
|
|
199
|
+
animated: snapshotAnimated,
|
|
200
|
+
statics: snapshotStatics,
|
|
201
|
+
transforms: snapshotTransforms,
|
|
202
|
+
gatedKeys,
|
|
203
|
+
seeds,
|
|
204
|
+
removedKeys,
|
|
205
|
+
removeTransform: Object.keys(removedKeys).some(key => key.startsWith("transform:")),
|
|
206
|
+
clearValue: isWeb ? "" : null
|
|
207
|
+
},
|
|
208
|
+
painted,
|
|
209
|
+
keys
|
|
210
|
+
};
|
|
211
|
+
};
|
|
212
|
+
const getGatedKeys = snapshot => Object.keys(snapshot.gatedKeys);
|
|
213
|
+
const createReanimatedConfig = config => {
|
|
214
|
+
"worklet";
|
|
215
|
+
|
|
216
|
+
const next = {};
|
|
217
|
+
const source = config;
|
|
218
|
+
for (const key in source) {
|
|
219
|
+
if (key === "type" || key === "delay") continue;
|
|
220
|
+
const value = source[key];
|
|
221
|
+
if (value !== void 0) {
|
|
222
|
+
next[key] = value;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return next;
|
|
226
|
+
};
|
|
227
|
+
const applyAnimation = (targetValue, config, callback, seedValue, validateStartAsColor = false) => {
|
|
23
228
|
"worklet";
|
|
24
229
|
|
|
25
230
|
const delay = config.delay;
|
|
231
|
+
const reanimatedConfig = createReanimatedConfig(config);
|
|
26
232
|
let animatedValue;
|
|
27
233
|
if (config.type === "timing") {
|
|
28
|
-
animatedValue = withTiming(targetValue,
|
|
234
|
+
animatedValue = withTiming(targetValue, reanimatedConfig, callback);
|
|
29
235
|
} else {
|
|
30
|
-
animatedValue = withSpring(targetValue,
|
|
236
|
+
animatedValue = withSpring(targetValue, reanimatedConfig, callback);
|
|
237
|
+
}
|
|
238
|
+
if (seedValue !== void 0 || validateStartAsColor) {
|
|
239
|
+
const innerOnStart = animatedValue.onStart;
|
|
240
|
+
animatedValue.onStart = (animation, value, timestamp, previousAnimation) => {
|
|
241
|
+
"worklet";
|
|
242
|
+
|
|
243
|
+
const startValue = validateStartAsColor ? isReanimatedColorHistory(value) ? toReanimatedColor(value) : seedValue ?? targetValue : seedValue;
|
|
244
|
+
innerOnStart(animation, startValue, timestamp, previousAnimation);
|
|
245
|
+
};
|
|
31
246
|
}
|
|
32
247
|
if (delay && delay > 0) {
|
|
33
248
|
animatedValue = withDelay(delay, animatedValue);
|
|
34
249
|
}
|
|
35
250
|
return animatedValue;
|
|
36
251
|
};
|
|
252
|
+
const animateSnapshotValue = (key, implicitKey, targetValue, config, previouslyEmitted, seedValue, gated, currentlyExiting, exitCycleId, currentlyCompletingAnimation, didAnimateCycleId, markExitKeyDone, markDidAnimateKeyDone, validateStartAsColor = false) => {
|
|
253
|
+
"worklet";
|
|
254
|
+
|
|
255
|
+
const cycleGated = gated && (currentlyExiting || currentlyCompletingAnimation);
|
|
256
|
+
if (!previouslyEmitted && seedValue === void 0 && !cycleGated) {
|
|
257
|
+
return targetValue;
|
|
258
|
+
}
|
|
259
|
+
let callback;
|
|
260
|
+
if (gated && currentlyExiting) {
|
|
261
|
+
callback = finished => {
|
|
262
|
+
"worklet";
|
|
263
|
+
|
|
264
|
+
runOnJS(markExitKeyDone)(key, exitCycleId, finished ?? false);
|
|
265
|
+
};
|
|
266
|
+
} else if (gated && currentlyCompletingAnimation) {
|
|
267
|
+
callback = finished => {
|
|
268
|
+
"worklet";
|
|
269
|
+
|
|
270
|
+
runOnJS(markDidAnimateKeyDone)(key, didAnimateCycleId, finished ?? false);
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
return applyAnimation(targetValue, config, callback, previouslyEmitted ? void 0 : seedValue ?? getImplicitDefault(implicitKey, targetValue), validateStartAsColor);
|
|
274
|
+
};
|
|
37
275
|
const ANIMATABLE_PROPERTIES = {
|
|
38
276
|
// Transform
|
|
39
277
|
transform: true,
|
|
@@ -108,6 +346,23 @@ const canAnimateProperty = (key, value, animateOnly) => {
|
|
|
108
346
|
if (animateOnly && !animateOnly.includes(key)) return false;
|
|
109
347
|
return true;
|
|
110
348
|
};
|
|
349
|
+
const splitAnimationStyles = (style, isDark, disableAnimation, animateOnly) => {
|
|
350
|
+
const animated = {};
|
|
351
|
+
const statics = {};
|
|
352
|
+
for (const key in style) {
|
|
353
|
+
const value = resolveDynamicValue(style[key], isDark);
|
|
354
|
+
if (value === void 0) continue;
|
|
355
|
+
if (!disableAnimation && canAnimateProperty(key, value, animateOnly)) {
|
|
356
|
+
animated[key] = cloneAnimationValue(value);
|
|
357
|
+
} else {
|
|
358
|
+
statics[key] = cloneAnimationValue(value);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
return {
|
|
362
|
+
animated,
|
|
363
|
+
statics
|
|
364
|
+
};
|
|
365
|
+
};
|
|
111
366
|
function createWebAnimatedComponent(defaultTag) {
|
|
112
367
|
const isText = defaultTag === "span";
|
|
113
368
|
const Component = Animated.createAnimatedComponent(forwardRef((propsIn, ref) => {
|
|
@@ -146,43 +401,43 @@ const AnimatedText = createWebAnimatedComponent("span");
|
|
|
146
401
|
function buildTransitionConfig(transition, animations, animationState, styleKeys) {
|
|
147
402
|
const normalized = normalizeTransition(transition);
|
|
148
403
|
const effectiveKey = getEffectiveAnimation(normalized, animationState);
|
|
149
|
-
let base = effectiveKey ? animations[effectiveKey] ?? {
|
|
404
|
+
let base = cloneTransitionConfig(effectiveKey ? animations[effectiveKey] ?? {
|
|
150
405
|
type: "spring"
|
|
151
406
|
} : {
|
|
152
407
|
type: "spring"
|
|
153
|
-
};
|
|
408
|
+
});
|
|
154
409
|
if (normalized.delay) {
|
|
155
|
-
base = {
|
|
410
|
+
base = cloneTransitionConfig({
|
|
156
411
|
...base,
|
|
157
412
|
delay: normalized.delay
|
|
158
|
-
};
|
|
413
|
+
});
|
|
159
414
|
}
|
|
160
415
|
if (normalized.config) {
|
|
161
|
-
base = {
|
|
416
|
+
base = cloneTransitionConfig({
|
|
162
417
|
...base,
|
|
163
418
|
...normalized.config
|
|
164
|
-
};
|
|
419
|
+
});
|
|
165
420
|
if (base.type !== "timing" && normalized.config.duration !== void 0 && normalized.config.damping === void 0 && normalized.config.stiffness === void 0 && normalized.config.mass === void 0) {
|
|
166
|
-
base = {
|
|
421
|
+
base = cloneTransitionConfig({
|
|
167
422
|
...base,
|
|
168
423
|
type: "timing"
|
|
169
|
-
};
|
|
424
|
+
});
|
|
170
425
|
}
|
|
171
426
|
}
|
|
172
427
|
const propertyConfigs = {};
|
|
173
428
|
for (const key of styleKeys) {
|
|
174
429
|
const propAnimation = normalized.properties[key];
|
|
175
430
|
if (typeof propAnimation === "string") {
|
|
176
|
-
propertyConfigs[key] = animations[propAnimation] ?? base;
|
|
431
|
+
propertyConfigs[key] = cloneTransitionConfig(animations[propAnimation] ?? base);
|
|
177
432
|
} else if (propAnimation && typeof propAnimation === "object") {
|
|
178
433
|
const configType = propAnimation.type;
|
|
179
434
|
const baseForProp = configType ? animations[configType] ?? base : base;
|
|
180
|
-
propertyConfigs[key] = {
|
|
435
|
+
propertyConfigs[key] = cloneTransitionConfig({
|
|
181
436
|
...baseForProp,
|
|
182
437
|
...propAnimation
|
|
183
|
-
};
|
|
438
|
+
});
|
|
184
439
|
} else {
|
|
185
|
-
propertyConfigs[key] = base;
|
|
440
|
+
propertyConfigs[key] = cloneTransitionConfig(base);
|
|
186
441
|
}
|
|
187
442
|
}
|
|
188
443
|
return {
|
|
@@ -204,10 +459,10 @@ function getStyleKeys(style) {
|
|
|
204
459
|
function createAnimations(animationsConfig) {
|
|
205
460
|
const animations = {};
|
|
206
461
|
for (const key in animationsConfig) {
|
|
207
|
-
animations[key] = {
|
|
462
|
+
animations[key] = cloneTransitionConfig({
|
|
208
463
|
type: "spring",
|
|
209
464
|
...animationsConfig[key]
|
|
210
|
-
};
|
|
465
|
+
});
|
|
211
466
|
}
|
|
212
467
|
return {
|
|
213
468
|
needsCustomComponent: true,
|
|
@@ -243,19 +498,22 @@ function createAnimations(animationsConfig) {
|
|
|
243
498
|
sharedValue.value = next;
|
|
244
499
|
onFinish?.();
|
|
245
500
|
} else {
|
|
246
|
-
const cb = onFinish ?
|
|
501
|
+
const cb = onFinish ? finished => {
|
|
247
502
|
"worklet";
|
|
248
503
|
|
|
249
|
-
|
|
504
|
+
if (finished !== false) {
|
|
505
|
+
runOnJS(onFinish)();
|
|
506
|
+
}
|
|
250
507
|
} : void 0;
|
|
508
|
+
const animationConfig = cloneTransitionConfig(config);
|
|
251
509
|
if (isWeb) {
|
|
252
|
-
sharedValue.value =
|
|
510
|
+
sharedValue.value = applyAnimation(next, animationConfig, cb);
|
|
253
511
|
} else {
|
|
254
|
-
runOnUI(() => {
|
|
512
|
+
runOnUI((targetValue, animationConfig2) => {
|
|
255
513
|
"worklet";
|
|
256
514
|
|
|
257
|
-
sharedValue.value =
|
|
258
|
-
})();
|
|
515
|
+
sharedValue.value = applyAnimation(targetValue, animationConfig2, cb);
|
|
516
|
+
})(next, animationConfig);
|
|
259
517
|
}
|
|
260
518
|
}
|
|
261
519
|
},
|
|
@@ -294,20 +552,24 @@ function createAnimations(animationsConfig) {
|
|
|
294
552
|
|
|
295
553
|
return getStyle(instance.value);
|
|
296
554
|
});
|
|
297
|
-
|
|
555
|
+
const animatedStyle = useAnimatedStyle(() => {
|
|
298
556
|
"worklet";
|
|
299
557
|
|
|
300
558
|
return styleVal.value;
|
|
301
559
|
});
|
|
560
|
+
silenceAnimatedComponentDevCheck(animatedStyle);
|
|
561
|
+
return animatedStyle;
|
|
302
562
|
},
|
|
303
563
|
useAnimatedNumbersStyle(vals, getStyle) {
|
|
304
564
|
const instances = vals.map(v => v.getInstance());
|
|
305
|
-
|
|
565
|
+
const animatedStyle = useAnimatedStyle(() => {
|
|
306
566
|
"worklet";
|
|
307
567
|
|
|
308
568
|
const currentValues = instances.map(inst => inst.value);
|
|
309
569
|
return getStyle(...currentValues);
|
|
310
570
|
}, isWeb ? [getStyle, ...instances] : void 0);
|
|
571
|
+
silenceAnimatedComponentDevCheck(animatedStyle);
|
|
572
|
+
return animatedStyle;
|
|
311
573
|
},
|
|
312
574
|
// =========================================================================
|
|
313
575
|
// useAnimations - Main animation hook for components
|
|
@@ -321,7 +583,8 @@ function createAnimations(animationsConfig) {
|
|
|
321
583
|
useStyleEmitter,
|
|
322
584
|
themeName,
|
|
323
585
|
stateRef,
|
|
324
|
-
styleState
|
|
586
|
+
styleState,
|
|
587
|
+
onDidAnimate
|
|
325
588
|
} = animationProps;
|
|
326
589
|
const isHydrating = componentState.unmounted === true;
|
|
327
590
|
const isMounting = componentState.unmounted === "should-enter";
|
|
@@ -339,6 +602,25 @@ function createAnimations(animationsConfig) {
|
|
|
339
602
|
const disableAnimation = isHydrating || !animationKey;
|
|
340
603
|
const isDark = themeName?.startsWith("dark") || false;
|
|
341
604
|
const sendExitComplete = presence?.[1];
|
|
605
|
+
const onDidAnimateRef = useRef(onDidAnimate);
|
|
606
|
+
useIsomorphicLayoutEffect(() => {
|
|
607
|
+
onDidAnimateRef.current = onDidAnimate;
|
|
608
|
+
}, [onDidAnimate]);
|
|
609
|
+
const didAnimateCycleIdRef = useRef(0);
|
|
610
|
+
const pendingDidAnimateKeysRef = useRef(/* @__PURE__ */new Set());
|
|
611
|
+
const didAnimateCompletedRef = useRef(false);
|
|
612
|
+
const isCompletingAnimationRef = useSharedValue(false);
|
|
613
|
+
const didAnimateCycleIdShared = useSharedValue(0);
|
|
614
|
+
const markDidAnimateKeyDone = useEvent((key, cycleId, finished) => {
|
|
615
|
+
if (!finished || cycleId !== didAnimateCycleIdRef.current) return;
|
|
616
|
+
if (didAnimateCompletedRef.current) return;
|
|
617
|
+
pendingDidAnimateKeysRef.current.delete(key);
|
|
618
|
+
if (pendingDidAnimateKeysRef.current.size === 0) {
|
|
619
|
+
didAnimateCompletedRef.current = true;
|
|
620
|
+
isCompletingAnimationRef.value = false;
|
|
621
|
+
onDidAnimateRef.current?.();
|
|
622
|
+
}
|
|
623
|
+
});
|
|
342
624
|
const exitCycleIdRef = useRef(0);
|
|
343
625
|
const pendingExitKeysRef = useRef(/* @__PURE__ */new Set());
|
|
344
626
|
const exitCompletedRef = useRef(false);
|
|
@@ -360,6 +642,9 @@ function createAnimations(animationsConfig) {
|
|
|
360
642
|
exitCycleIdRef.current++;
|
|
361
643
|
exitCompletedRef.current = false;
|
|
362
644
|
pendingExitKeysRef.current.clear();
|
|
645
|
+
didAnimateCycleIdRef.current++;
|
|
646
|
+
pendingDidAnimateKeysRef.current.clear();
|
|
647
|
+
didAnimateCompletedRef.current = true;
|
|
363
648
|
}
|
|
364
649
|
if (justStoppedExiting) {
|
|
365
650
|
exitCycleIdRef.current++;
|
|
@@ -368,44 +653,85 @@ function createAnimations(animationsConfig) {
|
|
|
368
653
|
useIsomorphicLayoutEffect(() => {
|
|
369
654
|
isExitingRef.value = isExiting;
|
|
370
655
|
exitCycleIdShared.value = exitCycleIdRef.current;
|
|
371
|
-
|
|
656
|
+
if (justStartedExiting) {
|
|
657
|
+
isCompletingAnimationRef.value = false;
|
|
658
|
+
didAnimateCycleIdShared.value = didAnimateCycleIdRef.current;
|
|
659
|
+
}
|
|
660
|
+
}, [isExiting, exitCycleIdRef.current, justStartedExiting]);
|
|
372
661
|
React.useEffect(() => {
|
|
373
662
|
wasExitingRef.current = isExiting;
|
|
374
663
|
});
|
|
375
|
-
const
|
|
376
|
-
const
|
|
377
|
-
const
|
|
664
|
+
const committedRenderKeysRef = useRef(/* @__PURE__ */new Set());
|
|
665
|
+
const lastPaintedRef = useRef({});
|
|
666
|
+
const carryRef = useRef({});
|
|
378
667
|
const {
|
|
379
668
|
animatedStyles,
|
|
380
|
-
staticStyles
|
|
669
|
+
staticStyles,
|
|
670
|
+
nextCarry
|
|
381
671
|
} = useMemo(() => {
|
|
382
|
-
const animated = {};
|
|
383
|
-
const staticStyles2 = {};
|
|
384
672
|
const animateOnly = props.animateOnly;
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
}
|
|
393
|
-
if (canAnimateProperty(key, value, animateOnly)) {
|
|
394
|
-
animated[key] = value;
|
|
395
|
-
} else {
|
|
396
|
-
staticStyles2[key] = value;
|
|
397
|
-
}
|
|
673
|
+
const {
|
|
674
|
+
animated,
|
|
675
|
+
statics
|
|
676
|
+
} = splitAnimationStyles(style, isDark, disableAnimation, animateOnly);
|
|
677
|
+
const nextCarry2 = cloneStyleRecord(carryRef.current);
|
|
678
|
+
for (const key in nextCarry2) {
|
|
679
|
+
if (!(key in animated)) delete nextCarry2[key];
|
|
398
680
|
}
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
681
|
+
for (const key in animated) {
|
|
682
|
+
if (!(key in nextCarry2)) {
|
|
683
|
+
nextCarry2[key] = cloneAnimationValue(animated[key]);
|
|
402
684
|
}
|
|
685
|
+
statics[key] = nextCarry2[key];
|
|
403
686
|
}
|
|
404
687
|
return {
|
|
405
688
|
animatedStyles: animated,
|
|
406
|
-
staticStyles:
|
|
689
|
+
staticStyles: statics,
|
|
690
|
+
nextCarry: nextCarry2
|
|
407
691
|
};
|
|
408
|
-
}, [disableAnimation, style, isDark,
|
|
692
|
+
}, [disableAnimation, style, isDark, props.animateOnly]);
|
|
693
|
+
const renderSnapshot = useMemo(() => buildSnapshot(animatedStyles, staticStyles, getAnimatedTransforms(animatedStyles.transform), committedRenderKeysRef.current, lastPaintedRef.current), [animatedStyles, staticStyles]);
|
|
694
|
+
const renderSnapshotRef = useSharedValue({
|
|
695
|
+
animated: {},
|
|
696
|
+
statics: {},
|
|
697
|
+
transforms: [],
|
|
698
|
+
gatedKeys: {},
|
|
699
|
+
seeds: {},
|
|
700
|
+
removedKeys: {},
|
|
701
|
+
removeTransform: false,
|
|
702
|
+
clearValue: isWeb ? "" : null
|
|
703
|
+
});
|
|
704
|
+
const emitterSnapshotRef = useSharedValue(null);
|
|
705
|
+
const emitterKeysRef = useRef(null);
|
|
706
|
+
useIsomorphicLayoutEffect(() => {
|
|
707
|
+
carryRef.current = nextCarry;
|
|
708
|
+
committedRenderKeysRef.current = renderSnapshot.keys;
|
|
709
|
+
lastPaintedRef.current = renderSnapshot.painted;
|
|
710
|
+
}, [nextCarry, renderSnapshot]);
|
|
711
|
+
const pseudoActiveRef = useRef(false);
|
|
712
|
+
const isExitingJSRef = useRef(false);
|
|
713
|
+
isExitingJSRef.current = isExiting;
|
|
714
|
+
const publishedSnapshotRef = useRef(null);
|
|
715
|
+
useIsomorphicLayoutEffect(() => {
|
|
716
|
+
const droppingLatch = (isExiting || !pseudoActiveRef.current) && emitterSnapshotRef.value !== null;
|
|
717
|
+
const emitterKeys = droppingLatch ? emitterKeysRef.current : null;
|
|
718
|
+
if (droppingLatch || publishedSnapshotRef.current !== renderSnapshot.value) {
|
|
719
|
+
const removedKeys = emitterKeys ? {
|
|
720
|
+
...renderSnapshot.value.removedKeys,
|
|
721
|
+
...getRemovedAnimatedKeys(renderSnapshot.keys, emitterKeys)
|
|
722
|
+
} : renderSnapshot.value.removedKeys;
|
|
723
|
+
renderSnapshotRef.value = {
|
|
724
|
+
...renderSnapshot.value,
|
|
725
|
+
removedKeys,
|
|
726
|
+
removeTransform: Object.keys(removedKeys).some(key => key.startsWith("transform:"))
|
|
727
|
+
};
|
|
728
|
+
publishedSnapshotRef.current = renderSnapshot.value;
|
|
729
|
+
}
|
|
730
|
+
if (droppingLatch) {
|
|
731
|
+
emitterSnapshotRef.value = null;
|
|
732
|
+
emitterKeysRef.current = null;
|
|
733
|
+
}
|
|
734
|
+
});
|
|
409
735
|
const {
|
|
410
736
|
baseConfig,
|
|
411
737
|
propertyConfigs
|
|
@@ -419,8 +745,8 @@ function createAnimations(animationsConfig) {
|
|
|
419
745
|
propertyConfigs: {}
|
|
420
746
|
};
|
|
421
747
|
}
|
|
422
|
-
return buildTransitionConfig(
|
|
423
|
-
}, [isHydrating,
|
|
748
|
+
return buildTransitionConfig(effectiveTransition, animations, animationState, getStyleKeys(animatedStyles));
|
|
749
|
+
}, [isHydrating, effectiveTransition, animatedStyles, animationState]);
|
|
424
750
|
const configRef = useSharedValue({
|
|
425
751
|
baseConfig,
|
|
426
752
|
propertyConfigs,
|
|
@@ -428,92 +754,74 @@ function createAnimations(animationsConfig) {
|
|
|
428
754
|
isHydrating
|
|
429
755
|
});
|
|
430
756
|
useIsomorphicLayoutEffect(() => {
|
|
431
|
-
configRef.
|
|
757
|
+
configRef.value = {
|
|
432
758
|
baseConfig,
|
|
433
759
|
propertyConfigs,
|
|
434
760
|
disableAnimation,
|
|
435
761
|
isHydrating
|
|
436
|
-
}
|
|
762
|
+
};
|
|
437
763
|
}, [baseConfig, propertyConfigs, disableAnimation, isHydrating]);
|
|
438
|
-
useStyleEmitter?.((nextStyle, effectiveTransition2) => {
|
|
764
|
+
useStyleEmitter?.((nextStyle, effectiveTransition2, pseudoActive) => {
|
|
765
|
+
if (isExitingJSRef.current) return;
|
|
766
|
+
pseudoActiveRef.current = pseudoActive === true;
|
|
439
767
|
const animateOnly = props.animateOnly;
|
|
440
|
-
const animated = {};
|
|
441
|
-
const statics = {};
|
|
442
|
-
const transforms = [];
|
|
443
768
|
const transitionToUse = effectiveTransition2 ?? props.transition;
|
|
444
769
|
const {
|
|
445
770
|
baseConfig: newBase,
|
|
446
771
|
propertyConfigs: newPropertyConfigs
|
|
447
772
|
} = buildTransitionConfig(transitionToUse, animations, animationState, getStyleKeys(nextStyle));
|
|
448
|
-
configRef.
|
|
773
|
+
configRef.value = {
|
|
449
774
|
baseConfig: newBase,
|
|
450
775
|
propertyConfigs: newPropertyConfigs,
|
|
451
|
-
disableAnimation: configRef.
|
|
452
|
-
isHydrating: configRef.
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
for (const t of value) {
|
|
464
|
-
if (t && typeof t === "object") {
|
|
465
|
-
const tKey = Object.keys(t)[0];
|
|
466
|
-
const tVal = t[tKey];
|
|
467
|
-
if (typeof tVal === "number" || typeof tVal === "string") {
|
|
468
|
-
transforms.push(t);
|
|
469
|
-
}
|
|
470
|
-
}
|
|
471
|
-
}
|
|
472
|
-
continue;
|
|
473
|
-
}
|
|
474
|
-
if (canAnimateProperty(key, value, animateOnly)) {
|
|
475
|
-
animated[key] = value;
|
|
476
|
-
} else {
|
|
477
|
-
statics[key] = value;
|
|
478
|
-
}
|
|
479
|
-
}
|
|
480
|
-
animatedTargetsRef.set(animated);
|
|
481
|
-
staticTargetsRef.set(statics);
|
|
482
|
-
transformTargetsRef.set(transforms);
|
|
776
|
+
disableAnimation: configRef.value.disableAnimation,
|
|
777
|
+
isHydrating: configRef.value.isHydrating
|
|
778
|
+
};
|
|
779
|
+
const previousKeys = emitterKeysRef.current ?? committedRenderKeysRef.current;
|
|
780
|
+
const {
|
|
781
|
+
animated,
|
|
782
|
+
statics
|
|
783
|
+
} = splitAnimationStyles(nextStyle, isDark, configRef.value.disableAnimation, animateOnly);
|
|
784
|
+
const snapshot = buildSnapshot(animated, statics, getAnimatedTransforms(animated.transform), previousKeys, lastPaintedRef.current);
|
|
785
|
+
emitterSnapshotRef.value = snapshot.value;
|
|
786
|
+
emitterKeysRef.current = snapshot.keys;
|
|
787
|
+
lastPaintedRef.current = snapshot.painted;
|
|
483
788
|
if (process.env.NODE_ENV === "development" && props.debug && props.debug !== "profile") {
|
|
484
789
|
console.info("[animations-reanimated] useStyleEmitter update", {
|
|
485
790
|
animated,
|
|
486
791
|
statics,
|
|
487
|
-
transforms
|
|
792
|
+
transforms: snapshot.value.transforms
|
|
488
793
|
});
|
|
489
794
|
}
|
|
490
795
|
});
|
|
491
796
|
const exitKeysRegistered = useRef(false);
|
|
492
797
|
if (justStartedExiting && sendExitComplete) {
|
|
493
|
-
const exitKeys =
|
|
494
|
-
const animateOnly = props.animateOnly;
|
|
495
|
-
for (const key in animatedStyles) {
|
|
496
|
-
if (key === "transform") continue;
|
|
497
|
-
if (canAnimateProperty(key, animatedStyles[key], animateOnly)) {
|
|
498
|
-
exitKeys.push(key);
|
|
499
|
-
}
|
|
500
|
-
}
|
|
501
|
-
const transforms = animatedStyles.transform;
|
|
502
|
-
if (transforms && Array.isArray(transforms)) {
|
|
503
|
-
for (const t of transforms) {
|
|
504
|
-
if (!t) continue;
|
|
505
|
-
const tKey = Object.keys(t)[0];
|
|
506
|
-
if (tKey) {
|
|
507
|
-
if (animateOnly && !animateOnly.includes(tKey)) {
|
|
508
|
-
continue;
|
|
509
|
-
}
|
|
510
|
-
exitKeys.push(`transform:${tKey}`);
|
|
511
|
-
}
|
|
512
|
-
}
|
|
513
|
-
}
|
|
798
|
+
const exitKeys = getGatedKeys(renderSnapshot.value);
|
|
514
799
|
pendingExitKeysRef.current = new Set(exitKeys);
|
|
515
800
|
exitKeysRegistered.current = exitKeys.length > 0;
|
|
516
801
|
}
|
|
802
|
+
const previousDidAnimateStyleRef = useRef(null);
|
|
803
|
+
const didAnimateStyle = onDidAnimate ? JSON.stringify(style) : null;
|
|
804
|
+
const previousDidAnimateStyle = previousDidAnimateStyleRef.current;
|
|
805
|
+
const shouldRegisterDidAnimate = didAnimateStyle !== null && previousDidAnimateStyle !== null && previousDidAnimateStyle !== didAnimateStyle && !isExiting && !isEntering && !justFinishedEntering;
|
|
806
|
+
const didAnimateKeys = shouldRegisterDidAnimate ? getGatedKeys(renderSnapshot.value) : [];
|
|
807
|
+
useIsomorphicLayoutEffect(() => {
|
|
808
|
+
if (didAnimateStyle === null) {
|
|
809
|
+
previousDidAnimateStyleRef.current = null;
|
|
810
|
+
isCompletingAnimationRef.value = false;
|
|
811
|
+
return;
|
|
812
|
+
}
|
|
813
|
+
const previousStyleStillCurrent = previousDidAnimateStyleRef.current === previousDidAnimateStyle;
|
|
814
|
+
previousDidAnimateStyleRef.current = didAnimateStyle;
|
|
815
|
+
if (!shouldRegisterDidAnimate || !previousStyleStillCurrent) return;
|
|
816
|
+
const cycleId = ++didAnimateCycleIdRef.current;
|
|
817
|
+
pendingDidAnimateKeysRef.current = new Set(didAnimateKeys);
|
|
818
|
+
didAnimateCompletedRef.current = didAnimateKeys.length === 0;
|
|
819
|
+
isCompletingAnimationRef.value = didAnimateKeys.length > 0;
|
|
820
|
+
didAnimateCycleIdShared.value = cycleId;
|
|
821
|
+
if (didAnimateKeys.length === 0) {
|
|
822
|
+
onDidAnimateRef.current?.();
|
|
823
|
+
}
|
|
824
|
+
}, [didAnimateStyle, shouldRegisterDidAnimate]);
|
|
517
825
|
React.useEffect(() => {
|
|
518
826
|
if (!justStartedExiting || !sendExitComplete) return;
|
|
519
827
|
if (!exitKeysRegistered.current && pendingExitKeysRef.current.size === 0) {
|
|
@@ -523,76 +831,77 @@ function createAnimations(animationsConfig) {
|
|
|
523
831
|
}
|
|
524
832
|
}
|
|
525
833
|
}, [justStartedExiting, sendExitComplete]);
|
|
834
|
+
const mapperStateRef = useSharedValue({
|
|
835
|
+
emitted: {}
|
|
836
|
+
});
|
|
526
837
|
const animatedStyle = useAnimatedStyle(() => {
|
|
527
838
|
"worklet";
|
|
528
839
|
|
|
529
|
-
|
|
840
|
+
const mapperState = mapperStateRef.value;
|
|
841
|
+
const config = configRef.value;
|
|
842
|
+
if (config.disableAnimation || config.isHydrating) {
|
|
843
|
+
updateMapperState(mapperStateRef, {});
|
|
530
844
|
return {};
|
|
531
845
|
}
|
|
846
|
+
const previouslyEmitted = mapperState.emitted;
|
|
847
|
+
const emitted = {};
|
|
532
848
|
const result = {};
|
|
533
|
-
const
|
|
534
|
-
const
|
|
535
|
-
const
|
|
536
|
-
const
|
|
537
|
-
const hasEmitterUpdates = emitterAnimated !== null;
|
|
538
|
-
const animatedValues = hasEmitterUpdates ? emitterAnimated : animatedStyles;
|
|
539
|
-
const staticValues = hasEmitterUpdates ? emitterStatic : {};
|
|
849
|
+
const emitterSnapshot = emitterSnapshotRef.value;
|
|
850
|
+
const snapshot = emitterSnapshot ?? renderSnapshotRef.value;
|
|
851
|
+
const animatedValues = snapshot.animated;
|
|
852
|
+
const staticValues = snapshot.statics;
|
|
540
853
|
const currentlyExiting = isExitingRef.value;
|
|
541
854
|
const currentCycleId = exitCycleIdShared.value;
|
|
855
|
+
const currentlyCompletingAnimation = isCompletingAnimationRef.value;
|
|
856
|
+
const currentDidAnimateCycleId = didAnimateCycleIdShared.value;
|
|
542
857
|
for (const key in staticValues) {
|
|
543
858
|
result[key] = staticValues[key];
|
|
544
859
|
}
|
|
860
|
+
for (const key in snapshot.removedKeys) {
|
|
861
|
+
if (!key.startsWith("transform:") && !(key in staticValues)) {
|
|
862
|
+
result[key] = snapshot.clearValue;
|
|
863
|
+
}
|
|
864
|
+
}
|
|
545
865
|
for (const key in animatedValues) {
|
|
546
866
|
if (key === "transform") continue;
|
|
547
867
|
const targetValue = animatedValues[key];
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
const capturedCycleId = currentCycleId;
|
|
553
|
-
callback = finished => {
|
|
554
|
-
"worklet";
|
|
555
|
-
|
|
556
|
-
runOnJS(markExitKeyDone)(capturedKey, capturedCycleId, finished ?? false);
|
|
557
|
-
};
|
|
868
|
+
emitted[key] = true;
|
|
869
|
+
if (typeof targetValue !== "number" && typeof targetValue !== "string") {
|
|
870
|
+
result[key] = targetValue;
|
|
871
|
+
continue;
|
|
558
872
|
}
|
|
559
|
-
result[key] =
|
|
873
|
+
result[key] = animateSnapshotValue(key, key, targetValue, config.propertyConfigs[key] ?? config.baseConfig, !!previouslyEmitted[key], snapshot.seeds[key], !!snapshot.gatedKeys[key], currentlyExiting, currentCycleId, currentlyCompletingAnimation, currentDidAnimateCycleId, markExitKeyDone, markDidAnimateKeyDone, !!COLOR_STYLE_KEYS[key]);
|
|
560
874
|
}
|
|
561
|
-
const transforms =
|
|
562
|
-
if (transforms
|
|
875
|
+
const transforms = snapshot.transforms;
|
|
876
|
+
if (transforms.length > 0 || snapshot.removeTransform) {
|
|
563
877
|
const validTransforms = [];
|
|
564
878
|
for (const t of transforms) {
|
|
565
879
|
if (!t) continue;
|
|
566
880
|
const keys = Object.keys(t);
|
|
567
881
|
if (keys.length === 0) continue;
|
|
568
|
-
const
|
|
882
|
+
const transformKey = keys[0];
|
|
883
|
+
const value = t[transformKey];
|
|
569
884
|
if (typeof value === "number" || typeof value === "string") {
|
|
570
|
-
const transformKey = Object.keys(t)[0];
|
|
571
|
-
const targetValue = t[transformKey];
|
|
572
885
|
const propConfig = config.propertyConfigs[transformKey] ?? config.baseConfig;
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
const capturedKey = `transform:${transformKey}`;
|
|
576
|
-
const capturedCycleId = currentCycleId;
|
|
577
|
-
callback = finished => {
|
|
578
|
-
"worklet";
|
|
579
|
-
|
|
580
|
-
runOnJS(markExitKeyDone)(capturedKey, capturedCycleId, finished ?? false);
|
|
581
|
-
};
|
|
582
|
-
}
|
|
886
|
+
const subKey = `transform:${transformKey}`;
|
|
887
|
+
emitted[subKey] = true;
|
|
583
888
|
validTransforms.push({
|
|
584
|
-
[transformKey]:
|
|
889
|
+
[transformKey]: animateSnapshotValue(subKey, transformKey, value, propConfig, !!previouslyEmitted[subKey], snapshot.seeds[subKey], !!snapshot.gatedKeys[subKey], currentlyExiting, currentCycleId, currentlyCompletingAnimation, currentDidAnimateCycleId, markExitKeyDone, markDidAnimateKeyDone)
|
|
585
890
|
});
|
|
891
|
+
} else {
|
|
892
|
+
validTransforms.push(t);
|
|
586
893
|
}
|
|
587
894
|
}
|
|
588
|
-
if (validTransforms.length > 0) {
|
|
895
|
+
if (validTransforms.length > 0 || !("transform" in staticValues)) {
|
|
589
896
|
result.transform = validTransforms;
|
|
590
897
|
}
|
|
591
898
|
}
|
|
899
|
+
updateMapperState(mapperStateRef, emitted);
|
|
592
900
|
return result;
|
|
593
|
-
}, isWeb ? [
|
|
594
|
-
// pass SharedValues so the mapper watches them on web (no babel plugin)
|
|
595
|
-
|
|
901
|
+
}, isWeb ? [
|
|
902
|
+
// pass SharedValues so the stable mapper watches them on web (no babel plugin)
|
|
903
|
+
renderSnapshotRef, emitterSnapshotRef, configRef, isExitingRef, exitCycleIdShared, markExitKeyDone, isCompletingAnimationRef, didAnimateCycleIdShared, markDidAnimateKeyDone] : void 0);
|
|
904
|
+
silenceAnimatedComponentDevCheck(animatedStyle);
|
|
596
905
|
if (process.env.NODE_ENV === "development" && props.debug && props.debug !== "profile") {
|
|
597
906
|
console.info("[animations-reanimated] useAnimations", {
|
|
598
907
|
animationKey,
|