@tamagui/animations-react-native 1.0.1-rc.9 → 1.0.2

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": "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",
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": "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",
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
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tamagui/animations-react-native",
3
- "version": "1.0.1-rc.9",
3
+ "version": "1.0.2",
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-rc.9",
19
- "@tamagui/use-presence": "^1.0.1-rc.9"
18
+ "@tamagui/core": "^1.0.2",
19
+ "@tamagui/use-presence": "^1.0.2"
20
20
  },
21
21
  "devDependencies": {
22
- "@tamagui/build": "^1.0.1-rc.9",
22
+ "@tamagui/build": "^1.0.2",
23
23
  "react": "^18.2.0",
24
24
  "react-dom": "^18.2.0",
25
25
  "react-native": "*"
26
26
  },
27
27
  "peerDependencies": {
28
- "react": "^18.2.0",
29
- "react-dom": "^18.2.0",
28
+ "react": "*",
29
+ "react-dom": "*",
30
30
  "react-native": "*"
31
31
  },
32
32
  "scripts": {
@@ -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
- console.log(
256
- ' 💠 animate',
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) {