@tamagui/animations-reanimated 2.4.6 → 2.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.
@@ -2,6 +2,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { getEffectiveAnimation, normalizeTransition } from "@tamagui/animation-helpers";
3
3
  import { getSplitStyles, hooks, isWeb, Text, useComposedRefs, useEvent, useIsomorphicLayoutEffect, useThemeWithState, View } from "@tamagui/core";
4
4
  import { ResetPresence, usePresence } from "@tamagui/use-presence";
5
+ import normalizeColor from "@react-native/normalize-colors";
5
6
  import React, { forwardRef, useMemo, useRef } from "react";
6
7
  import Animated_, { cancelAnimation, runOnJS, runOnUI, useAnimatedReaction, useAnimatedStyle, useDerivedValue, useSharedValue, withDelay, withSpring, withTiming } from "react-native-reanimated";
7
8
  function _type_of(obj) {
@@ -47,9 +48,284 @@ var cloneAnimationValue = function (value) {
47
48
  }
48
49
  return value;
49
50
  };
51
+ var cloneStyleRecord = function (style) {
52
+ var next = {};
53
+ for (var key in style) {
54
+ next[key] = cloneAnimationValue(style[key]);
55
+ }
56
+ return next;
57
+ };
50
58
  var cloneTransitionConfig = function (config) {
51
59
  return cloneAnimationValue(config);
52
60
  };
