@hanzogui/animations-reanimated 3.0.5 → 4.3.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 +484 -334
- package/dist/cjs/createAnimations.native.js +568 -409
- package/dist/cjs/createAnimations.native.js.map +1 -1
- package/dist/cjs/index.cjs +7 -5
- package/dist/cjs/index.native.js +7 -5
- package/dist/cjs/index.native.js.map +1 -1
- package/dist/esm/createAnimations.mjs +456 -308
- package/dist/esm/createAnimations.mjs.map +1 -1
- package/dist/esm/createAnimations.native.js +540 -383
- package/dist/esm/createAnimations.native.js.map +1 -1
- package/package.json +5 -5
- package/src/createAnimations.tsx +172 -124
- package/types/createAnimations.d.ts.map +2 -2
|
@@ -2,193 +2,226 @@ var __create = Object.create;
|
|
|
2
2
|
var __defProp = Object.defineProperty;
|
|
3
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __getProtoOf = Object.getPrototypeOf
|
|
6
|
-
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
7
|
var __export = (target, all) => {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
8
|
+
for (var name in all) __defProp(target, name, {
|
|
9
|
+
get: all[name],
|
|
10
|
+
enumerable: true
|
|
11
|
+
});
|
|
12
|
+
};
|
|
13
|
+
var __copyProps = (to, from, except, desc) => {
|
|
14
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
15
|
+
for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
15
16
|
get: () => from[key],
|
|
16
17
|
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
17
18
|
});
|
|
18
|
-
|
|
19
|
-
|
|
19
|
+
}
|
|
20
|
+
return to;
|
|
21
|
+
};
|
|
20
22
|
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
23
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
24
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
25
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
26
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
27
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
28
|
+
value: mod,
|
|
29
|
+
enumerable: true
|
|
30
|
+
}) : target, mod));
|
|
31
|
+
var __toCommonJS = mod => __copyProps(__defProp({}, "__esModule", {
|
|
32
|
+
value: true
|
|
33
|
+
}), mod);
|
|
32
34
|
var createAnimations_exports = {};
|
|
33
35
|
__export(createAnimations_exports, {
|
|
34
36
|
createAnimations: () => createAnimations
|
|
35
37
|
});
|
|
36
38
|
module.exports = __toCommonJS(createAnimations_exports);
|
|
37
|
-
var import_animation_helpers = require("@hanzogui/animation-helpers")
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
39
|
+
var import_animation_helpers = require("@hanzogui/animation-helpers");
|
|
40
|
+
var import_core = require("@hanzogui/core");
|
|
41
|
+
var import_use_presence = require("@hanzogui/use-presence");
|
|
42
|
+
var import_react = __toESM(require("react"), 1);
|
|
43
|
+
var import_react_native_reanimated = __toESM(require("react-native-reanimated"), 1);
|
|
44
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
43
45
|
const getDefaultExport = module2 => {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
46
|
+
const mod = module2;
|
|
47
|
+
if (mod.__esModule || mod[Symbol.toStringTag] === "Module") {
|
|
48
|
+
return mod.default || mod;
|
|
49
|
+
}
|
|
50
|
+
return mod;
|
|
51
|
+
};
|
|
52
|
+
const Animated = getDefaultExport(import_react_native_reanimated.default);
|
|
53
|
+
const resolveDynamicValue = (value, isDark) => {
|
|
54
|
+
if (value !== null && typeof value === "object" && "dynamic" in value && typeof value.dynamic === "object") {
|
|
55
|
+
const dynamic = value.dynamic;
|
|
56
|
+
return isDark ? dynamic.dark : dynamic.light;
|
|
57
|
+
}
|
|
58
|
+
return value;
|
|
59
|
+
};
|
|
60
|
+
const applyAnimation = (targetValue, config, callback) => {
|
|
61
|
+
"worklet";
|
|
57
62
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
63
|
+
const delay = config.delay;
|
|
64
|
+
let animatedValue;
|
|
65
|
+
if (config.type === "timing") {
|
|
66
|
+
animatedValue = (0, import_react_native_reanimated.withTiming)(targetValue, config, callback);
|
|
67
|
+
} else {
|
|
68
|
+
animatedValue = (0, import_react_native_reanimated.withSpring)(targetValue, config, callback);
|
|
69
|
+
}
|
|
70
|
+
if (delay && delay > 0) {
|
|
71
|
+
animatedValue = (0, import_react_native_reanimated.withDelay)(delay, animatedValue);
|
|
72
|
+
}
|
|
73
|
+
return animatedValue;
|
|
74
|
+
};
|
|
75
|
+
const ANIMATABLE_PROPERTIES = {
|
|
76
|
+
// Transform
|
|
77
|
+
transform: true,
|
|
78
|
+
// Opacity
|
|
79
|
+
opacity: true,
|
|
80
|
+
// Dimensions
|
|
81
|
+
height: true,
|
|
82
|
+
width: true,
|
|
83
|
+
minWidth: true,
|
|
84
|
+
minHeight: true,
|
|
85
|
+
maxWidth: true,
|
|
86
|
+
maxHeight: true,
|
|
87
|
+
// Background
|
|
88
|
+
backgroundColor: true,
|
|
89
|
+
// Border colors
|
|
90
|
+
borderColor: true,
|
|
91
|
+
borderLeftColor: true,
|
|
92
|
+
borderRightColor: true,
|
|
93
|
+
borderTopColor: true,
|
|
94
|
+
borderBottomColor: true,
|
|
95
|
+
// Border radius
|
|
96
|
+
borderRadius: true,
|
|
97
|
+
borderTopLeftRadius: true,
|
|
98
|
+
borderTopRightRadius: true,
|
|
99
|
+
borderBottomLeftRadius: true,
|
|
100
|
+
borderBottomRightRadius: true,
|
|
101
|
+
// Border width
|
|
102
|
+
borderWidth: true,
|
|
103
|
+
borderLeftWidth: true,
|
|
104
|
+
borderRightWidth: true,
|
|
105
|
+
borderTopWidth: true,
|
|
106
|
+
borderBottomWidth: true,
|
|
107
|
+
// Text
|
|
108
|
+
color: true,
|
|
109
|
+
fontSize: true,
|
|
110
|
+
fontWeight: true,
|
|
111
|
+
lineHeight: true,
|
|
112
|
+
letterSpacing: true,
|
|
113
|
+
// Position
|
|
114
|
+
left: true,
|
|
115
|
+
right: true,
|
|
116
|
+
top: true,
|
|
117
|
+
bottom: true,
|
|
118
|
+
// Margin
|
|
119
|
+
margin: true,
|
|
120
|
+
marginTop: true,
|
|
121
|
+
marginBottom: true,
|
|
122
|
+
marginLeft: true,
|
|
123
|
+
marginRight: true,
|
|
124
|
+
marginHorizontal: true,
|
|
125
|
+
marginVertical: true,
|
|
126
|
+
// Padding
|
|
127
|
+
padding: true,
|
|
128
|
+
paddingTop: true,
|
|
129
|
+
paddingBottom: true,
|
|
130
|
+
paddingLeft: true,
|
|
131
|
+
paddingRight: true,
|
|
132
|
+
paddingHorizontal: true,
|
|
133
|
+
paddingVertical: true,
|
|
134
|
+
// Flex/Gap
|
|
135
|
+
gap: true,
|
|
136
|
+
rowGap: true,
|
|
137
|
+
columnGap: true,
|
|
138
|
+
flex: true,
|
|
139
|
+
flexGrow: true,
|
|
140
|
+
flexShrink: true
|
|
141
|
+
};
|
|
142
|
+
const canAnimateProperty = (key, value, animateOnly) => {
|
|
143
|
+
if (!ANIMATABLE_PROPERTIES[key]) return false;
|
|
144
|
+
if (value === "auto") return false;
|
|
145
|
+
if (typeof value === "string" && value.startsWith("calc")) return false;
|
|
146
|
+
if (animateOnly && !animateOnly.includes(key)) return false;
|
|
147
|
+
return true;
|
|
148
|
+
};
|
|
130
149
|
function createWebAnimatedComponent(defaultTag) {
|
|
131
|
-
const isText = defaultTag === "span"
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
})
|
|
159
|
-
|
|
150
|
+
const isText = defaultTag === "span";
|
|
151
|
+
const Component = Animated.createAnimatedComponent((0, import_react.forwardRef)((propsIn, ref) => {
|
|
152
|
+
const {
|
|
153
|
+
forwardedRef,
|
|
154
|
+
render = defaultTag,
|
|
155
|
+
...rest
|
|
156
|
+
} = propsIn;
|
|
157
|
+
const hostRef = (0, import_react.useRef)(null);
|
|
158
|
+
const composedRefs = (0, import_core.useComposedRefs)(forwardedRef, ref, hostRef);
|
|
159
|
+
const stateRef = (0, import_react.useRef)({
|
|
160
|
+
get host() {
|
|
161
|
+
return hostRef.current;
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
const [, themeState] = (0, import_core.useThemeWithState)({});
|
|
165
|
+
const result = (0, import_core.getSplitStyles)(rest, isText ? import_core.Text.staticConfig : import_core.View.staticConfig, themeState?.theme ?? {}, themeState?.name ?? "", {
|
|
166
|
+
unmounted: false
|
|
167
|
+
}, {
|
|
168
|
+
isAnimated: false,
|
|
169
|
+
noClass: true
|
|
170
|
+
});
|
|
171
|
+
const viewProps = result?.viewProps ?? {};
|
|
172
|
+
const Element = render;
|
|
173
|
+
const transformedProps = import_core.hooks.usePropsTransform?.(render, viewProps, stateRef, false);
|
|
174
|
+
return /* @__PURE__ */(0, import_jsx_runtime.jsx)(Element, {
|
|
175
|
+
...transformedProps,
|
|
176
|
+
ref: composedRefs
|
|
177
|
+
});
|
|
178
|
+
}));
|
|
179
|
+
Component.acceptRenderProp = true;
|
|
180
|
+
return Component;
|
|
160
181
|
}
|
|
161
|
-
const AnimatedView = createWebAnimatedComponent("div")
|
|
162
|
-
|
|
182
|
+
const AnimatedView = createWebAnimatedComponent("div");
|
|
183
|
+
const AnimatedText = createWebAnimatedComponent("span");
|
|
163
184
|
function buildTransitionConfig(transition, animations, animationState, styleKeys) {
|
|
164
|
-
const normalized = (0, import_animation_helpers.normalizeTransition)(transition)
|
|
165
|
-
|
|
185
|
+
const normalized = (0, import_animation_helpers.normalizeTransition)(transition);
|
|
186
|
+
const effectiveKey = (0, import_animation_helpers.getEffectiveAnimation)(normalized, animationState);
|
|
166
187
|
let base = effectiveKey ? animations[effectiveKey] ?? {
|
|
167
188
|
type: "spring"
|
|
168
189
|
} : {
|
|
169
190
|
type: "spring"
|
|
170
191
|
};
|
|
171
|
-
normalized.delay
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
192
|
+
if (normalized.delay) {
|
|
193
|
+
base = {
|
|
194
|
+
...base,
|
|
195
|
+
delay: normalized.delay
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
if (normalized.config) {
|
|
199
|
+
base = {
|
|
200
|
+
...base,
|
|
201
|
+
...normalized.config
|
|
202
|
+
};
|
|
203
|
+
if (base.type !== "timing" && normalized.config.duration !== void 0 && normalized.config.damping === void 0 && normalized.config.stiffness === void 0 && normalized.config.mass === void 0) {
|
|
204
|
+
base = {
|
|
205
|
+
...base,
|
|
206
|
+
type: "timing"
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
}
|
|
181
210
|
const propertyConfigs = {};
|
|
182
211
|
for (const key of styleKeys) {
|
|
183
212
|
const propAnimation = normalized.properties[key];
|
|
184
|
-
if (typeof propAnimation
|
|
185
|
-
|
|
186
|
-
|
|
213
|
+
if (typeof propAnimation === "string") {
|
|
214
|
+
propertyConfigs[key] = animations[propAnimation] ?? base;
|
|
215
|
+
} else if (propAnimation && typeof propAnimation === "object") {
|
|
216
|
+
const configType = propAnimation.type;
|
|
217
|
+
const baseForProp = configType ? animations[configType] ?? base : base;
|
|
187
218
|
propertyConfigs[key] = {
|
|
188
219
|
...baseForProp,
|
|
189
220
|
...propAnimation
|
|
190
221
|
};
|
|
191
|
-
} else
|
|
222
|
+
} else {
|
|
223
|
+
propertyConfigs[key] = base;
|
|
224
|
+
}
|
|
192
225
|
}
|
|
193
226
|
return {
|
|
194
227
|
baseConfig: base,
|
|
@@ -197,23 +230,31 @@ function buildTransitionConfig(transition, animations, animationState, styleKeys
|
|
|
197
230
|
}
|
|
198
231
|
function getStyleKeys(style) {
|
|
199
232
|
const keys = new Set(Object.keys(style));
|
|
200
|
-
if (style.transform && Array.isArray(style.transform))
|
|
233
|
+
if (style.transform && Array.isArray(style.transform)) {
|
|
234
|
+
for (const t of style.transform) {
|
|
235
|
+
if (t && typeof t === "object") {
|
|
236
|
+
keys.add(Object.keys(t)[0]);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
201
240
|
return keys;
|
|
202
241
|
}
|
|
203
242
|
function createAnimations(animationsConfig) {
|
|
204
243
|
const animations = {};
|
|
205
|
-
for (const key in animationsConfig)
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
244
|
+
for (const key in animationsConfig) {
|
|
245
|
+
animations[key] = {
|
|
246
|
+
type: "spring",
|
|
247
|
+
...animationsConfig[key]
|
|
248
|
+
};
|
|
249
|
+
}
|
|
209
250
|
return {
|
|
210
|
-
needsCustomComponent:
|
|
251
|
+
needsCustomComponent: true,
|
|
211
252
|
View: import_core.isWeb ? AnimatedView : Animated.View,
|
|
212
253
|
Text: import_core.isWeb ? AnimatedText : Animated.Text,
|
|
213
|
-
isReactNative:
|
|
254
|
+
isReactNative: true,
|
|
214
255
|
inputStyle: "value",
|
|
215
256
|
outputStyle: "inline",
|
|
216
|
-
avoidReRenders:
|
|
257
|
+
avoidReRenders: true,
|
|
217
258
|
animations,
|
|
218
259
|
usePresence: import_use_presence.usePresence,
|
|
219
260
|
ResetPresence: import_use_presence.ResetPresence,
|
|
@@ -236,18 +277,27 @@ function createAnimations(animationsConfig) {
|
|
|
236
277
|
setValue(next, config = {
|
|
237
278
|
type: "spring"
|
|
238
279
|
}, onFinish) {
|
|
239
|
-
"
|
|
280
|
+
if (config.type === "direct") {
|
|
281
|
+
sharedValue.value = next;
|
|
282
|
+
onFinish?.();
|
|
283
|
+
} else {
|
|
284
|
+
const cb = onFinish ? () => {
|
|
285
|
+
"worklet";
|
|
240
286
|
|
|
241
|
-
|
|
242
|
-
|
|
287
|
+
(0, import_react_native_reanimated.runOnJS)(onFinish)();
|
|
288
|
+
} : void 0;
|
|
289
|
+
if (import_core.isWeb) {
|
|
290
|
+
sharedValue.value = config.type === "spring" ? (0, import_react_native_reanimated.withSpring)(next, config, cb) : (0, import_react_native_reanimated.withTiming)(next, config, cb);
|
|
291
|
+
} else {
|
|
292
|
+
(0, import_react_native_reanimated.runOnUI)(() => {
|
|
293
|
+
"worklet";
|
|
243
294
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
295
|
+
sharedValue.value = config.type === "spring" ? (0, import_react_native_reanimated.withSpring)(next, config, cb) : (0, import_react_native_reanimated.withTiming)(next, config, cb);
|
|
296
|
+
})();
|
|
297
|
+
}
|
|
298
|
+
}
|
|
247
299
|
},
|
|
248
300
|
stop() {
|
|
249
|
-
"worklet";
|
|
250
|
-
|
|
251
301
|
(0, import_react_native_reanimated.cancelAnimation)(sharedValue);
|
|
252
302
|
}
|
|
253
303
|
}), [sharedValue]);
|
|
@@ -260,106 +310,168 @@ function createAnimations(animationsConfig) {
|
|
|
260
310
|
}, onValue) {
|
|
261
311
|
const instance = value.getInstance();
|
|
262
312
|
return (0, import_react_native_reanimated.useAnimatedReaction)(() => instance.value, (next, prev) => {
|
|
263
|
-
prev !== next
|
|
313
|
+
if (prev !== next) {
|
|
314
|
+
(0, import_react_native_reanimated.runOnJS)(onValue)(next);
|
|
315
|
+
}
|
|
264
316
|
}, [onValue, instance]);
|
|
265
317
|
},
|
|
266
318
|
// =========================================================================
|
|
267
319
|
// useAnimatedNumberStyle - Create animated styles from values
|
|
268
320
|
// =========================================================================
|
|
269
321
|
useAnimatedNumberStyle(val, getStyle) {
|
|
270
|
-
const instance = val.getInstance()
|
|
271
|
-
|
|
272
|
-
|
|
322
|
+
const instance = val.getInstance();
|
|
323
|
+
if (import_core.isWeb) {
|
|
324
|
+
return (0, import_react_native_reanimated.useAnimatedStyle)(() => {
|
|
325
|
+
"worklet";
|
|
326
|
+
|
|
327
|
+
return getStyle(instance.value);
|
|
328
|
+
}, [instance, getStyle]);
|
|
329
|
+
}
|
|
330
|
+
const styleVal = (0, import_react_native_reanimated.useSharedValue)(getStyle(instance.value));
|
|
331
|
+
(0, import_react_native_reanimated.useAnimatedReaction)(() => {
|
|
332
|
+
"worklet";
|
|
333
|
+
|
|
334
|
+
return instance.value;
|
|
335
|
+
}, (current, previous) => {
|
|
336
|
+
"worklet";
|
|
337
|
+
|
|
338
|
+
if (current !== previous) {
|
|
339
|
+
styleVal.value = getStyle(current);
|
|
340
|
+
}
|
|
341
|
+
});
|
|
342
|
+
return (0, import_react_native_reanimated.useAnimatedStyle)(() => {
|
|
343
|
+
"worklet";
|
|
344
|
+
|
|
345
|
+
return styleVal.value;
|
|
346
|
+
});
|
|
347
|
+
},
|
|
348
|
+
useAnimatedNumbersStyle(vals, getStyle) {
|
|
349
|
+
const instances = vals.map(v => v.getInstance());
|
|
350
|
+
return (0, import_react_native_reanimated.useAnimatedStyle)(() => {
|
|
351
|
+
"worklet";
|
|
352
|
+
|
|
353
|
+
const currentValues = instances.map(inst => inst.value);
|
|
354
|
+
return getStyle(...currentValues);
|
|
355
|
+
}, import_core.isWeb ? [getStyle, ...instances] : void 0);
|
|
273
356
|
},
|
|
274
357
|
// =========================================================================
|
|
275
358
|
// useAnimations - Main animation hook for components
|
|
276
359
|
// =========================================================================
|
|
277
360
|
useAnimations(animationProps) {
|
|
278
361
|
const {
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
362
|
+
props,
|
|
363
|
+
presence,
|
|
364
|
+
style,
|
|
365
|
+
componentState,
|
|
366
|
+
useStyleEmitter,
|
|
367
|
+
themeName,
|
|
368
|
+
stateRef,
|
|
369
|
+
styleState
|
|
370
|
+
} = animationProps;
|
|
371
|
+
const isHydrating = componentState.unmounted === true;
|
|
372
|
+
const isMounting = componentState.unmounted === "should-enter";
|
|
373
|
+
const isEntering = !!componentState.unmounted;
|
|
374
|
+
const isExiting = presence?.[0] === false;
|
|
375
|
+
const wasEnteringRef = (0, import_react.useRef)(isEntering);
|
|
376
|
+
const justFinishedEntering = wasEnteringRef.current && !isEntering;
|
|
294
377
|
import_react.default.useEffect(() => {
|
|
295
378
|
wasEnteringRef.current = isEntering;
|
|
296
379
|
});
|
|
297
|
-
const effectiveTransition = styleState?.effectiveTransition ?? props.transition
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
380
|
+
const effectiveTransition = styleState?.effectiveTransition ?? props.transition;
|
|
381
|
+
const normalized = (0, import_animation_helpers.normalizeTransition)(effectiveTransition);
|
|
382
|
+
const animationState = isExiting ? "exit" : isMounting || justFinishedEntering ? "enter" : "default";
|
|
383
|
+
const animationKey = (0, import_animation_helpers.getEffectiveAnimation)(normalized, animationState);
|
|
384
|
+
const disableAnimation = isHydrating || !animationKey;
|
|
385
|
+
const isDark = themeName?.startsWith("dark") || false;
|
|
386
|
+
const sendExitComplete = presence?.[1];
|
|
387
|
+
const exitCycleIdRef = (0, import_react.useRef)(0);
|
|
388
|
+
const pendingExitKeysRef = (0, import_react.useRef)(/* @__PURE__ */new Set());
|
|
389
|
+
const exitCompletedRef = (0, import_react.useRef)(false);
|
|
390
|
+
const wasExitingRef = (0, import_react.useRef)(false);
|
|
391
|
+
const justStartedExiting = isExiting && !wasExitingRef.current;
|
|
392
|
+
const justStoppedExiting = !isExiting && wasExitingRef.current;
|
|
393
|
+
const markExitKeyDone = (0, import_core.useEvent)((key, cycleId, finished) => {
|
|
394
|
+
if (cycleId !== exitCycleIdRef.current) return;
|
|
395
|
+
if (exitCompletedRef.current) return;
|
|
396
|
+
pendingExitKeysRef.current.delete(key);
|
|
397
|
+
if (pendingExitKeysRef.current.size === 0) {
|
|
398
|
+
exitCompletedRef.current = true;
|
|
399
|
+
sendExitComplete?.();
|
|
400
|
+
}
|
|
401
|
+
});
|
|
402
|
+
const isExitingRef = (0, import_react_native_reanimated.useSharedValue)(isExiting);
|
|
403
|
+
const exitCycleIdShared = (0, import_react_native_reanimated.useSharedValue)(exitCycleIdRef.current);
|
|
404
|
+
if (justStartedExiting) {
|
|
405
|
+
exitCycleIdRef.current++;
|
|
406
|
+
exitCompletedRef.current = false;
|
|
407
|
+
pendingExitKeysRef.current.clear();
|
|
408
|
+
}
|
|
409
|
+
if (justStoppedExiting) {
|
|
410
|
+
exitCycleIdRef.current++;
|
|
411
|
+
pendingExitKeysRef.current.clear();
|
|
412
|
+
}
|
|
413
|
+
(0, import_core.useIsomorphicLayoutEffect)(() => {
|
|
414
|
+
isExitingRef.value = isExiting;
|
|
415
|
+
exitCycleIdShared.value = exitCycleIdRef.current;
|
|
416
|
+
}, [isExiting, exitCycleIdRef.current]);
|
|
417
|
+
import_react.default.useEffect(() => {
|
|
318
418
|
wasExitingRef.current = isExiting;
|
|
319
419
|
});
|
|
320
|
-
const animatedTargetsRef = (0, import_react_native_reanimated.useSharedValue)(null)
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
420
|
+
const animatedTargetsRef = (0, import_react_native_reanimated.useSharedValue)(null);
|
|
421
|
+
const staticTargetsRef = (0, import_react_native_reanimated.useSharedValue)(null);
|
|
422
|
+
const transformTargetsRef = (0, import_react_native_reanimated.useSharedValue)(null);
|
|
423
|
+
const {
|
|
424
|
+
animatedStyles,
|
|
425
|
+
staticStyles
|
|
426
|
+
} = (0, import_react.useMemo)(() => {
|
|
427
|
+
const animated = {};
|
|
428
|
+
const staticStyles2 = {};
|
|
429
|
+
const animateOnly = props.animateOnly;
|
|
430
|
+
for (const key in style) {
|
|
431
|
+
const rawValue = style[key];
|
|
432
|
+
const value = resolveDynamicValue(rawValue, isDark);
|
|
433
|
+
if (value === void 0) continue;
|
|
434
|
+
if (disableAnimation) {
|
|
435
|
+
staticStyles2[key] = value;
|
|
436
|
+
continue;
|
|
437
|
+
}
|
|
438
|
+
if (canAnimateProperty(key, value, animateOnly)) {
|
|
439
|
+
animated[key] = value;
|
|
440
|
+
} else {
|
|
441
|
+
staticStyles2[key] = value;
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
if (isMounting) {
|
|
445
|
+
for (const key in animated) {
|
|
446
|
+
staticStyles2[key] = animated[key];
|
|
340
447
|
}
|
|
341
|
-
|
|
448
|
+
}
|
|
449
|
+
return {
|
|
450
|
+
animatedStyles: animated,
|
|
451
|
+
staticStyles: staticStyles2
|
|
452
|
+
};
|
|
453
|
+
}, [disableAnimation, style, isDark, isMounting, props.animateOnly]);
|
|
454
|
+
const {
|
|
455
|
+
baseConfig,
|
|
456
|
+
propertyConfigs
|
|
457
|
+
} = (0, import_react.useMemo)(() => {
|
|
458
|
+
if (isHydrating) {
|
|
342
459
|
return {
|
|
343
|
-
|
|
344
|
-
|
|
460
|
+
baseConfig: {
|
|
461
|
+
type: "timing",
|
|
462
|
+
duration: 0
|
|
463
|
+
},
|
|
464
|
+
propertyConfigs: {}
|
|
345
465
|
};
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
propertyConfigs: {}
|
|
356
|
-
} : buildTransitionConfig(props.transition, animations, animationState, getStyleKeys(animatedStyles)), [isHydrating, props.transition, animatedStyles, animationState]),
|
|
357
|
-
configRef = (0, import_react_native_reanimated.useSharedValue)({
|
|
358
|
-
baseConfig,
|
|
359
|
-
propertyConfigs,
|
|
360
|
-
disableAnimation,
|
|
361
|
-
isHydrating
|
|
362
|
-
});
|
|
466
|
+
}
|
|
467
|
+
return buildTransitionConfig(props.transition, animations, animationState, getStyleKeys(animatedStyles));
|
|
468
|
+
}, [isHydrating, props.transition, animatedStyles, animationState]);
|
|
469
|
+
const configRef = (0, import_react_native_reanimated.useSharedValue)({
|
|
470
|
+
baseConfig,
|
|
471
|
+
propertyConfigs,
|
|
472
|
+
disableAnimation,
|
|
473
|
+
isHydrating
|
|
474
|
+
});
|
|
363
475
|
(0, import_core.useIsomorphicLayoutEffect)(() => {
|
|
364
476
|
configRef.set({
|
|
365
477
|
baseConfig,
|
|
@@ -367,16 +479,17 @@ function createAnimations(animationsConfig) {
|
|
|
367
479
|
disableAnimation,
|
|
368
480
|
isHydrating
|
|
369
481
|
});
|
|
370
|
-
}, [baseConfig, propertyConfigs, disableAnimation, isHydrating])
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
482
|
+
}, [baseConfig, propertyConfigs, disableAnimation, isHydrating]);
|
|
483
|
+
useStyleEmitter?.((nextStyle, effectiveTransition2) => {
|
|
484
|
+
const animateOnly = props.animateOnly;
|
|
485
|
+
const animated = {};
|
|
486
|
+
const statics = {};
|
|
487
|
+
const transforms = [];
|
|
488
|
+
const transitionToUse = effectiveTransition2 ?? props.transition;
|
|
489
|
+
const {
|
|
490
|
+
baseConfig: newBase,
|
|
491
|
+
propertyConfigs: newPropertyConfigs
|
|
492
|
+
} = buildTransitionConfig(transitionToUse, animations, animationState, getStyleKeys(nextStyle));
|
|
380
493
|
configRef.set({
|
|
381
494
|
baseConfig: newBase,
|
|
382
495
|
propertyConfigs: newPropertyConfigs,
|
|
@@ -384,76 +497,108 @@ function createAnimations(animationsConfig) {
|
|
|
384
497
|
isHydrating: configRef.get().isHydrating
|
|
385
498
|
});
|
|
386
499
|
for (const key in nextStyle) {
|
|
387
|
-
const rawValue = nextStyle[key]
|
|
388
|
-
|
|
389
|
-
if (value
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
500
|
+
const rawValue = nextStyle[key];
|
|
501
|
+
const value = resolveDynamicValue(rawValue, isDark);
|
|
502
|
+
if (value == void 0) continue;
|
|
503
|
+
if (configRef.get().disableAnimation) {
|
|
504
|
+
statics[key] = value;
|
|
505
|
+
continue;
|
|
506
|
+
}
|
|
507
|
+
if (key === "transform" && Array.isArray(value)) {
|
|
508
|
+
for (const t of value) {
|
|
509
|
+
if (t && typeof t === "object") {
|
|
510
|
+
const tKey = Object.keys(t)[0];
|
|
511
|
+
const tVal = t[tKey];
|
|
512
|
+
if (typeof tVal === "number" || typeof tVal === "string") {
|
|
513
|
+
transforms.push(t);
|
|
514
|
+
}
|
|
399
515
|
}
|
|
400
|
-
continue;
|
|
401
516
|
}
|
|
402
|
-
|
|
517
|
+
continue;
|
|
518
|
+
}
|
|
519
|
+
if (canAnimateProperty(key, value, animateOnly)) {
|
|
520
|
+
animated[key] = value;
|
|
521
|
+
} else {
|
|
522
|
+
statics[key] = value;
|
|
403
523
|
}
|
|
404
524
|
}
|
|
405
|
-
animatedTargetsRef.set(animated)
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
525
|
+
animatedTargetsRef.set(animated);
|
|
526
|
+
staticTargetsRef.set(statics);
|
|
527
|
+
transformTargetsRef.set(transforms);
|
|
528
|
+
if (process.env.NODE_ENV === "development" && props.debug && props.debug !== "profile") {
|
|
529
|
+
console.info("[animations-reanimated] useStyleEmitter update", {
|
|
530
|
+
animated,
|
|
531
|
+
statics,
|
|
532
|
+
transforms
|
|
533
|
+
});
|
|
534
|
+
}
|
|
410
535
|
});
|
|
411
|
-
const exitKeysRegistered = (0, import_react.useRef)(
|
|
536
|
+
const exitKeysRegistered = (0, import_react.useRef)(false);
|
|
412
537
|
if (justStartedExiting && sendExitComplete) {
|
|
413
|
-
const exitKeys = []
|
|
414
|
-
|
|
415
|
-
for (const key in animatedStyles)
|
|
538
|
+
const exitKeys = [];
|
|
539
|
+
const animateOnly = props.animateOnly;
|
|
540
|
+
for (const key in animatedStyles) {
|
|
541
|
+
if (key === "transform") continue;
|
|
542
|
+
if (canAnimateProperty(key, animatedStyles[key], animateOnly)) {
|
|
543
|
+
exitKeys.push(key);
|
|
544
|
+
}
|
|
545
|
+
}
|
|
416
546
|
const transforms = animatedStyles.transform;
|
|
417
|
-
if (transforms && Array.isArray(transforms))
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
if (
|
|
422
|
-
|
|
547
|
+
if (transforms && Array.isArray(transforms)) {
|
|
548
|
+
for (const t of transforms) {
|
|
549
|
+
if (!t) continue;
|
|
550
|
+
const tKey = Object.keys(t)[0];
|
|
551
|
+
if (tKey) {
|
|
552
|
+
if (animateOnly && !animateOnly.includes(tKey)) {
|
|
553
|
+
continue;
|
|
554
|
+
}
|
|
555
|
+
exitKeys.push(`transform:${tKey}`);
|
|
556
|
+
}
|
|
423
557
|
}
|
|
424
558
|
}
|
|
425
|
-
pendingExitKeysRef.current = new Set(exitKeys)
|
|
559
|
+
pendingExitKeysRef.current = new Set(exitKeys);
|
|
560
|
+
exitKeysRegistered.current = exitKeys.length > 0;
|
|
426
561
|
}
|
|
427
562
|
import_react.default.useEffect(() => {
|
|
428
|
-
!justStartedExiting || !sendExitComplete
|
|
563
|
+
if (!justStartedExiting || !sendExitComplete) return;
|
|
564
|
+
if (!exitKeysRegistered.current && pendingExitKeysRef.current.size === 0) {
|
|
565
|
+
if (!exitCompletedRef.current) {
|
|
566
|
+
exitCompletedRef.current = true;
|
|
567
|
+
sendExitComplete();
|
|
568
|
+
}
|
|
569
|
+
}
|
|
429
570
|
}, [justStartedExiting, sendExitComplete]);
|
|
430
571
|
const animatedStyle = (0, import_react_native_reanimated.useAnimatedStyle)(() => {
|
|
431
572
|
"worklet";
|
|
432
573
|
|
|
433
|
-
if (disableAnimation || isHydrating)
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
574
|
+
if (disableAnimation || isHydrating) {
|
|
575
|
+
return {};
|
|
576
|
+
}
|
|
577
|
+
const result = {};
|
|
578
|
+
const config = configRef.get();
|
|
579
|
+
const emitterAnimated = animatedTargetsRef.value;
|
|
580
|
+
const emitterStatic = staticTargetsRef.value;
|
|
581
|
+
const emitterTransforms = transformTargetsRef.value;
|
|
582
|
+
const hasEmitterUpdates = emitterAnimated !== null;
|
|
583
|
+
const animatedValues = hasEmitterUpdates ? emitterAnimated : animatedStyles;
|
|
584
|
+
const staticValues = hasEmitterUpdates ? emitterStatic : {};
|
|
585
|
+
const currentlyExiting = isExitingRef.value;
|
|
586
|
+
const currentCycleId = exitCycleIdShared.value;
|
|
587
|
+
for (const key in staticValues) {
|
|
588
|
+
result[key] = staticValues[key];
|
|
589
|
+
}
|
|
445
590
|
for (const key in animatedValues) {
|
|
446
591
|
if (key === "transform") continue;
|
|
447
|
-
const targetValue = animatedValues[key]
|
|
448
|
-
|
|
592
|
+
const targetValue = animatedValues[key];
|
|
593
|
+
const propConfig = config.propertyConfigs[key] ?? config.baseConfig;
|
|
449
594
|
let callback;
|
|
450
595
|
if (currentlyExiting) {
|
|
451
|
-
const capturedKey = key
|
|
452
|
-
|
|
596
|
+
const capturedKey = key;
|
|
597
|
+
const capturedCycleId = currentCycleId;
|
|
453
598
|
callback = finished => {
|
|
454
599
|
"worklet";
|
|
455
600
|
|
|
456
|
-
(0, import_react_native_reanimated.runOnJS)(markExitKeyDone)(capturedKey, capturedCycleId, finished ??
|
|
601
|
+
(0, import_react_native_reanimated.runOnJS)(markExitKeyDone)(capturedKey, capturedCycleId, finished ?? false);
|
|
457
602
|
};
|
|
458
603
|
}
|
|
459
604
|
result[key] = applyAnimation(targetValue, propConfig, callback);
|
|
@@ -466,18 +611,18 @@ function createAnimations(animationsConfig) {
|
|
|
466
611
|
const keys = Object.keys(t);
|
|
467
612
|
if (keys.length === 0) continue;
|
|
468
613
|
const value = t[keys[0]];
|
|
469
|
-
if (typeof value
|
|
470
|
-
const transformKey = Object.keys(t)[0]
|
|
471
|
-
|
|
472
|
-
|
|
614
|
+
if (typeof value === "number" || typeof value === "string") {
|
|
615
|
+
const transformKey = Object.keys(t)[0];
|
|
616
|
+
const targetValue = t[transformKey];
|
|
617
|
+
const propConfig = config.propertyConfigs[transformKey] ?? config.baseConfig;
|
|
473
618
|
let callback;
|
|
474
619
|
if (currentlyExiting) {
|
|
475
|
-
const capturedKey = `transform:${transformKey}
|
|
476
|
-
|
|
620
|
+
const capturedKey = `transform:${transformKey}`;
|
|
621
|
+
const capturedCycleId = currentCycleId;
|
|
477
622
|
callback = finished => {
|
|
478
623
|
"worklet";
|
|
479
624
|
|
|
480
|
-
(0, import_react_native_reanimated.runOnJS)(markExitKeyDone)(capturedKey, capturedCycleId, finished ??
|
|
625
|
+
(0, import_react_native_reanimated.runOnJS)(markExitKeyDone)(capturedKey, capturedCycleId, finished ?? false);
|
|
481
626
|
};
|
|
482
627
|
}
|
|
483
628
|
validTransforms.push({
|
|
@@ -485,21 +630,26 @@ function createAnimations(animationsConfig) {
|
|
|
485
630
|
});
|
|
486
631
|
}
|
|
487
632
|
}
|
|
488
|
-
validTransforms.length > 0
|
|
633
|
+
if (validTransforms.length > 0) {
|
|
634
|
+
result.transform = validTransforms;
|
|
635
|
+
}
|
|
489
636
|
}
|
|
490
637
|
return result;
|
|
491
|
-
}, [animatedStyles, baseConfig, propertyConfigs, disableAnimation, isHydrating,
|
|
492
|
-
//
|
|
493
|
-
animatedTargetsRef, staticTargetsRef, transformTargetsRef, isExitingRef, exitCycleIdShared, markExitKeyDone]);
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
638
|
+
}, import_core.isWeb ? [animatedStyles, baseConfig, propertyConfigs, disableAnimation, isHydrating,
|
|
639
|
+
// pass SharedValues so the mapper watches them on web (no babel plugin)
|
|
640
|
+
animatedTargetsRef, staticTargetsRef, transformTargetsRef, isExitingRef, exitCycleIdShared, markExitKeyDone] : void 0);
|
|
641
|
+
if (process.env.NODE_ENV === "development" && props.debug && props.debug !== "profile") {
|
|
642
|
+
console.info("[animations-reanimated] useAnimations", {
|
|
643
|
+
animationKey,
|
|
644
|
+
componentState,
|
|
645
|
+
isExiting,
|
|
646
|
+
animatedStyles,
|
|
647
|
+
staticStyles,
|
|
648
|
+
baseConfig,
|
|
649
|
+
propertyConfigs
|
|
650
|
+
});
|
|
651
|
+
}
|
|
652
|
+
return {
|
|
503
653
|
style: [staticStyles, animatedStyle]
|
|
504
654
|
};
|
|
505
655
|
}
|