@tamagui/animations-react-native 1.0.1-rc.9 → 1.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.
|
@@ -122,8 +122,6 @@ function createAnimations(animations) {
|
|
|
122
122
|
if (!animationsState.current) {
|
|
123
123
|
animationsState.current = /* @__PURE__ */ new WeakMap();
|
|
124
124
|
}
|
|
125
|
-
const runners = [];
|
|
126
|
-
const completions = [];
|
|
127
125
|
const args = [
|
|
128
126
|
JSON.stringify(mergedStyles),
|
|
129
127
|
JSON.stringify(state),
|
|
@@ -132,6 +130,8 @@ function createAnimations(animations) {
|
|
|
132
130
|
];
|
|
133
131
|
const res = (0, import_react.useMemo)(() => {
|
|
134
132
|
var _a;
|
|
133
|
+
const runners = [];
|
|
134
|
+
const completions = [];
|
|
135
135
|
const nonAnimatedStyle = {};
|
|
136
136
|
for (const key in mergedStyles) {
|
|
137
137
|
const val = mergedStyles[key];
|
|
@@ -173,11 +173,18 @@ function createAnimations(animations) {
|
|
|
173
173
|
})
|
|
174
174
|
};
|
|
175
175
|
return {
|
|
176
|
+
runners,
|
|
177
|
+
completions,
|
|
176
178
|
style: [nonAnimatedStyle, animatedStyle]
|
|
177
179
|
};
|
|
178
180
|
function update(key, animated, valIn) {
|
|
179
181
|
const [val, type] = getValue(valIn);
|
|
180
182
|
const value = animated || new import_react_native.Animated.Value(val);
|
|
183
|
+
if (import_core.isWeb) {
|
|
184
|
+
if (animated && val === animated["_value"]) {
|
|
185
|
+
return value;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
181
188
|
let interpolateArgs;
|
|
182
189
|
if (type) {
|
|
183
190
|
const curInterpolation = animationsState.current.get(value);
|
|
@@ -213,26 +220,16 @@ function createAnimations(animations) {
|
|
|
213
220
|
}
|
|
214
221
|
if (process.env.NODE_ENV === "development") {
|
|
215
222
|
if (props["debug"]) {
|
|
216
|
-
console.log(
|
|
217
|
-
" \u{1F4A0} animate",
|
|
218
|
-
key,
|
|
219
|
-
`from ${value["_value"]} to`,
|
|
220
|
-
valIn,
|
|
221
|
-
`(${val})`,
|
|
222
|
-
"type",
|
|
223
|
-
type,
|
|
224
|
-
"interpolate",
|
|
225
|
-
interpolateArgs
|
|
226
|
-
);
|
|
223
|
+
console.log(" \u{1F4A0} animate", key, `from ${value["_value"]} to`, valIn, `(${val})`, "type", type, "interpolate", interpolateArgs);
|
|
227
224
|
}
|
|
228
225
|
}
|
|
229
226
|
return value;
|
|
230
227
|
}
|
|
231
228
|
}, args);
|
|
232
229
|
(0, import_core.useIsomorphicLayoutEffect)(() => {
|
|
233
|
-
runners.forEach((r) => r());
|
|
230
|
+
res.runners.forEach((r) => r());
|
|
234
231
|
let cancel = false;
|
|
235
|
-
Promise.all(completions).then(() => {
|
|
232
|
+
Promise.all(res.completions).then(() => {
|
|
236
233
|
if (cancel)
|
|
237
234
|
return;
|
|
238
235
|
onDidAnimate == null ? void 0 : onDidAnimate();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/createAnimations.tsx"],
|
|
4
|
-
"sourcesContent": ["import {\n AnimatedNumberStrategy,\n AnimationDriver,\n AnimationProp,\n UniversalAnimatedNumber,\n isWeb,\n useEvent,\n useIsomorphicLayoutEffect,\n useSafeRef,\n} from '@tamagui/core'\nimport { usePresence } from '@tamagui/use-presence'\nimport { useEffect, useMemo } from 'react'\nimport { Animated } from 'react-native'\n\ntype AnimationsConfig<A extends Object = any> = {\n [Key in keyof A]: AnimationConfig\n}\n\ntype AnimationConfig = Partial<\n Pick<\n Animated.SpringAnimationConfig,\n | 'delay'\n | 'bounciness'\n | 'damping'\n | 'friction'\n | 'mass'\n | 'overshootClamping'\n | 'speed'\n | 'stiffness'\n | 'tension'\n | 'velocity'\n >\n>\n\nconst animatedStyleKey = {\n transform: true,\n opacity: true,\n}\n\nexport const AnimatedView = Animated.View\nexport const AnimatedText = Animated.Text\n\nexport function useAnimatedNumber(\n initial: number\n): UniversalAnimatedNumber<Animated.Value> {\n const state = useSafeRef(\n null as any as {\n val: Animated.Value\n composite: Animated.CompositeAnimation | null\n strategy: AnimatedNumberStrategy\n }\n )\n if (!state.current) {\n state.current = {\n composite: null,\n val: new Animated.Value(initial),\n strategy: { type: 'spring' },\n }\n }\n\n return {\n getInstance() {\n return state.current.val\n },\n getValue() {\n return state.current.val['_value']\n },\n stop() {\n state.current.composite?.stop()\n state.current.composite = null\n },\n setValue(next: number, { type, ...config } = { type: 'spring' }) {\n const val = state.current.val\n if (type === 'direct') {\n val.setValue(next)\n } else if (type === 'spring') {\n state.current.composite?.stop()\n const composite = Animated.spring(val, {\n ...config,\n toValue: next,\n useNativeDriver: !isWeb,\n })\n composite.start()\n state.current.composite = composite\n } else {\n state.current.composite?.stop()\n const composite = Animated.timing(val, {\n ...config,\n toValue: next,\n useNativeDriver: !isWeb,\n })\n composite.start()\n state.current.composite = composite\n }\n },\n }\n}\n\nexport function useAnimatedNumberReaction(\n value: UniversalAnimatedNumber<Animated.Value>,\n cb: (current: number) => void\n) {\n const onChange = useEvent((current) => {\n cb(current.value)\n })\n\n useEffect(() => {\n const id = value.getInstance().addListener(onChange)\n return () => {\n value.getInstance().removeListener(id)\n }\n }, [value, onChange])\n}\n\nexport function useAnimatedNumberStyle<V extends UniversalAnimatedNumber<Animated.Value>>(\n value: V,\n getStyle: (value: any) => any\n) {\n return getStyle(value.getInstance())\n}\n\nexport function createAnimations<A extends AnimationsConfig>(\n animations: A\n): AnimationDriver<A> {\n AnimatedView['displayName'] = 'AnimatedView'\n AnimatedText['displayName'] = 'AnimatedText'\n\n return {\n isReactNative: true,\n animations,\n View: AnimatedView,\n Text: AnimatedText,\n useAnimatedNumber,\n useAnimatedNumberReaction,\n useAnimatedNumberStyle,\n usePresence,\n useAnimations: ({ props, onDidAnimate, style, state, presence }) => {\n const isExiting = presence?.[0] === false\n const sendExitComplete = presence?.[1]\n const mergedStyles = style\n const animateStyles = useSafeRef<Record<string, Animated.Value>>({})\n const animatedTranforms = useSafeRef<{ [key: string]: Animated.Value }[]>([])\n const animationsState = useSafeRef<\n WeakMap<\n Animated.Value,\n {\n interopolation: Animated.AnimatedInterpolation<any>\n current?: number | undefined\n }\n >\n >(null as any)\n if (!animationsState.current) {\n animationsState.current = new WeakMap()\n }\n\n const runners: Function[] = []\n const completions: Promise<void>[] = []\n\n // const args = [JSON.stringify(mergedStyles)]\n const args = [\n JSON.stringify(mergedStyles),\n JSON.stringify(state),\n isExiting,\n !!onDidAnimate,\n ]\n\n const res = useMemo(() => {\n const nonAnimatedStyle = {}\n for (const key in mergedStyles) {\n const val = mergedStyles[key]\n if (!animatedStyleKey[key]) {\n nonAnimatedStyle[key] = val\n continue\n }\n if (key !== 'transform') {\n animateStyles.current[key] = update(key, animateStyles.current[key], val)\n continue\n }\n // key: 'transform'\n // for now just support one transform key\n if (!val) continue\n for (const [index, transform] of val.entries()) {\n if (!transform) continue\n const tkey = Object.keys(transform)[0]\n const currentTransform = animatedTranforms.current[index]?.[tkey]\n animatedTranforms.current[index] = {\n [tkey]: update(tkey, currentTransform, transform[tkey]),\n }\n animatedTranforms.current = [...animatedTranforms.current]\n }\n }\n\n const animatedStyle = {\n ...Object.fromEntries(\n Object.entries({\n ...animateStyles.current,\n }).map(([k, v]) => [k, animationsState.current!.get(v)?.interopolation || v])\n ),\n transform: animatedTranforms.current.map((r) => {\n const key = Object.keys(r)[0]\n const val = animationsState.current!.get(r[key])?.interopolation || r[key]\n return { [key]: val }\n }),\n }\n\n return {\n style: [nonAnimatedStyle, animatedStyle],\n }\n\n function update(\n key: string,\n animated: Animated.Value | undefined,\n valIn: string | number\n ) {\n const [val, type] = getValue(valIn)\n const value = animated || new Animated.Value(val)\n let interpolateArgs: any\n if (type) {\n const curInterpolation = animationsState.current.get(value)\n interpolateArgs = getInterpolated(\n curInterpolation?.current ?? value['_value'],\n val,\n type\n )\n animationsState.current!.set(value, {\n interopolation: value.interpolate(interpolateArgs),\n current: val,\n })\n }\n if (value) {\n const animationConfig = getAnimationConfig(key, animations, props.animation)\n\n let resolve\n const promise = new Promise<void>((res) => {\n resolve = res\n })\n completions.push(promise)\n\n runners.push(() => {\n value.stopAnimation()\n Animated.spring(value, {\n toValue: val,\n useNativeDriver: !isWeb,\n ...animationConfig,\n }).start(({ finished }) => {\n if (finished) {\n resolve()\n }\n })\n })\n }\n if (process.env.NODE_ENV === 'development') {\n if (props['debug']) {\n // eslint-disable-next-line no-console\n console.log(\n ' \uD83D\uDCA0 animate',\n key,\n `from ${value['_value']} to`,\n valIn,\n `(${val})`,\n 'type',\n type,\n 'interpolate',\n interpolateArgs\n )\n }\n }\n return value\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, args)\n\n useIsomorphicLayoutEffect(() => {\n runners.forEach((r) => r())\n let cancel = false\n Promise.all(completions).then(() => {\n if (cancel) return\n onDidAnimate?.()\n if (isExiting) {\n sendExitComplete?.()\n }\n })\n return () => {\n cancel = true\n }\n }, args)\n\n if (process.env.NODE_ENV === 'development') {\n if (props['debug']) {\n // eslint-disable-next-line no-console\n console.log(`Returning animated`, res)\n }\n }\n\n return res\n },\n }\n}\n\nfunction getInterpolated(current: number, next: number, postfix = 'deg') {\n if (next === current) {\n current = next - 0.000000001\n }\n const inputRange = [current, next]\n const outputRange = [`${current}${postfix}`, `${next}${postfix}`]\n if (next < current) {\n inputRange.reverse()\n outputRange.reverse()\n }\n return {\n inputRange,\n outputRange,\n }\n}\n\nfunction getAnimationConfig(\n key: string,\n animations: AnimationsConfig,\n animation?: AnimationProp\n) {\n if (typeof animation === 'string') {\n return animations[animation]\n }\n let type = ''\n let extraConf: any\n if (Array.isArray(animation)) {\n type = animation[0] as string\n const conf = animation[1] && animation[1][key]\n if (conf) {\n if (typeof conf === 'string') {\n type = conf\n } else {\n type = (conf as any).type || type\n extraConf = conf\n }\n }\n } else {\n const val = animation?.[key]\n type = val?.type\n extraConf = val\n }\n const found = animations[type]\n if (!found) {\n throw new Error(`No animation of type \"${type}\" for key \"${key}\"`)\n }\n return {\n ...found,\n ...extraConf,\n }\n}\n\nfunction getValue(input: number | string) {\n if (typeof input !== 'string') {\n return [input] as const\n }\n const [_, number, after] = input.match(/([-0-9]+)(deg|%|px)/) ?? []\n return [+number, after] as const\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBASO;AACP,0BAA4B;AAC5B,mBAAmC;AACnC,0BAAyB;AAsBzB,MAAM,mBAAmB;AAAA,EACvB,WAAW;AAAA,EACX,SAAS;AACX;AAEO,MAAM,eAAe,6BAAS;AAC9B,MAAM,eAAe,6BAAS;AAE9B,SAAS,kBACd,SACyC;AACzC,QAAM,YAAQ;AAAA,IACZ;AAAA,EAKF;AACA,MAAI,CAAC,MAAM,SAAS;AAClB,UAAM,UAAU;AAAA,MACd,WAAW;AAAA,MACX,KAAK,IAAI,6BAAS,MAAM,OAAO;AAAA,MAC/B,UAAU,EAAE,MAAM,SAAS;AAAA,IAC7B;AAAA,EACF;AAEA,SAAO;AAAA,IACL,cAAc;AACZ,aAAO,MAAM,QAAQ;AAAA,IACvB;AAAA,IACA,WAAW;AACT,aAAO,MAAM,QAAQ,IAAI;AAAA,IAC3B;AAAA,IACA,OAAO;AAnEX;AAoEM,kBAAM,QAAQ,cAAd,mBAAyB;AACzB,YAAM,QAAQ,YAAY;AAAA,IAC5B;AAAA,IACA,SAAS,MAAc,EAAE,SAAS,OAAO,IAAI,EAAE,MAAM,SAAS,GAAG;AAvErE;AAwEM,YAAM,MAAM,MAAM,QAAQ;AAC1B,UAAI,SAAS,UAAU;AACrB,YAAI,SAAS,IAAI;AAAA,MACnB,WAAW,SAAS,UAAU;AAC5B,oBAAM,QAAQ,cAAd,mBAAyB;AACzB,cAAM,YAAY,6BAAS,OAAO,KAAK;AAAA,UACrC,GAAG;AAAA,UACH,SAAS;AAAA,UACT,iBAAiB,CAAC;AAAA,QACpB,CAAC;AACD,kBAAU,MAAM;AAChB,cAAM,QAAQ,YAAY;AAAA,MAC5B,OAAO;AACL,oBAAM,QAAQ,cAAd,mBAAyB;AACzB,cAAM,YAAY,6BAAS,OAAO,KAAK;AAAA,UACrC,GAAG;AAAA,UACH,SAAS;AAAA,UACT,iBAAiB,CAAC;AAAA,QACpB,CAAC;AACD,kBAAU,MAAM;AAChB,cAAM,QAAQ,YAAY;AAAA,MAC5B;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,0BACd,OACA,IACA;AACA,QAAM,eAAW,sBAAS,CAAC,YAAY;AACrC,OAAG,QAAQ,KAAK;AAAA,EAClB,CAAC;AAED,8BAAU,MAAM;AACd,UAAM,KAAK,MAAM,YAAY,EAAE,YAAY,QAAQ;AACnD,WAAO,MAAM;AACX,YAAM,YAAY,EAAE,eAAe,EAAE;AAAA,IACvC;AAAA,EACF,GAAG,CAAC,OAAO,QAAQ,CAAC;AACtB;AAEO,SAAS,uBACd,OACA,UACA;AACA,SAAO,SAAS,MAAM,YAAY,CAAC;AACrC;AAEO,SAAS,iBACd,YACoB;AACpB,eAAa,iBAAiB;AAC9B,eAAa,iBAAiB;AAE9B,SAAO;AAAA,IACL,eAAe;AAAA,IACf;AAAA,IACA,MAAM;AAAA,IACN,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,eAAe,CAAC,EAAE,OAAO,cAAc,OAAO,OAAO,SAAS,MAAM;AAClE,YAAM,aAAY,qCAAW,QAAO;AACpC,YAAM,mBAAmB,qCAAW;AACpC,YAAM,eAAe;AACrB,YAAM,oBAAgB,wBAA2C,CAAC,CAAC;AACnE,YAAM,wBAAoB,wBAAgD,CAAC,CAAC;AAC5E,YAAM,sBAAkB,wBAQtB,IAAW;AACb,UAAI,CAAC,gBAAgB,SAAS;AAC5B,wBAAgB,UAAU,oBAAI,QAAQ;AAAA,MACxC;
|
|
4
|
+
"sourcesContent": ["import {\n AnimatedNumberStrategy,\n AnimationDriver,\n AnimationProp,\n UniversalAnimatedNumber,\n isWeb,\n useEvent,\n useIsomorphicLayoutEffect,\n useSafeRef,\n} from '@tamagui/core'\nimport { usePresence } from '@tamagui/use-presence'\nimport { useEffect, useMemo } from 'react'\nimport { Animated } from 'react-native'\n\ntype AnimationsConfig<A extends Object = any> = {\n [Key in keyof A]: AnimationConfig\n}\n\ntype AnimationConfig = Partial<\n Pick<\n Animated.SpringAnimationConfig,\n | 'delay'\n | 'bounciness'\n | 'damping'\n | 'friction'\n | 'mass'\n | 'overshootClamping'\n | 'speed'\n | 'stiffness'\n | 'tension'\n | 'velocity'\n >\n>\n\nconst animatedStyleKey = {\n transform: true,\n opacity: true,\n}\n\nexport const AnimatedView = Animated.View\nexport const AnimatedText = Animated.Text\n\nexport function useAnimatedNumber(\n initial: number\n): UniversalAnimatedNumber<Animated.Value> {\n const state = useSafeRef(\n null as any as {\n val: Animated.Value\n composite: Animated.CompositeAnimation | null\n strategy: AnimatedNumberStrategy\n }\n )\n if (!state.current) {\n state.current = {\n composite: null,\n val: new Animated.Value(initial),\n strategy: { type: 'spring' },\n }\n }\n\n return {\n getInstance() {\n return state.current.val\n },\n getValue() {\n return state.current.val['_value']\n },\n stop() {\n state.current.composite?.stop()\n state.current.composite = null\n },\n setValue(next: number, { type, ...config } = { type: 'spring' }) {\n const val = state.current.val\n if (type === 'direct') {\n val.setValue(next)\n } else if (type === 'spring') {\n state.current.composite?.stop()\n const composite = Animated.spring(val, {\n ...config,\n toValue: next,\n useNativeDriver: !isWeb,\n })\n composite.start()\n state.current.composite = composite\n } else {\n state.current.composite?.stop()\n const composite = Animated.timing(val, {\n ...config,\n toValue: next,\n useNativeDriver: !isWeb,\n })\n composite.start()\n state.current.composite = composite\n }\n },\n }\n}\n\nexport function useAnimatedNumberReaction(\n value: UniversalAnimatedNumber<Animated.Value>,\n cb: (current: number) => void\n) {\n const onChange = useEvent((current) => {\n cb(current.value)\n })\n\n useEffect(() => {\n const id = value.getInstance().addListener(onChange)\n return () => {\n value.getInstance().removeListener(id)\n }\n }, [value, onChange])\n}\n\nexport function useAnimatedNumberStyle<V extends UniversalAnimatedNumber<Animated.Value>>(\n value: V,\n getStyle: (value: any) => any\n) {\n return getStyle(value.getInstance())\n}\n\nexport function createAnimations<A extends AnimationsConfig>(\n animations: A\n): AnimationDriver<A> {\n AnimatedView['displayName'] = 'AnimatedView'\n AnimatedText['displayName'] = 'AnimatedText'\n\n return {\n isReactNative: true,\n animations,\n View: AnimatedView,\n Text: AnimatedText,\n useAnimatedNumber,\n useAnimatedNumberReaction,\n useAnimatedNumberStyle,\n usePresence,\n useAnimations: ({ props, onDidAnimate, style, state, presence }) => {\n const isExiting = presence?.[0] === false\n const sendExitComplete = presence?.[1]\n const mergedStyles = style\n const animateStyles = useSafeRef<Record<string, Animated.Value>>({})\n const animatedTranforms = useSafeRef<{ [key: string]: Animated.Value }[]>([])\n const animationsState = useSafeRef<\n WeakMap<\n Animated.Value,\n {\n interopolation: Animated.AnimatedInterpolation<any>\n current?: number | undefined\n }\n >\n >(null as any)\n if (!animationsState.current) {\n animationsState.current = new WeakMap()\n }\n\n // const args = [JSON.stringify(mergedStyles)]\n const args = [\n JSON.stringify(mergedStyles),\n JSON.stringify(state),\n isExiting,\n !!onDidAnimate,\n ]\n\n const res = useMemo(() => {\n const runners: Function[] = []\n const completions: Promise<void>[] = []\n\n const nonAnimatedStyle = {}\n for (const key in mergedStyles) {\n const val = mergedStyles[key]\n if (!animatedStyleKey[key]) {\n nonAnimatedStyle[key] = val\n continue\n }\n if (key !== 'transform') {\n animateStyles.current[key] = update(key, animateStyles.current[key], val)\n continue\n }\n // key: 'transform'\n // for now just support one transform key\n if (!val) continue\n\n for (const [index, transform] of val.entries()) {\n if (!transform) continue\n const tkey = Object.keys(transform)[0]\n const currentTransform = animatedTranforms.current[index]?.[tkey]\n animatedTranforms.current[index] = {\n [tkey]: update(tkey, currentTransform, transform[tkey]),\n }\n animatedTranforms.current = [...animatedTranforms.current]\n }\n }\n\n const animatedStyle = {\n ...Object.fromEntries(\n Object.entries({\n ...animateStyles.current,\n }).map(([k, v]) => [k, animationsState.current!.get(v)?.interopolation || v])\n ),\n transform: animatedTranforms.current.map((r) => {\n const key = Object.keys(r)[0]\n const val = animationsState.current!.get(r[key])?.interopolation || r[key]\n return { [key]: val }\n }),\n }\n\n return {\n runners,\n completions,\n style: [nonAnimatedStyle, animatedStyle],\n }\n\n function update(\n key: string,\n animated: Animated.Value | undefined,\n valIn: string | number\n ) {\n const [val, type] = getValue(valIn)\n const value = animated || new Animated.Value(val)\n\n // this optimization seems to work for web but not native...\n if (isWeb) {\n if (animated && val === animated['_value']) {\n // avoid running again for same value\n return value\n }\n }\n\n let interpolateArgs: any\n if (type) {\n const curInterpolation = animationsState.current.get(value)\n interpolateArgs = getInterpolated(\n curInterpolation?.current ?? value['_value'],\n val,\n type\n )\n animationsState.current!.set(value, {\n interopolation: value.interpolate(interpolateArgs),\n current: val,\n })\n }\n\n if (value) {\n const animationConfig = getAnimationConfig(key, animations, props.animation)\n\n let resolve\n const promise = new Promise<void>((res) => {\n resolve = res\n })\n completions.push(promise)\n\n runners.push(() => {\n value.stopAnimation()\n Animated.spring(value, {\n toValue: val,\n useNativeDriver: !isWeb,\n ...animationConfig,\n }).start(({ finished }) => {\n if (finished) {\n resolve()\n }\n })\n })\n }\n\n if (process.env.NODE_ENV === 'development') {\n if (props['debug']) {\n // eslint-disable-next-line no-console\n // prettier-ignore\n console.log(' \uD83D\uDCA0 animate',key,`from ${value['_value']} to`,valIn,`(${val})`,'type',type,'interpolate',interpolateArgs)\n }\n }\n return value\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, args)\n\n useIsomorphicLayoutEffect(() => {\n res.runners.forEach((r) => r())\n let cancel = false\n Promise.all(res.completions).then(() => {\n if (cancel) return\n onDidAnimate?.()\n if (isExiting) {\n sendExitComplete?.()\n }\n })\n return () => {\n cancel = true\n }\n }, args)\n\n if (process.env.NODE_ENV === 'development') {\n if (props['debug']) {\n // eslint-disable-next-line no-console\n console.log(`Returning animated`, res)\n }\n }\n\n return res\n },\n }\n}\n\nfunction getInterpolated(current: number, next: number, postfix = 'deg') {\n if (next === current) {\n current = next - 0.000000001\n }\n const inputRange = [current, next]\n const outputRange = [`${current}${postfix}`, `${next}${postfix}`]\n if (next < current) {\n inputRange.reverse()\n outputRange.reverse()\n }\n return {\n inputRange,\n outputRange,\n }\n}\n\nfunction getAnimationConfig(\n key: string,\n animations: AnimationsConfig,\n animation?: AnimationProp\n) {\n if (typeof animation === 'string') {\n return animations[animation]\n }\n let type = ''\n let extraConf: any\n if (Array.isArray(animation)) {\n type = animation[0] as string\n const conf = animation[1] && animation[1][key]\n if (conf) {\n if (typeof conf === 'string') {\n type = conf\n } else {\n type = (conf as any).type || type\n extraConf = conf\n }\n }\n } else {\n const val = animation?.[key]\n type = val?.type\n extraConf = val\n }\n const found = animations[type]\n if (!found) {\n throw new Error(`No animation of type \"${type}\" for key \"${key}\"`)\n }\n return {\n ...found,\n ...extraConf,\n }\n}\n\nfunction getValue(input: number | string) {\n if (typeof input !== 'string') {\n return [input] as const\n }\n const [_, number, after] = input.match(/([-0-9]+)(deg|%|px)/) ?? []\n return [+number, after] as const\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["_a", "res"]
|
|
7
7
|
}
|
|
@@ -99,8 +99,6 @@ function createAnimations(animations) {
|
|
|
99
99
|
if (!animationsState.current) {
|
|
100
100
|
animationsState.current = /* @__PURE__ */ new WeakMap();
|
|
101
101
|
}
|
|
102
|
-
const runners = [];
|
|
103
|
-
const completions = [];
|
|
104
102
|
const args = [
|
|
105
103
|
JSON.stringify(mergedStyles),
|
|
106
104
|
JSON.stringify(state),
|
|
@@ -109,6 +107,8 @@ function createAnimations(animations) {
|
|
|
109
107
|
];
|
|
110
108
|
const res = useMemo(() => {
|
|
111
109
|
var _a;
|
|
110
|
+
const runners = [];
|
|
111
|
+
const completions = [];
|
|
112
112
|
const nonAnimatedStyle = {};
|
|
113
113
|
for (const key in mergedStyles) {
|
|
114
114
|
const val = mergedStyles[key];
|
|
@@ -150,11 +150,18 @@ function createAnimations(animations) {
|
|
|
150
150
|
})
|
|
151
151
|
};
|
|
152
152
|
return {
|
|
153
|
+
runners,
|
|
154
|
+
completions,
|
|
153
155
|
style: [nonAnimatedStyle, animatedStyle]
|
|
154
156
|
};
|
|
155
157
|
function update(key, animated, valIn) {
|
|
156
158
|
const [val, type] = getValue(valIn);
|
|
157
159
|
const value = animated || new Animated.Value(val);
|
|
160
|
+
if (isWeb) {
|
|
161
|
+
if (animated && val === animated["_value"]) {
|
|
162
|
+
return value;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
158
165
|
let interpolateArgs;
|
|
159
166
|
if (type) {
|
|
160
167
|
const curInterpolation = animationsState.current.get(value);
|
|
@@ -190,26 +197,16 @@ function createAnimations(animations) {
|
|
|
190
197
|
}
|
|
191
198
|
if (process.env.NODE_ENV === "development") {
|
|
192
199
|
if (props["debug"]) {
|
|
193
|
-
console.log(
|
|
194
|
-
" \u{1F4A0} animate",
|
|
195
|
-
key,
|
|
196
|
-
`from ${value["_value"]} to`,
|
|
197
|
-
valIn,
|
|
198
|
-
`(${val})`,
|
|
199
|
-
"type",
|
|
200
|
-
type,
|
|
201
|
-
"interpolate",
|
|
202
|
-
interpolateArgs
|
|
203
|
-
);
|
|
200
|
+
console.log(" \u{1F4A0} animate", key, `from ${value["_value"]} to`, valIn, `(${val})`, "type", type, "interpolate", interpolateArgs);
|
|
204
201
|
}
|
|
205
202
|
}
|
|
206
203
|
return value;
|
|
207
204
|
}
|
|
208
205
|
}, args);
|
|
209
206
|
useIsomorphicLayoutEffect(() => {
|
|
210
|
-
runners.forEach((r) => r());
|
|
207
|
+
res.runners.forEach((r) => r());
|
|
211
208
|
let cancel = false;
|
|
212
|
-
Promise.all(completions).then(() => {
|
|
209
|
+
Promise.all(res.completions).then(() => {
|
|
213
210
|
if (cancel)
|
|
214
211
|
return;
|
|
215
212
|
onDidAnimate == null ? void 0 : onDidAnimate();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/createAnimations.tsx"],
|
|
4
|
-
"sourcesContent": ["import {\n AnimatedNumberStrategy,\n AnimationDriver,\n AnimationProp,\n UniversalAnimatedNumber,\n isWeb,\n useEvent,\n useIsomorphicLayoutEffect,\n useSafeRef,\n} from '@tamagui/core'\nimport { usePresence } from '@tamagui/use-presence'\nimport { useEffect, useMemo } from 'react'\nimport { Animated } from 'react-native'\n\ntype AnimationsConfig<A extends Object = any> = {\n [Key in keyof A]: AnimationConfig\n}\n\ntype AnimationConfig = Partial<\n Pick<\n Animated.SpringAnimationConfig,\n | 'delay'\n | 'bounciness'\n | 'damping'\n | 'friction'\n | 'mass'\n | 'overshootClamping'\n | 'speed'\n | 'stiffness'\n | 'tension'\n | 'velocity'\n >\n>\n\nconst animatedStyleKey = {\n transform: true,\n opacity: true,\n}\n\nexport const AnimatedView = Animated.View\nexport const AnimatedText = Animated.Text\n\nexport function useAnimatedNumber(\n initial: number\n): UniversalAnimatedNumber<Animated.Value> {\n const state = useSafeRef(\n null as any as {\n val: Animated.Value\n composite: Animated.CompositeAnimation | null\n strategy: AnimatedNumberStrategy\n }\n )\n if (!state.current) {\n state.current = {\n composite: null,\n val: new Animated.Value(initial),\n strategy: { type: 'spring' },\n }\n }\n\n return {\n getInstance() {\n return state.current.val\n },\n getValue() {\n return state.current.val['_value']\n },\n stop() {\n state.current.composite?.stop()\n state.current.composite = null\n },\n setValue(next: number, { type, ...config } = { type: 'spring' }) {\n const val = state.current.val\n if (type === 'direct') {\n val.setValue(next)\n } else if (type === 'spring') {\n state.current.composite?.stop()\n const composite = Animated.spring(val, {\n ...config,\n toValue: next,\n useNativeDriver: !isWeb,\n })\n composite.start()\n state.current.composite = composite\n } else {\n state.current.composite?.stop()\n const composite = Animated.timing(val, {\n ...config,\n toValue: next,\n useNativeDriver: !isWeb,\n })\n composite.start()\n state.current.composite = composite\n }\n },\n }\n}\n\nexport function useAnimatedNumberReaction(\n value: UniversalAnimatedNumber<Animated.Value>,\n cb: (current: number) => void\n) {\n const onChange = useEvent((current) => {\n cb(current.value)\n })\n\n useEffect(() => {\n const id = value.getInstance().addListener(onChange)\n return () => {\n value.getInstance().removeListener(id)\n }\n }, [value, onChange])\n}\n\nexport function useAnimatedNumberStyle<V extends UniversalAnimatedNumber<Animated.Value>>(\n value: V,\n getStyle: (value: any) => any\n) {\n return getStyle(value.getInstance())\n}\n\nexport function createAnimations<A extends AnimationsConfig>(\n animations: A\n): AnimationDriver<A> {\n AnimatedView['displayName'] = 'AnimatedView'\n AnimatedText['displayName'] = 'AnimatedText'\n\n return {\n isReactNative: true,\n animations,\n View: AnimatedView,\n Text: AnimatedText,\n useAnimatedNumber,\n useAnimatedNumberReaction,\n useAnimatedNumberStyle,\n usePresence,\n useAnimations: ({ props, onDidAnimate, style, state, presence }) => {\n const isExiting = presence?.[0] === false\n const sendExitComplete = presence?.[1]\n const mergedStyles = style\n const animateStyles = useSafeRef<Record<string, Animated.Value>>({})\n const animatedTranforms = useSafeRef<{ [key: string]: Animated.Value }[]>([])\n const animationsState = useSafeRef<\n WeakMap<\n Animated.Value,\n {\n interopolation: Animated.AnimatedInterpolation<any>\n current?: number | undefined\n }\n >\n >(null as any)\n if (!animationsState.current) {\n animationsState.current = new WeakMap()\n }\n\n const runners: Function[] = []\n const completions: Promise<void>[] = []\n\n // const args = [JSON.stringify(mergedStyles)]\n const args = [\n JSON.stringify(mergedStyles),\n JSON.stringify(state),\n isExiting,\n !!onDidAnimate,\n ]\n\n const res = useMemo(() => {\n const nonAnimatedStyle = {}\n for (const key in mergedStyles) {\n const val = mergedStyles[key]\n if (!animatedStyleKey[key]) {\n nonAnimatedStyle[key] = val\n continue\n }\n if (key !== 'transform') {\n animateStyles.current[key] = update(key, animateStyles.current[key], val)\n continue\n }\n // key: 'transform'\n // for now just support one transform key\n if (!val) continue\n for (const [index, transform] of val.entries()) {\n if (!transform) continue\n const tkey = Object.keys(transform)[0]\n const currentTransform = animatedTranforms.current[index]?.[tkey]\n animatedTranforms.current[index] = {\n [tkey]: update(tkey, currentTransform, transform[tkey]),\n }\n animatedTranforms.current = [...animatedTranforms.current]\n }\n }\n\n const animatedStyle = {\n ...Object.fromEntries(\n Object.entries({\n ...animateStyles.current,\n }).map(([k, v]) => [k, animationsState.current!.get(v)?.interopolation || v])\n ),\n transform: animatedTranforms.current.map((r) => {\n const key = Object.keys(r)[0]\n const val = animationsState.current!.get(r[key])?.interopolation || r[key]\n return { [key]: val }\n }),\n }\n\n return {\n style: [nonAnimatedStyle, animatedStyle],\n }\n\n function update(\n key: string,\n animated: Animated.Value | undefined,\n valIn: string | number\n ) {\n const [val, type] = getValue(valIn)\n const value = animated || new Animated.Value(val)\n let interpolateArgs: any\n if (type) {\n const curInterpolation = animationsState.current.get(value)\n interpolateArgs = getInterpolated(\n curInterpolation?.current ?? value['_value'],\n val,\n type\n )\n animationsState.current!.set(value, {\n interopolation: value.interpolate(interpolateArgs),\n current: val,\n })\n }\n if (value) {\n const animationConfig = getAnimationConfig(key, animations, props.animation)\n\n let resolve\n const promise = new Promise<void>((res) => {\n resolve = res\n })\n completions.push(promise)\n\n runners.push(() => {\n value.stopAnimation()\n Animated.spring(value, {\n toValue: val,\n useNativeDriver: !isWeb,\n ...animationConfig,\n }).start(({ finished }) => {\n if (finished) {\n resolve()\n }\n })\n })\n }\n if (process.env.NODE_ENV === 'development') {\n if (props['debug']) {\n // eslint-disable-next-line no-console\n console.log(\n ' \uD83D\uDCA0 animate',\n key,\n `from ${value['_value']} to`,\n valIn,\n `(${val})`,\n 'type',\n type,\n 'interpolate',\n interpolateArgs\n )\n }\n }\n return value\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, args)\n\n useIsomorphicLayoutEffect(() => {\n runners.forEach((r) => r())\n let cancel = false\n Promise.all(completions).then(() => {\n if (cancel) return\n onDidAnimate?.()\n if (isExiting) {\n sendExitComplete?.()\n }\n })\n return () => {\n cancel = true\n }\n }, args)\n\n if (process.env.NODE_ENV === 'development') {\n if (props['debug']) {\n // eslint-disable-next-line no-console\n console.log(`Returning animated`, res)\n }\n }\n\n return res\n },\n }\n}\n\nfunction getInterpolated(current: number, next: number, postfix = 'deg') {\n if (next === current) {\n current = next - 0.000000001\n }\n const inputRange = [current, next]\n const outputRange = [`${current}${postfix}`, `${next}${postfix}`]\n if (next < current) {\n inputRange.reverse()\n outputRange.reverse()\n }\n return {\n inputRange,\n outputRange,\n }\n}\n\nfunction getAnimationConfig(\n key: string,\n animations: AnimationsConfig,\n animation?: AnimationProp\n) {\n if (typeof animation === 'string') {\n return animations[animation]\n }\n let type = ''\n let extraConf: any\n if (Array.isArray(animation)) {\n type = animation[0] as string\n const conf = animation[1] && animation[1][key]\n if (conf) {\n if (typeof conf === 'string') {\n type = conf\n } else {\n type = (conf as any).type || type\n extraConf = conf\n }\n }\n } else {\n const val = animation?.[key]\n type = val?.type\n extraConf = val\n }\n const found = animations[type]\n if (!found) {\n throw new Error(`No animation of type \"${type}\" for key \"${key}\"`)\n }\n return {\n ...found,\n ...extraConf,\n }\n}\n\nfunction getValue(input: number | string) {\n if (typeof input !== 'string') {\n return [input] as const\n }\n const [_, number, after] = input.match(/([-0-9]+)(deg|%|px)/) ?? []\n return [+number, after] as const\n}\n"],
|
|
5
|
-
"mappings": "AAAA;AAAA,EAKE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,mBAAmB;AAC5B,SAAS,WAAW,eAAe;AACnC,SAAS,gBAAgB;AAsBzB,MAAM,mBAAmB;AAAA,EACvB,WAAW;AAAA,EACX,SAAS;AACX;AAEO,MAAM,eAAe,SAAS;AAC9B,MAAM,eAAe,SAAS;AAE9B,SAAS,kBACd,SACyC;AACzC,QAAM,QAAQ;AAAA,IACZ;AAAA,EAKF;AACA,MAAI,CAAC,MAAM,SAAS;AAClB,UAAM,UAAU;AAAA,MACd,WAAW;AAAA,MACX,KAAK,IAAI,SAAS,MAAM,OAAO;AAAA,MAC/B,UAAU,EAAE,MAAM,SAAS;AAAA,IAC7B;AAAA,EACF;AAEA,SAAO;AAAA,IACL,cAAc;AACZ,aAAO,MAAM,QAAQ;AAAA,IACvB;AAAA,IACA,WAAW;AACT,aAAO,MAAM,QAAQ,IAAI;AAAA,IAC3B;AAAA,IACA,OAAO;AAnEX;AAoEM,kBAAM,QAAQ,cAAd,mBAAyB;AACzB,YAAM,QAAQ,YAAY;AAAA,IAC5B;AAAA,IACA,SAAS,MAAc,EAAE,SAAS,OAAO,IAAI,EAAE,MAAM,SAAS,GAAG;AAvErE;AAwEM,YAAM,MAAM,MAAM,QAAQ;AAC1B,UAAI,SAAS,UAAU;AACrB,YAAI,SAAS,IAAI;AAAA,MACnB,WAAW,SAAS,UAAU;AAC5B,oBAAM,QAAQ,cAAd,mBAAyB;AACzB,cAAM,YAAY,SAAS,OAAO,KAAK;AAAA,UACrC,GAAG;AAAA,UACH,SAAS;AAAA,UACT,iBAAiB,CAAC;AAAA,QACpB,CAAC;AACD,kBAAU,MAAM;AAChB,cAAM,QAAQ,YAAY;AAAA,MAC5B,OAAO;AACL,oBAAM,QAAQ,cAAd,mBAAyB;AACzB,cAAM,YAAY,SAAS,OAAO,KAAK;AAAA,UACrC,GAAG;AAAA,UACH,SAAS;AAAA,UACT,iBAAiB,CAAC;AAAA,QACpB,CAAC;AACD,kBAAU,MAAM;AAChB,cAAM,QAAQ,YAAY;AAAA,MAC5B;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,0BACd,OACA,IACA;AACA,QAAM,WAAW,SAAS,CAAC,YAAY;AACrC,OAAG,QAAQ,KAAK;AAAA,EAClB,CAAC;AAED,YAAU,MAAM;AACd,UAAM,KAAK,MAAM,YAAY,EAAE,YAAY,QAAQ;AACnD,WAAO,MAAM;AACX,YAAM,YAAY,EAAE,eAAe,EAAE;AAAA,IACvC;AAAA,EACF,GAAG,CAAC,OAAO,QAAQ,CAAC;AACtB;AAEO,SAAS,uBACd,OACA,UACA;AACA,SAAO,SAAS,MAAM,YAAY,CAAC;AACrC;AAEO,SAAS,iBACd,YACoB;AACpB,eAAa,iBAAiB;AAC9B,eAAa,iBAAiB;AAE9B,SAAO;AAAA,IACL,eAAe;AAAA,IACf;AAAA,IACA,MAAM;AAAA,IACN,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,eAAe,CAAC,EAAE,OAAO,cAAc,OAAO,OAAO,SAAS,MAAM;AAClE,YAAM,aAAY,qCAAW,QAAO;AACpC,YAAM,mBAAmB,qCAAW;AACpC,YAAM,eAAe;AACrB,YAAM,gBAAgB,WAA2C,CAAC,CAAC;AACnE,YAAM,oBAAoB,WAAgD,CAAC,CAAC;AAC5E,YAAM,kBAAkB,WAQtB,IAAW;AACb,UAAI,CAAC,gBAAgB,SAAS;AAC5B,wBAAgB,UAAU,oBAAI,QAAQ;AAAA,MACxC;
|
|
4
|
+
"sourcesContent": ["import {\n AnimatedNumberStrategy,\n AnimationDriver,\n AnimationProp,\n UniversalAnimatedNumber,\n isWeb,\n useEvent,\n useIsomorphicLayoutEffect,\n useSafeRef,\n} from '@tamagui/core'\nimport { usePresence } from '@tamagui/use-presence'\nimport { useEffect, useMemo } from 'react'\nimport { Animated } from 'react-native'\n\ntype AnimationsConfig<A extends Object = any> = {\n [Key in keyof A]: AnimationConfig\n}\n\ntype AnimationConfig = Partial<\n Pick<\n Animated.SpringAnimationConfig,\n | 'delay'\n | 'bounciness'\n | 'damping'\n | 'friction'\n | 'mass'\n | 'overshootClamping'\n | 'speed'\n | 'stiffness'\n | 'tension'\n | 'velocity'\n >\n>\n\nconst animatedStyleKey = {\n transform: true,\n opacity: true,\n}\n\nexport const AnimatedView = Animated.View\nexport const AnimatedText = Animated.Text\n\nexport function useAnimatedNumber(\n initial: number\n): UniversalAnimatedNumber<Animated.Value> {\n const state = useSafeRef(\n null as any as {\n val: Animated.Value\n composite: Animated.CompositeAnimation | null\n strategy: AnimatedNumberStrategy\n }\n )\n if (!state.current) {\n state.current = {\n composite: null,\n val: new Animated.Value(initial),\n strategy: { type: 'spring' },\n }\n }\n\n return {\n getInstance() {\n return state.current.val\n },\n getValue() {\n return state.current.val['_value']\n },\n stop() {\n state.current.composite?.stop()\n state.current.composite = null\n },\n setValue(next: number, { type, ...config } = { type: 'spring' }) {\n const val = state.current.val\n if (type === 'direct') {\n val.setValue(next)\n } else if (type === 'spring') {\n state.current.composite?.stop()\n const composite = Animated.spring(val, {\n ...config,\n toValue: next,\n useNativeDriver: !isWeb,\n })\n composite.start()\n state.current.composite = composite\n } else {\n state.current.composite?.stop()\n const composite = Animated.timing(val, {\n ...config,\n toValue: next,\n useNativeDriver: !isWeb,\n })\n composite.start()\n state.current.composite = composite\n }\n },\n }\n}\n\nexport function useAnimatedNumberReaction(\n value: UniversalAnimatedNumber<Animated.Value>,\n cb: (current: number) => void\n) {\n const onChange = useEvent((current) => {\n cb(current.value)\n })\n\n useEffect(() => {\n const id = value.getInstance().addListener(onChange)\n return () => {\n value.getInstance().removeListener(id)\n }\n }, [value, onChange])\n}\n\nexport function useAnimatedNumberStyle<V extends UniversalAnimatedNumber<Animated.Value>>(\n value: V,\n getStyle: (value: any) => any\n) {\n return getStyle(value.getInstance())\n}\n\nexport function createAnimations<A extends AnimationsConfig>(\n animations: A\n): AnimationDriver<A> {\n AnimatedView['displayName'] = 'AnimatedView'\n AnimatedText['displayName'] = 'AnimatedText'\n\n return {\n isReactNative: true,\n animations,\n View: AnimatedView,\n Text: AnimatedText,\n useAnimatedNumber,\n useAnimatedNumberReaction,\n useAnimatedNumberStyle,\n usePresence,\n useAnimations: ({ props, onDidAnimate, style, state, presence }) => {\n const isExiting = presence?.[0] === false\n const sendExitComplete = presence?.[1]\n const mergedStyles = style\n const animateStyles = useSafeRef<Record<string, Animated.Value>>({})\n const animatedTranforms = useSafeRef<{ [key: string]: Animated.Value }[]>([])\n const animationsState = useSafeRef<\n WeakMap<\n Animated.Value,\n {\n interopolation: Animated.AnimatedInterpolation<any>\n current?: number | undefined\n }\n >\n >(null as any)\n if (!animationsState.current) {\n animationsState.current = new WeakMap()\n }\n\n // const args = [JSON.stringify(mergedStyles)]\n const args = [\n JSON.stringify(mergedStyles),\n JSON.stringify(state),\n isExiting,\n !!onDidAnimate,\n ]\n\n const res = useMemo(() => {\n const runners: Function[] = []\n const completions: Promise<void>[] = []\n\n const nonAnimatedStyle = {}\n for (const key in mergedStyles) {\n const val = mergedStyles[key]\n if (!animatedStyleKey[key]) {\n nonAnimatedStyle[key] = val\n continue\n }\n if (key !== 'transform') {\n animateStyles.current[key] = update(key, animateStyles.current[key], val)\n continue\n }\n // key: 'transform'\n // for now just support one transform key\n if (!val) continue\n\n for (const [index, transform] of val.entries()) {\n if (!transform) continue\n const tkey = Object.keys(transform)[0]\n const currentTransform = animatedTranforms.current[index]?.[tkey]\n animatedTranforms.current[index] = {\n [tkey]: update(tkey, currentTransform, transform[tkey]),\n }\n animatedTranforms.current = [...animatedTranforms.current]\n }\n }\n\n const animatedStyle = {\n ...Object.fromEntries(\n Object.entries({\n ...animateStyles.current,\n }).map(([k, v]) => [k, animationsState.current!.get(v)?.interopolation || v])\n ),\n transform: animatedTranforms.current.map((r) => {\n const key = Object.keys(r)[0]\n const val = animationsState.current!.get(r[key])?.interopolation || r[key]\n return { [key]: val }\n }),\n }\n\n return {\n runners,\n completions,\n style: [nonAnimatedStyle, animatedStyle],\n }\n\n function update(\n key: string,\n animated: Animated.Value | undefined,\n valIn: string | number\n ) {\n const [val, type] = getValue(valIn)\n const value = animated || new Animated.Value(val)\n\n // this optimization seems to work for web but not native...\n if (isWeb) {\n if (animated && val === animated['_value']) {\n // avoid running again for same value\n return value\n }\n }\n\n let interpolateArgs: any\n if (type) {\n const curInterpolation = animationsState.current.get(value)\n interpolateArgs = getInterpolated(\n curInterpolation?.current ?? value['_value'],\n val,\n type\n )\n animationsState.current!.set(value, {\n interopolation: value.interpolate(interpolateArgs),\n current: val,\n })\n }\n\n if (value) {\n const animationConfig = getAnimationConfig(key, animations, props.animation)\n\n let resolve\n const promise = new Promise<void>((res) => {\n resolve = res\n })\n completions.push(promise)\n\n runners.push(() => {\n value.stopAnimation()\n Animated.spring(value, {\n toValue: val,\n useNativeDriver: !isWeb,\n ...animationConfig,\n }).start(({ finished }) => {\n if (finished) {\n resolve()\n }\n })\n })\n }\n\n if (process.env.NODE_ENV === 'development') {\n if (props['debug']) {\n // eslint-disable-next-line no-console\n // prettier-ignore\n console.log(' \uD83D\uDCA0 animate',key,`from ${value['_value']} to`,valIn,`(${val})`,'type',type,'interpolate',interpolateArgs)\n }\n }\n return value\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, args)\n\n useIsomorphicLayoutEffect(() => {\n res.runners.forEach((r) => r())\n let cancel = false\n Promise.all(res.completions).then(() => {\n if (cancel) return\n onDidAnimate?.()\n if (isExiting) {\n sendExitComplete?.()\n }\n })\n return () => {\n cancel = true\n }\n }, args)\n\n if (process.env.NODE_ENV === 'development') {\n if (props['debug']) {\n // eslint-disable-next-line no-console\n console.log(`Returning animated`, res)\n }\n }\n\n return res\n },\n }\n}\n\nfunction getInterpolated(current: number, next: number, postfix = 'deg') {\n if (next === current) {\n current = next - 0.000000001\n }\n const inputRange = [current, next]\n const outputRange = [`${current}${postfix}`, `${next}${postfix}`]\n if (next < current) {\n inputRange.reverse()\n outputRange.reverse()\n }\n return {\n inputRange,\n outputRange,\n }\n}\n\nfunction getAnimationConfig(\n key: string,\n animations: AnimationsConfig,\n animation?: AnimationProp\n) {\n if (typeof animation === 'string') {\n return animations[animation]\n }\n let type = ''\n let extraConf: any\n if (Array.isArray(animation)) {\n type = animation[0] as string\n const conf = animation[1] && animation[1][key]\n if (conf) {\n if (typeof conf === 'string') {\n type = conf\n } else {\n type = (conf as any).type || type\n extraConf = conf\n }\n }\n } else {\n const val = animation?.[key]\n type = val?.type\n extraConf = val\n }\n const found = animations[type]\n if (!found) {\n throw new Error(`No animation of type \"${type}\" for key \"${key}\"`)\n }\n return {\n ...found,\n ...extraConf,\n }\n}\n\nfunction getValue(input: number | string) {\n if (typeof input !== 'string') {\n return [input] as const\n }\n const [_, number, after] = input.match(/([-0-9]+)(deg|%|px)/) ?? []\n return [+number, after] as const\n}\n"],
|
|
5
|
+
"mappings": "AAAA;AAAA,EAKE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,mBAAmB;AAC5B,SAAS,WAAW,eAAe;AACnC,SAAS,gBAAgB;AAsBzB,MAAM,mBAAmB;AAAA,EACvB,WAAW;AAAA,EACX,SAAS;AACX;AAEO,MAAM,eAAe,SAAS;AAC9B,MAAM,eAAe,SAAS;AAE9B,SAAS,kBACd,SACyC;AACzC,QAAM,QAAQ;AAAA,IACZ;AAAA,EAKF;AACA,MAAI,CAAC,MAAM,SAAS;AAClB,UAAM,UAAU;AAAA,MACd,WAAW;AAAA,MACX,KAAK,IAAI,SAAS,MAAM,OAAO;AAAA,MAC/B,UAAU,EAAE,MAAM,SAAS;AAAA,IAC7B;AAAA,EACF;AAEA,SAAO;AAAA,IACL,cAAc;AACZ,aAAO,MAAM,QAAQ;AAAA,IACvB;AAAA,IACA,WAAW;AACT,aAAO,MAAM,QAAQ,IAAI;AAAA,IAC3B;AAAA,IACA,OAAO;AAnEX;AAoEM,kBAAM,QAAQ,cAAd,mBAAyB;AACzB,YAAM,QAAQ,YAAY;AAAA,IAC5B;AAAA,IACA,SAAS,MAAc,EAAE,SAAS,OAAO,IAAI,EAAE,MAAM,SAAS,GAAG;AAvErE;AAwEM,YAAM,MAAM,MAAM,QAAQ;AAC1B,UAAI,SAAS,UAAU;AACrB,YAAI,SAAS,IAAI;AAAA,MACnB,WAAW,SAAS,UAAU;AAC5B,oBAAM,QAAQ,cAAd,mBAAyB;AACzB,cAAM,YAAY,SAAS,OAAO,KAAK;AAAA,UACrC,GAAG;AAAA,UACH,SAAS;AAAA,UACT,iBAAiB,CAAC;AAAA,QACpB,CAAC;AACD,kBAAU,MAAM;AAChB,cAAM,QAAQ,YAAY;AAAA,MAC5B,OAAO;AACL,oBAAM,QAAQ,cAAd,mBAAyB;AACzB,cAAM,YAAY,SAAS,OAAO,KAAK;AAAA,UACrC,GAAG;AAAA,UACH,SAAS;AAAA,UACT,iBAAiB,CAAC;AAAA,QACpB,CAAC;AACD,kBAAU,MAAM;AAChB,cAAM,QAAQ,YAAY;AAAA,MAC5B;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,0BACd,OACA,IACA;AACA,QAAM,WAAW,SAAS,CAAC,YAAY;AACrC,OAAG,QAAQ,KAAK;AAAA,EAClB,CAAC;AAED,YAAU,MAAM;AACd,UAAM,KAAK,MAAM,YAAY,EAAE,YAAY,QAAQ;AACnD,WAAO,MAAM;AACX,YAAM,YAAY,EAAE,eAAe,EAAE;AAAA,IACvC;AAAA,EACF,GAAG,CAAC,OAAO,QAAQ,CAAC;AACtB;AAEO,SAAS,uBACd,OACA,UACA;AACA,SAAO,SAAS,MAAM,YAAY,CAAC;AACrC;AAEO,SAAS,iBACd,YACoB;AACpB,eAAa,iBAAiB;AAC9B,eAAa,iBAAiB;AAE9B,SAAO;AAAA,IACL,eAAe;AAAA,IACf;AAAA,IACA,MAAM;AAAA,IACN,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,eAAe,CAAC,EAAE,OAAO,cAAc,OAAO,OAAO,SAAS,MAAM;AAClE,YAAM,aAAY,qCAAW,QAAO;AACpC,YAAM,mBAAmB,qCAAW;AACpC,YAAM,eAAe;AACrB,YAAM,gBAAgB,WAA2C,CAAC,CAAC;AACnE,YAAM,oBAAoB,WAAgD,CAAC,CAAC;AAC5E,YAAM,kBAAkB,WAQtB,IAAW;AACb,UAAI,CAAC,gBAAgB,SAAS;AAC5B,wBAAgB,UAAU,oBAAI,QAAQ;AAAA,MACxC;AAGA,YAAM,OAAO;AAAA,QACX,KAAK,UAAU,YAAY;AAAA,QAC3B,KAAK,UAAU,KAAK;AAAA,QACpB;AAAA,QACA,CAAC,CAAC;AAAA,MACJ;AAEA,YAAM,MAAM,QAAQ,MAAM;AAnKhC;AAoKQ,cAAM,UAAsB,CAAC;AAC7B,cAAM,cAA+B,CAAC;AAEtC,cAAM,mBAAmB,CAAC;AAC1B,mBAAW,OAAO,cAAc;AAC9B,gBAAM,MAAM,aAAa;AACzB,cAAI,CAAC,iBAAiB,MAAM;AAC1B,6BAAiB,OAAO;AACxB;AAAA,UACF;AACA,cAAI,QAAQ,aAAa;AACvB,0BAAc,QAAQ,OAAO,OAAO,KAAK,cAAc,QAAQ,MAAM,GAAG;AACxE;AAAA,UACF;AAGA,cAAI,CAAC;AAAK;AAEV,qBAAW,CAAC,OAAO,SAAS,KAAK,IAAI,QAAQ,GAAG;AAC9C,gBAAI,CAAC;AAAW;AAChB,kBAAM,OAAO,OAAO,KAAK,SAAS,EAAE;AACpC,kBAAM,oBAAmB,uBAAkB,QAAQ,WAA1B,mBAAmC;AAC5D,8BAAkB,QAAQ,SAAS;AAAA,cACjC,CAAC,OAAO,OAAO,MAAM,kBAAkB,UAAU,KAAK;AAAA,YACxD;AACA,8BAAkB,UAAU,CAAC,GAAG,kBAAkB,OAAO;AAAA,UAC3D;AAAA,QACF;AAEA,cAAM,gBAAgB;AAAA,UACpB,GAAG,OAAO;AAAA,YACR,OAAO,QAAQ;AAAA,cACb,GAAG,cAAc;AAAA,YACnB,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAG;AArM5B,kBAAAA;AAqM+B,sBAAC,KAAGA,MAAA,gBAAgB,QAAS,IAAI,CAAC,MAA9B,gBAAAA,IAAiC,mBAAkB,CAAC;AAAA,aAAC;AAAA,UAC9E;AAAA,UACA,WAAW,kBAAkB,QAAQ,IAAI,CAAC,MAAM;AAvM1D,gBAAAA;AAwMY,kBAAM,MAAM,OAAO,KAAK,CAAC,EAAE;AAC3B,kBAAM,QAAMA,MAAA,gBAAgB,QAAS,IAAI,EAAE,IAAI,MAAnC,gBAAAA,IAAsC,mBAAkB,EAAE;AACtE,mBAAO,EAAE,CAAC,MAAM,IAAI;AAAA,UACtB,CAAC;AAAA,QACH;AAEA,eAAO;AAAA,UACL;AAAA,UACA;AAAA,UACA,OAAO,CAAC,kBAAkB,aAAa;AAAA,QACzC;AAEA,iBAAS,OACP,KACA,UACA,OACA;AACA,gBAAM,CAAC,KAAK,IAAI,IAAI,SAAS,KAAK;AAClC,gBAAM,QAAQ,YAAY,IAAI,SAAS,MAAM,GAAG;AAGhD,cAAI,OAAO;AACT,gBAAI,YAAY,QAAQ,SAAS,WAAW;AAE1C,qBAAO;AAAA,YACT;AAAA,UACF;AAEA,cAAI;AACJ,cAAI,MAAM;AACR,kBAAM,mBAAmB,gBAAgB,QAAQ,IAAI,KAAK;AAC1D,8BAAkB;AAAA,eAChB,qDAAkB,YAAW,MAAM;AAAA,cACnC;AAAA,cACA;AAAA,YACF;AACA,4BAAgB,QAAS,IAAI,OAAO;AAAA,cAClC,gBAAgB,MAAM,YAAY,eAAe;AAAA,cACjD,SAAS;AAAA,YACX,CAAC;AAAA,UACH;AAEA,cAAI,OAAO;AACT,kBAAM,kBAAkB,mBAAmB,KAAK,YAAY,MAAM,SAAS;AAE3E,gBAAI;AACJ,kBAAM,UAAU,IAAI,QAAc,CAACC,SAAQ;AACzC,wBAAUA;AAAA,YACZ,CAAC;AACD,wBAAY,KAAK,OAAO;AAExB,oBAAQ,KAAK,MAAM;AACjB,oBAAM,cAAc;AACpB,uBAAS,OAAO,OAAO;AAAA,gBACrB,SAAS;AAAA,gBACT,iBAAiB,CAAC;AAAA,gBAClB,GAAG;AAAA,cACL,CAAC,EAAE,MAAM,CAAC,EAAE,SAAS,MAAM;AACzB,oBAAI,UAAU;AACZ,0BAAQ;AAAA,gBACV;AAAA,cACF,CAAC;AAAA,YACH,CAAC;AAAA,UACH;AAEA,cAAI,QAAQ,IAAI,aAAa,eAAe;AAC1C,gBAAI,MAAM,UAAU;AAGlB,sBAAQ,IAAI,sBAAc,KAAI,QAAQ,MAAM,gBAAe,OAAM,IAAI,QAAO,QAAO,MAAK,eAAc,eAAe;AAAA,YACvH;AAAA,UACF;AACA,iBAAO;AAAA,QACT;AAAA,MAEF,GAAG,IAAI;AAEP,gCAA0B,MAAM;AAC9B,YAAI,QAAQ,QAAQ,CAAC,MAAM,EAAE,CAAC;AAC9B,YAAI,SAAS;AACb,gBAAQ,IAAI,IAAI,WAAW,EAAE,KAAK,MAAM;AACtC,cAAI;AAAQ;AACZ;AACA,cAAI,WAAW;AACb;AAAA,UACF;AAAA,QACF,CAAC;AACD,eAAO,MAAM;AACX,mBAAS;AAAA,QACX;AAAA,MACF,GAAG,IAAI;AAEP,UAAI,QAAQ,IAAI,aAAa,eAAe;AAC1C,YAAI,MAAM,UAAU;AAElB,kBAAQ,IAAI,sBAAsB,GAAG;AAAA,QACvC;AAAA,MACF;AAEA,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAEA,SAAS,gBAAgB,SAAiB,MAAc,UAAU,OAAO;AACvE,MAAI,SAAS,SAAS;AACpB,cAAU,OAAO;AAAA,EACnB;AACA,QAAM,aAAa,CAAC,SAAS,IAAI;AACjC,QAAM,cAAc,CAAC,GAAG,UAAU,WAAW,GAAG,OAAO,SAAS;AAChE,MAAI,OAAO,SAAS;AAClB,eAAW,QAAQ;AACnB,gBAAY,QAAQ;AAAA,EACtB;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,mBACP,KACA,YACA,WACA;AACA,MAAI,OAAO,cAAc,UAAU;AACjC,WAAO,WAAW;AAAA,EACpB;AACA,MAAI,OAAO;AACX,MAAI;AACJ,MAAI,MAAM,QAAQ,SAAS,GAAG;AAC5B,WAAO,UAAU;AACjB,UAAM,OAAO,UAAU,MAAM,UAAU,GAAG;AAC1C,QAAI,MAAM;AACR,UAAI,OAAO,SAAS,UAAU;AAC5B,eAAO;AAAA,MACT,OAAO;AACL,eAAQ,KAAa,QAAQ;AAC7B,oBAAY;AAAA,MACd;AAAA,IACF;AAAA,EACF,OAAO;AACL,UAAM,MAAM,uCAAY;AACxB,WAAO,2BAAK;AACZ,gBAAY;AAAA,EACd;AACA,QAAM,QAAQ,WAAW;AACzB,MAAI,CAAC,OAAO;AACV,UAAM,IAAI,MAAM,yBAAyB,kBAAkB,MAAM;AAAA,EACnE;AACA,SAAO;AAAA,IACL,GAAG;AAAA,IACH,GAAG;AAAA,EACL;AACF;AAEA,SAAS,SAAS,OAAwB;AACxC,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO,CAAC,KAAK;AAAA,EACf;AACA,QAAM,CAAC,GAAG,QAAQ,KAAK,IAAI,MAAM,MAAM,qBAAqB,KAAK,CAAC;AAClE,SAAO,CAAC,CAAC,QAAQ,KAAK;AACxB;",
|
|
6
6
|
"names": ["_a", "res"]
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tamagui/animations-react-native",
|
|
3
|
-
"version": "1.0.1
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"source": "src/index.ts",
|
|
5
5
|
"sideEffects": [
|
|
6
6
|
"./polyfill.js"
|
|
@@ -15,18 +15,18 @@
|
|
|
15
15
|
"dist"
|
|
16
16
|
],
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@tamagui/core": "^1.0.1
|
|
19
|
-
"@tamagui/use-presence": "^1.0.1
|
|
18
|
+
"@tamagui/core": "^1.0.1",
|
|
19
|
+
"@tamagui/use-presence": "^1.0.1"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
|
-
"@tamagui/build": "^1.0.1
|
|
22
|
+
"@tamagui/build": "^1.0.1",
|
|
23
23
|
"react": "^18.2.0",
|
|
24
24
|
"react-dom": "^18.2.0",
|
|
25
25
|
"react-native": "*"
|
|
26
26
|
},
|
|
27
27
|
"peerDependencies": {
|
|
28
|
-
"react": "
|
|
29
|
-
"react-dom": "
|
|
28
|
+
"react": "*",
|
|
29
|
+
"react-dom": "*",
|
|
30
30
|
"react-native": "*"
|
|
31
31
|
},
|
|
32
32
|
"scripts": {
|
package/src/createAnimations.tsx
CHANGED
|
@@ -153,9 +153,6 @@ export function createAnimations<A extends AnimationsConfig>(
|
|
|
153
153
|
animationsState.current = new WeakMap()
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
-
const runners: Function[] = []
|
|
157
|
-
const completions: Promise<void>[] = []
|
|
158
|
-
|
|
159
156
|
// const args = [JSON.stringify(mergedStyles)]
|
|
160
157
|
const args = [
|
|
161
158
|
JSON.stringify(mergedStyles),
|
|
@@ -165,6 +162,9 @@ export function createAnimations<A extends AnimationsConfig>(
|
|
|
165
162
|
]
|
|
166
163
|
|
|
167
164
|
const res = useMemo(() => {
|
|
165
|
+
const runners: Function[] = []
|
|
166
|
+
const completions: Promise<void>[] = []
|
|
167
|
+
|
|
168
168
|
const nonAnimatedStyle = {}
|
|
169
169
|
for (const key in mergedStyles) {
|
|
170
170
|
const val = mergedStyles[key]
|
|
@@ -179,6 +179,7 @@ export function createAnimations<A extends AnimationsConfig>(
|
|
|
179
179
|
// key: 'transform'
|
|
180
180
|
// for now just support one transform key
|
|
181
181
|
if (!val) continue
|
|
182
|
+
|
|
182
183
|
for (const [index, transform] of val.entries()) {
|
|
183
184
|
if (!transform) continue
|
|
184
185
|
const tkey = Object.keys(transform)[0]
|
|
@@ -204,6 +205,8 @@ export function createAnimations<A extends AnimationsConfig>(
|
|
|
204
205
|
}
|
|
205
206
|
|
|
206
207
|
return {
|
|
208
|
+
runners,
|
|
209
|
+
completions,
|
|
207
210
|
style: [nonAnimatedStyle, animatedStyle],
|
|
208
211
|
}
|
|
209
212
|
|
|
@@ -214,6 +217,15 @@ export function createAnimations<A extends AnimationsConfig>(
|
|
|
214
217
|
) {
|
|
215
218
|
const [val, type] = getValue(valIn)
|
|
216
219
|
const value = animated || new Animated.Value(val)
|
|
220
|
+
|
|
221
|
+
// this optimization seems to work for web but not native...
|
|
222
|
+
if (isWeb) {
|
|
223
|
+
if (animated && val === animated['_value']) {
|
|
224
|
+
// avoid running again for same value
|
|
225
|
+
return value
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
217
229
|
let interpolateArgs: any
|
|
218
230
|
if (type) {
|
|
219
231
|
const curInterpolation = animationsState.current.get(value)
|
|
@@ -227,6 +239,7 @@ export function createAnimations<A extends AnimationsConfig>(
|
|
|
227
239
|
current: val,
|
|
228
240
|
})
|
|
229
241
|
}
|
|
242
|
+
|
|
230
243
|
if (value) {
|
|
231
244
|
const animationConfig = getAnimationConfig(key, animations, props.animation)
|
|
232
245
|
|
|
@@ -249,20 +262,12 @@ export function createAnimations<A extends AnimationsConfig>(
|
|
|
249
262
|
})
|
|
250
263
|
})
|
|
251
264
|
}
|
|
265
|
+
|
|
252
266
|
if (process.env.NODE_ENV === 'development') {
|
|
253
267
|
if (props['debug']) {
|
|
254
268
|
// eslint-disable-next-line no-console
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
key,
|
|
258
|
-
`from ${value['_value']} to`,
|
|
259
|
-
valIn,
|
|
260
|
-
`(${val})`,
|
|
261
|
-
'type',
|
|
262
|
-
type,
|
|
263
|
-
'interpolate',
|
|
264
|
-
interpolateArgs
|
|
265
|
-
)
|
|
269
|
+
// prettier-ignore
|
|
270
|
+
console.log(' 💠 animate',key,`from ${value['_value']} to`,valIn,`(${val})`,'type',type,'interpolate',interpolateArgs)
|
|
266
271
|
}
|
|
267
272
|
}
|
|
268
273
|
return value
|
|
@@ -271,9 +276,9 @@ export function createAnimations<A extends AnimationsConfig>(
|
|
|
271
276
|
}, args)
|
|
272
277
|
|
|
273
278
|
useIsomorphicLayoutEffect(() => {
|
|
274
|
-
runners.forEach((r) => r())
|
|
279
|
+
res.runners.forEach((r) => r())
|
|
275
280
|
let cancel = false
|
|
276
|
-
Promise.all(completions).then(() => {
|
|
281
|
+
Promise.all(res.completions).then(() => {
|
|
277
282
|
if (cancel) return
|
|
278
283
|
onDidAnimate?.()
|
|
279
284
|
if (isExiting) {
|