61
+ var getAnimatedTransforms = function (value) {
62
+ if (!Array.isArray(value)) return [];
63
+ return value.filter(function (item) {
64
+ return item !== null && (typeof item === "undefined" ? "undefined" : _type_of(item)) === "object" && !Array.isArray(item);
65
+ });
66
+ };
67
+ var getRemovedAnimatedKeys = function (current, previous) {
68
+ var removedKeys = {};
69
+ var _iteratorNormalCompletion = true,
70
+ _didIteratorError = false,
71
+ _iteratorError = void 0;
72
+ try {
73
+ for (var _iterator = previous[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
74
+ var key = _step.value;
75
+ if (!current.has(key)) removedKeys[key] = true;
76
+ }
77
+ } catch (err) {
78
+ _didIteratorError = true;
79
+ _iteratorError = err;
80
+ } finally {
81
+ try {
82
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
83
+ _iterator.return();
84
+ }
85
+ } finally {
86
+ if (_didIteratorError) {
87
+ throw _iteratorError;
88
+ }
89
+ }
90
+ }
91
+ return removedKeys;
92
+ };
93
+ var getImplicitDefault = function (key, targetValue) {
94
+ "worklet";
95
+
96
+ var value = key === "opacity" || key === "scale" || key === "scaleX" || key === "scaleY" ? 1 : 0;
97
+ if (typeof targetValue !== "string") return value;
98
+ var suffixIndex = 0;
99
+ while (suffixIndex < targetValue.length) {
100
+ var character = targetValue[suffixIndex];
101
+ var code = character.charCodeAt(0);
102
+ if (code >= 48 && code <= 57 || character === "." || character === "-" || character === "+") {
103
+ suffixIndex++;
104
+ } else {
105
+ break;
106
+ }
107
+ }
108
+ return suffixIndex > 0 ? `${value}${targetValue.slice(suffixIndex)}` : value;
109
+ };
110
+ var COLOR_STYLE_KEYS = {
111
+ backgroundColor: true,
112
+ borderColor: true,
113
+ borderLeftColor: true,
114
+ borderRightColor: true,
115
+ borderTopColor: true,
116
+ borderBottomColor: true,
117
+ color: true
118
+ };
119
+ var toReanimatedColor = function (value) {
120
+ "worklet";
121
+
122
+ if (typeof value === "number") {
123
+ var color = value >>> 0;
124
+ var alpha = (color >>> 24 & 255) / 255;
125
+ var red = color >>> 16 & 255;
126
+ var green = color >>> 8 & 255;
127
+ var blue = color & 255;
128
+ return `rgba(${red}, ${green}, ${blue}, ${alpha})`;
129
+ }
130
+ if (typeof value !== "string") return value;
131
+ var trimmed = value.trim();
132
+ if (trimmed === "transparent") return "rgba(0, 0, 0, 0)";
133
+ return trimmed;
134
+ };
135
+ var isReanimatedColorHistory = function (value) {
136
+ "worklet";
137
+
138
+ var normalized = toReanimatedColor(value);
139
+ return typeof normalized === "string" && normalized.startsWith("rgba(");
140
+ };
141
+ var normalizeAnimationColor = function (value) {
142
+ if (typeof value === "number") {
143
+ return toReanimatedColor(value);
144
+ }
145
+ if (typeof value !== "string") return;
146
+ var color = normalizeColor(value);
147
+ if (color == null) return;
148
+ var red = Math.round((color & 4278190080) >>> 24);
149
+ var green = Math.round((color & 16711680) >>> 16);
150
+ var blue = Math.round((color & 65280) >>> 8);
151
+ var alpha = (color & 255) / 255;
152
+ return `rgba(${red}, ${green}, ${blue}, ${alpha})`;
153
+ };
154
+ var buildSnapshot = function (animated, statics, transforms, previousKeys, lastPainted) {
155
+ var snapshotAnimated = {};
156
+ var snapshotStatics = cloneStyleRecord(statics);
157
+ for (var key in snapshotStatics) {
158
+ if (!COLOR_STYLE_KEYS[key]) continue;
159
+ var normalized = normalizeAnimationColor(snapshotStatics[key]);
160
+ if (normalized !== void 0) snapshotStatics[key] = normalized;
161
+ }
162
+ for (var key1 in animated) {
163
+ if (key1 === "transform") continue;
164
+ var value = animated[key1];
165
+ if (COLOR_STYLE_KEYS[key1]) {
166
+ var normalized1 = normalizeAnimationColor(value);
167
+ if (normalized1 === void 0) {
168
+ snapshotStatics[key1] = cloneAnimationValue(value);
169
+ continue;
170
+ }
171
+ snapshotAnimated[key1] = normalized1;
172
+ } else {
173
+ snapshotAnimated[key1] = cloneAnimationValue(value);
174
+ }
175
+ }
176
+ var snapshotTransforms = transforms.map(cloneStyleRecord);
177
+ var keys = new Set(Object.keys(snapshotAnimated));
178
+ var _iteratorNormalCompletion = true,
179
+ _didIteratorError = false,
180
+ _iteratorError = void 0;
181
+ try {
182
+ for (var _iterator = snapshotTransforms[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
183
+ var transform = _step.value;
184
+ var key2 = Object.keys(transform)[0];
185
+ var value1 = key2 ? transform[key2] : void 0;
186
+ if (key2 && (typeof value1 === "number" || typeof value1 === "string")) {
187
+ keys.add(`transform:${key2}`);
188
+ }
189
+ }
190
+ } catch (err) {
191
+ _didIteratorError = true;
192
+ _iteratorError = err;
193
+ } finally {
194
+ try {
195
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
196
+ _iterator.return();
197
+ }
198
+ } finally {
199
+ if (_didIteratorError) {
200
+ throw _iteratorError;
201
+ }
202
+ }
203
+ }
204
+ var seeds = {};
205
+ var _iteratorNormalCompletion1 = true,
206
+ _didIteratorError1 = false,
207
+ _iteratorError1 = void 0;
208
+ try {
209
+ for (var _iterator1 = keys[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true) {
210
+ var key3 = _step1.value;
211
+ var value2 = lastPainted[key3];
212
+ if (typeof value2 !== "number" && typeof value2 !== "string") continue;
213
+ if (value2 === "auto" || typeof value2 === "string" && value2.startsWith("calc")) {
214
+ continue;
215
+ }
216
+ if (COLOR_STYLE_KEYS[key3]) value2 = normalizeAnimationColor(value2);
217
+ if (value2 !== void 0) seeds[key3] = value2;
218
+ }
219
+ } catch (err) {
220
+ _didIteratorError1 = true;
221
+ _iteratorError1 = err;
222
+ } finally {
223
+ try {
224
+ if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
225
+ _iterator1.return();
226
+ }
227
+ } finally {
228
+ if (_didIteratorError1) {
229
+ throw _iteratorError1;
230
+ }
231
+ }
232
+ }
233
+ var gatedKeys = {};
234
+ var _iteratorNormalCompletion2 = true,
235
+ _didIteratorError2 = false,
236
+ _iteratorError2 = void 0;
237
+ try {
238
+ for (var _iterator2 = keys[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
239
+ var key4 = _step2.value;
240
+ gatedKeys[key4] = true;
241
+ }
242
+ } catch (err) {
243
+ _didIteratorError2 = true;
244
+ _iteratorError2 = err;
245
+ } finally {
246
+ try {
247
+ if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
248
+ _iterator2.return();
249
+ }
250
+ } finally {
251
+ if (_didIteratorError2) {
252
+ throw _iteratorError2;
253
+ }
254
+ }
255
+ }
256
+ var removedKeys = getRemovedAnimatedKeys(keys, previousKeys);
257
+ var painted = {
258
+ ...snapshotStatics,
259
+ ...snapshotAnimated
260
+ };
261
+ var staticTransforms = getAnimatedTransforms(snapshotStatics.transform);
262
+ delete painted.transform;
263
+ var _iteratorNormalCompletion3 = true,
264
+ _didIteratorError3 = false,
265
+ _iteratorError3 = void 0;
266
+ try {
267
+ for (var _iterator3 = staticTransforms[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
268
+ var transform1 = _step3.value;
269
+ var key5 = Object.keys(transform1)[0];
270
+ if (key5) painted[`transform:${key5}`] = transform1[key5];
271
+ }
272
+ } catch (err) {
273
+ _didIteratorError3 = true;
274
+ _iteratorError3 = err;
275
+ } finally {
276
+ try {
277
+ if (!_iteratorNormalCompletion3 && _iterator3.return != null) {
278
+ _iterator3.return();
279
+ }
280
+ } finally {
281
+ if (_didIteratorError3) {
282
+ throw _iteratorError3;
283
+ }
284
+ }
285
+ }
286
+ var _iteratorNormalCompletion4 = true,
287
+ _didIteratorError4 = false,
288
+ _iteratorError4 = void 0;
289
+ try {
290
+ for (var _iterator4 = snapshotTransforms[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
291
+ var transform2 = _step4.value;
292
+ var key6 = Object.keys(transform2)[0];
293
+ if (key6) painted[`transform:${key6}`] = transform2[key6];
294
+ }
295
+ } catch (err) {
296
+ _didIteratorError4 = true;
297
+ _iteratorError4 = err;
298
+ } finally {
299
+ try {
300
+ if (!_iteratorNormalCompletion4 && _iterator4.return != null) {
301
+ _iterator4.return();
302
+ }
303
+ } finally {
304
+ if (_didIteratorError4) {
305
+ throw _iteratorError4;
306
+ }
307
+ }
308
+ }
309
+ return {
310
+ value: {
311
+ animated: snapshotAnimated,
312
+ statics: snapshotStatics,
313
+ transforms: snapshotTransforms,
314
+ gatedKeys,
315
+ seeds,
316
+ removedKeys,
317
+ removeTransform: Object.keys(removedKeys).some(function (key7) {
318
+ return key7.startsWith("transform:");
319
+ }),
320
+ clearValue: isWeb ? "" : null
321
+ },
322
+ painted,
323
+ keys
324
+ };
325
+ };
326
+ var getGatedKeys = function (snapshot) {
327
+ return Object.keys(snapshot.gatedKeys);
328
+ };
53
329
  var createReanimatedConfig = function (config) {
54
330
  "worklet";
55
331
 
@@ -64,9 +340,10 @@ var createReanimatedConfig = function (config) {
64
340
  }
65
341
  return next;
66
342
  };
67
- var applyAnimation = function (targetValue, config, callback) {
343
+ var applyAnimation = function (targetValue, config, callback, seedValue) {
68
344
  "worklet";
69
345
 
346
+ var validateStartAsColor = arguments.length > 4 && arguments[4] !== void 0 ? arguments[4] : false;
70
347
  var delay = config.delay;
71
348
  var reanimatedConfig = createReanimatedConfig(config);
72
349
  var animatedValue;
@@ -75,11 +352,44 @@ var applyAnimation = function (targetValue, config, callback) {
75
352
  } else {
76
353
  animatedValue = withSpring(targetValue, reanimatedConfig, callback);
77
354
  }
355
+ if (seedValue !== void 0 || validateStartAsColor) {
356
+ var innerOnStart = animatedValue.onStart;
357
+ animatedValue.onStart = function (animation, value, timestamp, previousAnimation) {
358
+ "worklet";
359
+
360
+ var startValue = validateStartAsColor ? isReanimatedColorHistory(value) ? toReanimatedColor(value) : seedValue !== null && seedValue !== void 0 ? seedValue : targetValue : seedValue;
361
+ innerOnStart(animation, startValue, timestamp, previousAnimation);
362
+ };
363
+ }
78
364
  if (delay && delay > 0) {
79
365
  animatedValue = withDelay(delay, animatedValue);
80
366
  }
81
367
  return animatedValue;
82
368
  };
369
+ var animateSnapshotValue = function (key, implicitKey, targetValue, config, previouslyEmitted, seedValue, gated, currentlyExiting, exitCycleId, currentlyCompletingAnimation, didAnimateCycleId, markExitKeyDone, markDidAnimateKeyDone) {
370
+ "worklet";
371
+
372
+ var validateStartAsColor = arguments.length > 13 && arguments[13] !== void 0 ? arguments[13] : false;
373
+ var cycleGated = gated && (currentlyExiting || currentlyCompletingAnimation);
374
+ if (!previouslyEmitted && seedValue === void 0 && !cycleGated) {
375
+ return targetValue;
376
+ }
377
+ var callback;
378
+ if (gated && currentlyExiting) {
379
+ callback = function (finished) {
380
+ "worklet";
381
+
382
+ runOnJS(markExitKeyDone)(key, exitCycleId, finished !== null && finished !== void 0 ? finished : false);
383
+ };
384
+ } else if (gated && currentlyCompletingAnimation) {
385
+ callback = function (finished) {
386
+ "worklet";
387
+
388
+ runOnJS(markDidAnimateKeyDone)(key, didAnimateCycleId, finished !== null && finished !== void 0 ? finished : false);
389
+ };
390
+ }
391
+ return applyAnimation(targetValue, config, callback, previouslyEmitted ? void 0 : seedValue !== null && seedValue !== void 0 ? seedValue : getImplicitDefault(implicitKey, targetValue), validateStartAsColor);
392
+ };
83
393
  var ANIMATABLE_PROPERTIES = {
84
394
  // Transform
85
395
  transform: true,
@@ -154,6 +464,23 @@ var canAnimateProperty = function (key, value, animateOnly) {
154
464
  if (animateOnly && !animateOnly.includes(key)) return false;
155
465
  return true;
156
466
  };
467
+ var splitAnimationStyles = function (style, isDark, disableAnimation, animateOnly) {
468
+ var animated = {};
469
+ var statics = {};
470
+ for (var key in style) {
471
+ var value = resolveDynamicValue(style[key], isDark);
472
+ if (value === void 0) continue;
473
+ if (!disableAnimation && canAnimateProperty(key, value, animateOnly)) {
474
+ animated[key] = cloneAnimationValue(value);
475
+ } else {
476
+ statics[key] = cloneAnimationValue(value);
477
+ }
478
+ }
479
+ return {
480
+ animated,
481
+ statics
482
+ };
483
+ };
157
484
  function createWebAnimatedComponent(defaultTag) {
158
485
  var isText = defaultTag === "span";
159
486
  var Component = Animated.createAnimatedComponent(/* @__PURE__ */forwardRef(function (propsIn, ref) {
@@ -429,7 +756,8 @@ function createAnimations(animationsConfig) {
429
756
  useStyleEmitter,
430
757
  themeName,
431
758
  stateRef,
432
- styleState
759
+ styleState,
760
+ onDidAnimate
433
761
  } = animationProps;
434
762
  var isHydrating = componentState.unmounted === true;
435
763
  var isMounting = componentState.unmounted === "should-enter";
@@ -448,16 +776,36 @@ function createAnimations(animationsConfig) {
448
776
  var disableAnimation = isHydrating || !animationKey;
449
777
  var isDark = (themeName === null || themeName === void 0 ? void 0 : themeName.startsWith("dark")) || false;
450
778
  var sendExitComplete = presence === null || presence === void 0 ? void 0 : presence[1];
779
+ var onDidAnimateRef = useRef(onDidAnimate);
780
+ useIsomorphicLayoutEffect(function () {
781
+ onDidAnimateRef.current = onDidAnimate;
782
+ }, [onDidAnimate]);
783
+ var didAnimateCycleIdRef = useRef(0);
784
+ var pendingDidAnimateKeysRef = useRef(/* @__PURE__ */new Set());
785
+ var didAnimateCompletedRef = useRef(false);
786
+ var isCompletingAnimationRef = useSharedValue(false);
787
+ var didAnimateCycleIdShared = useSharedValue(0);
788
+ var markDidAnimateKeyDone = useEvent(function (key2, cycleId, finished) {
789
+ if (!finished || cycleId !== didAnimateCycleIdRef.current) return;
790
+ if (didAnimateCompletedRef.current) return;
791
+ pendingDidAnimateKeysRef.current.delete(key2);
792
+ if (pendingDidAnimateKeysRef.current.size === 0) {
793
+ var _onDidAnimateRef_current;
794
+ didAnimateCompletedRef.current = true;
795
+ isCompletingAnimationRef.value = false;
796
+ (_onDidAnimateRef_current = onDidAnimateRef.current) === null || _onDidAnimateRef_current === void 0 ? void 0 : _onDidAnimateRef_current.call(onDidAnimateRef);
797
+ }
798
+ });
451
799
  var exitCycleIdRef = useRef(0);
452
800
  var pendingExitKeysRef = useRef(/* @__PURE__ */new Set());
453
801
  var exitCompletedRef = useRef(false);
454
802
  var wasExitingRef = useRef(false);
455
803
  var justStartedExiting = isExiting && !wasExitingRef.current;
456
804
  var justStoppedExiting = !isExiting && wasExitingRef.current;
457
- var markExitKeyDone = useEvent(function (key3, cycleId, finished) {
805
+ var markExitKeyDone = useEvent(function (key2, cycleId, finished) {
458
806
  if (cycleId !== exitCycleIdRef.current) return;
459
807
  if (exitCompletedRef.current) return;
460
- pendingExitKeysRef.current.delete(key3);
808
+ pendingExitKeysRef.current.delete(key2);
461
809
  if (pendingExitKeysRef.current.size === 0) {
462
810
  exitCompletedRef.current = true;
463
811
  sendExitComplete === null || sendExitComplete === void 0 ? void 0 : sendExitComplete();
@@ -469,6 +817,9 @@ function createAnimations(animationsConfig) {
469
817
  exitCycleIdRef.current++;
470
818
  exitCompletedRef.current = false;
471
819
  pendingExitKeysRef.current.clear();
820
+ didAnimateCycleIdRef.current++;
821
+ pendingDidAnimateKeysRef.current.clear();
822
+ didAnimateCompletedRef.current = true;
472
823
  }
473
824
  if (justStoppedExiting) {
474
825
  exitCycleIdRef.current++;
@@ -477,52 +828,87 @@ function createAnimations(animationsConfig) {
477
828
  useIsomorphicLayoutEffect(function () {
478
829
  isExitingRef.value = isExiting;
479
830
  exitCycleIdShared.value = exitCycleIdRef.current;
480
- }, [isExiting, exitCycleIdRef.current]);
831
+ if (justStartedExiting) {
832
+ isCompletingAnimationRef.value = false;
833
+ didAnimateCycleIdShared.value = didAnimateCycleIdRef.current;
834
+ }
835
+ }, [isExiting, exitCycleIdRef.current, justStartedExiting]);
481
836
  React.useEffect(function () {
482
837
  wasExitingRef.current = isExiting;
483
838
  });
484
- var animatedTargetsRef = useSharedValue(null);
485
- var staticTargetsRef = useSharedValue(null);
486
- var transformTargetsRef = useSharedValue(null);
839
+ var committedRenderKeysRef = useRef(/* @__PURE__ */new Set());
840
+ var lastPaintedRef = useRef({});
841
+ var carryRef = useRef({});
487
842
  var {
488
843
  animatedStyles,
489
- staticStyles
844
+ staticStyles,
845
+ nextCarry
490
846
  } = useMemo(function () {
491
- var animated = {};
492
- var staticStyles2 = {};
493
- var animateOnly2 = props.animateOnly;
494
- for (var key3 in style) {
495
- var rawValue = style[key3];
496
- var value = resolveDynamicValue(rawValue, isDark);
497
- if (value === void 0) continue;
498
- if (disableAnimation) {
499
- staticStyles2[key3] = cloneAnimationValue(value);
500
- continue;
501
- }
502
- if (canAnimateProperty(key3, value, animateOnly2)) {
503
- animated[key3] = cloneAnimationValue(value);
504
- } else {
505
- staticStyles2[key3] = cloneAnimationValue(value);
506
- }
847
+ var animateOnly = props.animateOnly;
848
+ var {
849
+ animated,
850
+ statics
851
+ } = splitAnimationStyles(style, isDark, disableAnimation, animateOnly);
852
+ var nextCarry2 = cloneStyleRecord(carryRef.current);
853
+ for (var key2 in nextCarry2) {
854
+ if (!(key2 in animated)) delete nextCarry2[key2];
507
855
  }
508
- if (isMounting) {
509
- for (var key1 in animated) {
510
- staticStyles2[key1] = animated[key1];
856
+ for (var key1 in animated) {
857
+ if (!(key1 in nextCarry2)) {
858
+ nextCarry2[key1] = cloneAnimationValue(animated[key1]);
511
859
  }
860
+ statics[key1] = nextCarry2[key1];
512
861
  }
513
862
  return {
514
863
  animatedStyles: animated,
515
- staticStyles: staticStyles2
864
+ staticStyles: statics,
865
+ nextCarry: nextCarry2
516
866
  };
517
- }, [disableAnimation, style, isDark, isMounting, props.animateOnly]);
867
+ }, [disableAnimation, style, isDark, props.animateOnly]);
868
+ var renderSnapshot = useMemo(function () {
869
+ return buildSnapshot(animatedStyles, staticStyles, getAnimatedTransforms(animatedStyles.transform), committedRenderKeysRef.current, lastPaintedRef.current);
870
+ }, [animatedStyles, staticStyles]);
871
+ var renderSnapshotRef = useSharedValue({
872
+ animated: {},
873
+ statics: {},
874
+ transforms: [],
875
+ gatedKeys: {},
876
+ seeds: {},
877
+ removedKeys: {},
878
+ removeTransform: false,
879
+ clearValue: isWeb ? "" : null
880
+ });
881
+ var emitterSnapshotRef = useSharedValue(null);
882
+ var emitterKeysRef = useRef(null);
883
+ useIsomorphicLayoutEffect(function () {
884
+ carryRef.current = nextCarry;
885
+ committedRenderKeysRef.current = renderSnapshot.keys;
886
+ lastPaintedRef.current = renderSnapshot.painted;
887
+ }, [nextCarry, renderSnapshot]);
518
888
  var pseudoActiveRef = useRef(false);
519
889
  var isExitingJSRef = useRef(false);
520
890
  isExitingJSRef.current = isExiting;
891
+ var publishedSnapshotRef = useRef(null);
521
892
  useIsomorphicLayoutEffect(function () {
522
- if ((isExiting || !pseudoActiveRef.current) && animatedTargetsRef.value !== null) {
523
- animatedTargetsRef.value = null;
524
- staticTargetsRef.value = null;
525
- transformTargetsRef.value = null;
893
+ var droppingLatch = (isExiting || !pseudoActiveRef.current) && emitterSnapshotRef.value !== null;
894
+ var emitterKeys = droppingLatch ? emitterKeysRef.current : null;
895
+ if (droppingLatch || publishedSnapshotRef.current !== renderSnapshot.value) {
896
+ var removedKeys = emitterKeys ? {
897
+ ...renderSnapshot.value.removedKeys,
898
+ ...getRemovedAnimatedKeys(renderSnapshot.keys, emitterKeys)
899
+ } : renderSnapshot.value.removedKeys;
900
+ renderSnapshotRef.value = {
901
+ ...renderSnapshot.value,
902
+ removedKeys,
903
+ removeTransform: Object.keys(removedKeys).some(function (key2) {
904
+ return key2.startsWith("transform:");
905
+ })
906
+ };
907
+ publishedSnapshotRef.current = renderSnapshot.value;
908
+ }
909
+ if (droppingLatch) {
910
+ emitterSnapshotRef.value = null;
911
+ emitterKeysRef.current = null;
526
912
  }
527
913
  });
528
914
  var {
@@ -557,10 +943,7 @@ function createAnimations(animationsConfig) {
557
943
  useStyleEmitter === null || useStyleEmitter === void 0 ? void 0 : useStyleEmitter(function (nextStyle, effectiveTransition2, pseudoActive) {
558
944
  if (isExitingJSRef.current) return;
559
945
  pseudoActiveRef.current = pseudoActive === true;
560
- var animateOnly2 = props.animateOnly;
561
- var animated = {};
562
- var statics = {};
563
- var transforms2 = [];
946
+ var animateOnly = props.animateOnly;
564
947
  var transitionToUse = effectiveTransition2 !== null && effectiveTransition2 !== void 0 ? effectiveTransition2 : props.transition;
565
948
  var {
566
949
  baseConfig: newBase,
@@ -572,107 +955,54 @@ function createAnimations(animationsConfig) {
572
955
  disableAnimation: configRef.value.disableAnimation,
573
956
  isHydrating: configRef.value.isHydrating
574
957
  };
575
- for (var key3 in nextStyle) {
576
- var rawValue = nextStyle[key3];
577
- var value = resolveDynamicValue(rawValue, isDark);
578
- if (value == void 0) continue;
579
- if (configRef.value.disableAnimation) {
580
- statics[key3] = cloneAnimationValue(value);
581
- continue;
582
- }
583
- if (key3 === "transform" && Array.isArray(value)) {
584
- var _iteratorNormalCompletion2 = true,
585
- _didIteratorError2 = false,
586
- _iteratorError2 = void 0;
587
- try {
588
- for (var _iterator2 = value[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
589
- var t2 = _step2.value;
590
- if (t2 && (typeof t2 === "undefined" ? "undefined" : _type_of(t2)) === "object") {
591
- var tKey2 = Object.keys(t2)[0];
592
- var tVal = t2[tKey2];
593
- if (typeof tVal === "number" || typeof tVal === "string") {
594
- transforms2.push(cloneAnimationValue(t2));
595
- }
596
- }
597
- }
598
- } catch (err) {
599
- _didIteratorError2 = true;
600
- _iteratorError2 = err;
601
- } finally {
602
- try {
603
- if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
604
- _iterator2.return();
605
- }
606
- } finally {
607
- if (_didIteratorError2) {
608
- throw _iteratorError2;
609
- }
610
- }
611
- }
612
- continue;
613
- }
614
- if (canAnimateProperty(key3, value, animateOnly2)) {
615
- animated[key3] = cloneAnimationValue(value);
616
- } else {
617
- statics[key3] = cloneAnimationValue(value);
618
- }
619
- }
620
- animatedTargetsRef.value = animated;
621
- staticTargetsRef.value = statics;
622
- transformTargetsRef.value = transforms2;
958
+ var _emitterKeysRef_current;
959
+ var previousKeys = (_emitterKeysRef_current = emitterKeysRef.current) !== null && _emitterKeysRef_current !== void 0 ? _emitterKeysRef_current : committedRenderKeysRef.current;
960
+ var {
961
+ animated,
962
+ statics
963
+ } = splitAnimationStyles(nextStyle, isDark, configRef.value.disableAnimation, animateOnly);
964
+ var snapshot = buildSnapshot(animated, statics, getAnimatedTransforms(animated.transform), previousKeys, lastPaintedRef.current);
965
+ emitterSnapshotRef.value = snapshot.value;
966
+ emitterKeysRef.current = snapshot.keys;
967
+ lastPaintedRef.current = snapshot.painted;
623
968
  if (process.env.NODE_ENV === "development" && props.debug && props.debug !== "profile") {
624
969
  console.info("[animations-reanimated] useStyleEmitter update", {
625
970
  animated,
626
971
  statics,
627
- transforms: transforms2
972
+ transforms: snapshot.value.transforms
628
973
  });
629
974
  }
630
975
  });
631
976
  var exitKeysRegistered = useRef(false);
632
977
  if (justStartedExiting && sendExitComplete) {
633
- var exitKeys = [];
634
- var animateOnly = props.animateOnly;
635
- for (var key2 in animatedStyles) {
636
- if (key2 === "transform") continue;
637
- if (canAnimateProperty(key2, animatedStyles[key2], animateOnly)) {
638
- exitKeys.push(key2);
639
- }
640
- }
641
- var transforms = animatedStyles.transform;
642
- if (transforms && Array.isArray(transforms)) {
643
- var _iteratorNormalCompletion = true,
644
- _didIteratorError = false,
645
- _iteratorError = void 0;
646
- try {
647
- for (var _iterator = transforms[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
648
- var t = _step.value;
649
- if (!t) continue;
650
- var tKey = Object.keys(t)[0];
651
- if (tKey) {
652
- if (animateOnly && !animateOnly.includes(tKey)) {
653
- continue;
654
- }
655
- exitKeys.push(`transform:${tKey}`);
656
- }
657
- }
658
- } catch (err) {
659
- _didIteratorError = true;
660
- _iteratorError = err;
661
- } finally {
662
- try {
663
- if (!_iteratorNormalCompletion && _iterator.return != null) {
664
- _iterator.return();
665
- }
666
- } finally {
667
- if (_didIteratorError) {
668
- throw _iteratorError;
669
- }
670
- }
671
- }
672
- }
978
+ var exitKeys = getGatedKeys(renderSnapshot.value);
673
979
  pendingExitKeysRef.current = new Set(exitKeys);
674
980
  exitKeysRegistered.current = exitKeys.length > 0;
675
981
  }
982
+ var previousDidAnimateStyleRef = useRef(null);
983
+ var didAnimateStyle = onDidAnimate ? JSON.stringify(style) : null;
984
+ var previousDidAnimateStyle = previousDidAnimateStyleRef.current;
985
+ var shouldRegisterDidAnimate = didAnimateStyle !== null && previousDidAnimateStyle !== null && previousDidAnimateStyle !== didAnimateStyle && !isExiting && !isEntering && !justFinishedEntering;
986
+ var didAnimateKeys = shouldRegisterDidAnimate ? getGatedKeys(renderSnapshot.value) : [];
987
+ useIsomorphicLayoutEffect(function () {
988
+ if (didAnimateStyle === null) {
989
+ previousDidAnimateStyleRef.current = null;
990
+ isCompletingAnimationRef.value = false;
991
+ return;
992
+ }
993
+ var previousStyleStillCurrent = previousDidAnimateStyleRef.current === previousDidAnimateStyle;
994
+ previousDidAnimateStyleRef.current = didAnimateStyle;
995
+ if (!shouldRegisterDidAnimate || !previousStyleStillCurrent) return;
996
+ var cycleId = ++didAnimateCycleIdRef.current;
997
+ pendingDidAnimateKeysRef.current = new Set(didAnimateKeys);
998
+ didAnimateCompletedRef.current = didAnimateKeys.length === 0;
999
+ isCompletingAnimationRef.value = didAnimateKeys.length > 0;
1000
+ didAnimateCycleIdShared.value = cycleId;
1001
+ if (didAnimateKeys.length === 0) {
1002
+ var _onDidAnimateRef_current;
1003
+ (_onDidAnimateRef_current = onDidAnimateRef.current) === null || _onDidAnimateRef_current === void 0 ? void 0 : _onDidAnimateRef_current.call(onDidAnimateRef);
1004
+ }
1005
+ }, [didAnimateStyle, shouldRegisterDidAnimate]);
676
1006
  React.useEffect(function () {
677
1007
  if (!justStartedExiting || !sendExitComplete) return;
678
1008
  if (!exitKeysRegistered.current && pendingExitKeysRef.current.size === 0) {
@@ -682,99 +1012,97 @@ function createAnimations(animationsConfig) {
682
1012
  }
683
1013
  }
684
1014
  }, [justStartedExiting, sendExitComplete]);
1015
+ var mapperStateRef = useSharedValue({
1016
+ emitted: {}
1017
+ });
685
1018
  var animatedStyle = useAnimatedStyle(function () {
686
1019
  "worklet";
687
1020
 
688
- var _loop = function (key12) {
689
- if (key12 === "transform") return "continue";
690
- var targetValue = animatedValues[key12];
691
- var _config_propertyConfigs_key;
692
- var propConfig = (_config_propertyConfigs_key = config.propertyConfigs[key12]) !== null && _config_propertyConfigs_key !== void 0 ? _config_propertyConfigs_key : config.baseConfig;
693
- var callback = void 0;
694
- if (currentlyExiting) {
695
- var capturedKey = key12;
696
- var capturedCycleId = currentCycleId;
697
- callback = function (finished) {
698
- "worklet";
699
-
700
- runOnJS(markExitKeyDone)(capturedKey, capturedCycleId, finished !== null && finished !== void 0 ? finished : false);
701
- };
702
- }
703
- result[key12] = applyAnimation(targetValue, propConfig, callback);
704
- };
705
- if (disableAnimation || isHydrating) {
1021
+ var mapperState = mapperStateRef.value;
1022
+ var config = configRef.value;
1023
+ if (config.disableAnimation || config.isHydrating) {
1024
+ mapperState.emitted = {};
706
1025
  return {};
707
1026
  }
1027
+ var previouslyEmitted = mapperState.emitted;
1028
+ var emitted = {};
708
1029
  var result = {};
709
- var config = configRef.value;
710
- var emitterAnimated = animatedTargetsRef.value;
711
- var emitterStatic = staticTargetsRef.value;
712
- var emitterTransforms = transformTargetsRef.value;
713
- var hasEmitterUpdates = emitterAnimated !== null;
714
- var animatedValues = hasEmitterUpdates ? emitterAnimated : animatedStyles;
715
- var staticValues = hasEmitterUpdates ? emitterStatic : staticStyles;
1030
+ var emitterSnapshot = emitterSnapshotRef.value;
1031
+ var snapshot = emitterSnapshot !== null && emitterSnapshot !== void 0 ? emitterSnapshot : renderSnapshotRef.value;
1032
+ var animatedValues = snapshot.animated;
1033
+ var staticValues = snapshot.statics;
716
1034
  var currentlyExiting = isExitingRef.value;
717
1035
  var currentCycleId = exitCycleIdShared.value;
718
- for (var key3 in staticValues) {
719
- result[key3] = staticValues[key3];
1036
+ var currentlyCompletingAnimation = isCompletingAnimationRef.value;
1037
+ var currentDidAnimateCycleId = didAnimateCycleIdShared.value;
1038
+ for (var key2 in staticValues) {
1039
+ result[key2] = staticValues[key2];
1040
+ }
1041
+ for (var key1 in snapshot.removedKeys) {
1042
+ if (!key1.startsWith("transform:") && !(key1 in staticValues)) {
1043
+ result[key1] = snapshot.clearValue;
1044
+ }
720
1045
  }
721
- for (var key1 in animatedValues) _loop(key1);
722
- var transforms2 = hasEmitterUpdates ? emitterTransforms : animatedStyles.transform;
723
- if (transforms2 && Array.isArray(transforms2)) {
1046
+ for (var key22 in animatedValues) {
1047
+ if (key22 === "transform") continue;
1048
+ var targetValue = animatedValues[key22];
1049
+ emitted[key22] = true;
1050
+ if (typeof targetValue !== "number" && typeof targetValue !== "string") {
1051
+ result[key22] = targetValue;
1052
+ continue;
1053
+ }
1054
+ var _config_propertyConfigs_key;
1055
+ result[key22] = animateSnapshotValue(key22, key22, targetValue, (_config_propertyConfigs_key = config.propertyConfigs[key22]) !== null && _config_propertyConfigs_key !== void 0 ? _config_propertyConfigs_key : config.baseConfig, !!previouslyEmitted[key22], snapshot.seeds[key22], !!snapshot.gatedKeys[key22], currentlyExiting, currentCycleId, currentlyCompletingAnimation, currentDidAnimateCycleId, markExitKeyDone, markDidAnimateKeyDone, !!COLOR_STYLE_KEYS[key22]);
1056
+ }
1057
+ var transforms = snapshot.transforms;
1058
+ if (transforms.length > 0 || snapshot.removeTransform) {
724
1059
  var validTransforms = [];
725
- var _iteratorNormalCompletion2 = true,
726
- _didIteratorError2 = false,
727
- _iteratorError2 = void 0;
1060
+ var _iteratorNormalCompletion = true,
1061
+ _didIteratorError = false,
1062
+ _iteratorError = void 0;
728
1063
  try {
729
- var _loop1 = function () {
730
- var t2 = _step2.value;
731
- if (!t2) return "continue";
732
- var keys = Object.keys(t2);
733
- if (keys.length === 0) return "continue";
734
- var value = t2[keys[0]];
1064
+ for (var _iterator = transforms[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
1065
+ var t = _step.value;
1066
+ if (!t) continue;
1067
+ var keys = Object.keys(t);
1068
+ if (keys.length === 0) continue;
1069
+ var transformKey = keys[0];
1070
+ var value = t[transformKey];
735
1071
  if (typeof value === "number" || typeof value === "string") {
736
- var transformKey = Object.keys(t2)[0];
737
- var targetValue = t2[transformKey];
738
1072
  var _config_propertyConfigs_transformKey;
739
1073
  var propConfig = (_config_propertyConfigs_transformKey = config.propertyConfigs[transformKey]) !== null && _config_propertyConfigs_transformKey !== void 0 ? _config_propertyConfigs_transformKey : config.baseConfig;
740
- var callback = void 0;
741
- if (currentlyExiting) {
742
- var capturedKey = `transform:${transformKey}`;
743
- var capturedCycleId = currentCycleId;
744
- callback = function (finished) {
745
- "worklet";
746
-
747
- runOnJS(markExitKeyDone)(capturedKey, capturedCycleId, finished !== null && finished !== void 0 ? finished : false);
748
- };
749
- }
1074
+ var subKey = `transform:${transformKey}`;
1075
+ emitted[subKey] = true;
750
1076
  validTransforms.push({
751
- [transformKey]: applyAnimation(targetValue, propConfig, callback)
1077
+ [transformKey]: animateSnapshotValue(subKey, transformKey, value, propConfig, !!previouslyEmitted[subKey], snapshot.seeds[subKey], !!snapshot.gatedKeys[subKey], currentlyExiting, currentCycleId, currentlyCompletingAnimation, currentDidAnimateCycleId, markExitKeyDone, markDidAnimateKeyDone)
752
1078
  });
1079
+ } else {
1080
+ validTransforms.push(t);
753
1081
  }
754
- };
755
- for (var _iterator2 = transforms2[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) _loop1();
1082
+ }
756
1083
  } catch (err) {
757
- _didIteratorError2 = true;
758
- _iteratorError2 = err;
1084
+ _didIteratorError = true;
1085
+ _iteratorError = err;
759
1086
  } finally {
760
1087
  try {
761
- if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
762
- _iterator2.return();
1088
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
1089
+ _iterator.return();
763
1090
  }
764
1091
  } finally {
765
- if (_didIteratorError2) {
766
- throw _iteratorError2;
1092
+ if (_didIteratorError) {
1093
+ throw _iteratorError;
767
1094
  }
768
1095
  }
769
1096
  }
770
- if (validTransforms.length > 0) {
1097
+ if (validTransforms.length > 0 || !("transform" in staticValues)) {
771
1098
  result.transform = validTransforms;
772
1099
  }
773
1100
  }
1101
+ mapperState.emitted = emitted;
774
1102
  return result;
775
- }, isWeb ? [animatedStyles, staticStyles, baseConfig, propertyConfigs, disableAnimation, isHydrating,
776
- // pass SharedValues so the mapper watches them on web (no babel plugin)
777
- animatedTargetsRef, staticTargetsRef, transformTargetsRef, isExitingRef, exitCycleIdShared, markExitKeyDone] : void 0);
1103
+ }, isWeb ? [
1104
+ // pass SharedValues so the stable mapper watches them on web (no babel plugin)
1105
+ renderSnapshotRef, emitterSnapshotRef, configRef, isExitingRef, exitCycleIdShared, markExitKeyDone, isCompletingAnimationRef, didAnimateCycleIdShared, markDidAnimateKeyDone] : void 0);
778
1106
  silenceAnimatedComponentDevCheck(animatedStyle);
779
1107
  if (process.env.NODE_ENV === "development" && props.debug && props.debug !== "profile") {
780
1108
  console.info("[animations-reanimated] useAnimations", {