@tamagui/animations-react-native 1.0.1-beta.190 → 1.0.1-beta.191

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.
@@ -143,6 +143,11 @@ function createAnimations(animations) {
143
143
  });
144
144
  completions.push(promise);
145
145
  runners.push(() => {
146
+ if (animated["_value"] === val) {
147
+ resolve();
148
+ return;
149
+ }
150
+ animated.stopAnimation();
146
151
  import_react_native.Animated.spring(animated, {
147
152
  toValue: val,
148
153
  useNativeDriver: !import_core.isWeb,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/createAnimations.tsx"],
4
- "sourcesContent": ["import { PresenceContext, usePresence } from '@tamagui/animate-presence'\nimport {\n AnimatedNumberStrategy,\n AnimationDriver,\n AnimationProp,\n UniversalAnimatedNumber,\n isWeb,\n useEvent,\n useIsomorphicLayoutEffect,\n} from '@tamagui/core'\nimport { useContext, useEffect, useMemo, useRef } 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(initial: number): UniversalAnimatedNumber<Animated.Value> {\n const state = useRef(\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>(animations: A): AnimationDriver<A> {\n AnimatedView['displayName'] = 'AnimatedView'\n AnimatedText['displayName'] = 'AnimatedText'\n\n return {\n avoidClasses: true,\n animations,\n View: AnimatedView,\n Text: AnimatedText,\n useAnimatedNumber,\n useAnimatedNumberReaction,\n useAnimatedNumberStyle,\n useAnimations: (props, helpers) => {\n const { onDidAnimate, delay, getStyle, state } = helpers\n const [isPresent, sendExitComplete] = usePresence()\n const presence = useContext(PresenceContext)\n\n // const exitStyle = presence?.exitVariant\n // ? staticConfig.variantsParsed?.[presence.exitVariant]?.true || pseudos.exitStyle\n // : pseudos.exitStyle\n\n const isExiting = isPresent === false\n const isEntering = !state.mounted\n\n const all = getStyle({\n isExiting,\n isEntering,\n exitVariant: presence?.exitVariant,\n enterVariant: presence?.enterVariant,\n })\n\n const animateStyles = useRef<Record<string, Animated.Value>>({})\n const animatedTranforms = useRef<{ [key: string]: Animated.Value }[]>([])\n const interpolations = useRef(new WeakMap<Animated.Value, Animated.AnimatedInterpolation>())\n\n // TODO loop and create values, run them if they change\n\n const runners: Function[] = []\n const completions: Promise<void>[] = []\n\n function update(key: string, animated: Animated.Value | undefined, valIn: string | number) {\n const [val, type] = getValue(valIn)\n const value = animated || new Animated.Value(val)\n if (type) {\n interpolations.current.set(value, getInterpolated(value, type, val))\n }\n if (animated) {\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 Animated.spring(animated, {\n toValue: val,\n useNativeDriver: !isWeb,\n ...animationConfig,\n }).start(({ finished }) => {\n if (finished) {\n resolve()\n }\n })\n })\n }\n return value\n }\n\n function getValue(input: number | string) {\n if (typeof input !== 'string') {\n return [input] as const\n }\n const neg = input[0] === '-'\n if (neg) input = input.slice(1)\n const [_, number, after] = input.match(/([-0-9]+)(deg|%)/) ?? []\n return [+number * (neg ? -1 : 1), after] as const\n }\n\n const nonAnimatedStyle = {}\n for (const key in all) {\n const val = all[key]\n if (animatedStyleKey[key]) {\n if (key === 'transform') {\n // for now just support one transform key\n if (val) {\n for (const [index, transform] of val.entries()) {\n if (!transform) continue\n const tkey = Object.keys(transform)[0]\n animatedTranforms.current[index] = {\n [tkey]: update(tkey, animatedTranforms.current[index]?.[tkey], transform[tkey]),\n }\n }\n }\n } else {\n animateStyles.current[key] = update(key, animateStyles.current[key], val)\n }\n } else {\n nonAnimatedStyle[key] = val\n }\n }\n\n const animatedStyle = {\n ...Object.fromEntries(\n Object.entries({\n ...animateStyles.current,\n }).map(([k, v]) => [k, interpolations.current.get(v) || v])\n ),\n transform: animatedTranforms.current.map((r) => {\n const key = Object.keys(r)[0]\n const val = interpolations.current.get(r[key]) || r[key]\n return { [key]: val }\n }),\n }\n\n const args = [\n JSON.stringify(all),\n state.mounted,\n state.hover,\n state.press,\n state.pressIn,\n state.focus,\n delay,\n isPresent,\n onDidAnimate,\n presence?.exitVariant,\n presence?.enterVariant,\n ]\n\n useIsomorphicLayoutEffect(() => {\n //\n for (const runner of runners) {\n runner()\n }\n Promise.all(completions).then(() => {\n onDidAnimate?.()\n if (isExiting) {\n sendExitComplete?.()\n }\n })\n }, args)\n\n return useMemo(() => {\n return {\n style: [nonAnimatedStyle, animatedStyle],\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, args)\n },\n }\n}\n\nfunction getInterpolated(val: Animated.Value, postfix: string, next: number) {\n const cur = val['_value'] as number\n const inputRange = [cur, next]\n const outputRange = [`${cur}deg`, `${next}deg`]\n if (next < cur) {\n inputRange.reverse()\n outputRange.reverse()\n }\n return val.interpolate({\n inputRange,\n outputRange,\n })\n}\n\nfunction getAnimationConfig(key: string, animations: AnimationsConfig, animation?: AnimationProp) {\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"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { PresenceContext, usePresence } from '@tamagui/animate-presence'\nimport {\n AnimatedNumberStrategy,\n AnimationDriver,\n AnimationProp,\n UniversalAnimatedNumber,\n isWeb,\n useEvent,\n useIsomorphicLayoutEffect,\n} from '@tamagui/core'\nimport { useContext, useEffect, useMemo, useRef } 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(initial: number): UniversalAnimatedNumber<Animated.Value> {\n const state = useRef(\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>(animations: A): AnimationDriver<A> {\n AnimatedView['displayName'] = 'AnimatedView'\n AnimatedText['displayName'] = 'AnimatedText'\n\n return {\n avoidClasses: true,\n animations,\n View: AnimatedView,\n Text: AnimatedText,\n useAnimatedNumber,\n useAnimatedNumberReaction,\n useAnimatedNumberStyle,\n useAnimations: (props, helpers) => {\n const { onDidAnimate, delay, getStyle, state } = helpers\n const [isPresent, sendExitComplete] = usePresence()\n const presence = useContext(PresenceContext)\n\n // const exitStyle = presence?.exitVariant\n // ? staticConfig.variantsParsed?.[presence.exitVariant]?.true || pseudos.exitStyle\n // : pseudos.exitStyle\n\n const isExiting = isPresent === false\n const isEntering = !state.mounted\n\n const all = getStyle({\n isExiting,\n isEntering,\n exitVariant: presence?.exitVariant,\n enterVariant: presence?.enterVariant,\n })\n\n const animateStyles = useRef<Record<string, Animated.Value>>({})\n const animatedTranforms = useRef<{ [key: string]: Animated.Value }[]>([])\n const interpolations = useRef(new WeakMap<Animated.Value, Animated.AnimatedInterpolation>())\n\n // TODO loop and create values, run them if they change\n\n const runners: Function[] = []\n const completions: Promise<void>[] = []\n\n function update(key: string, animated: Animated.Value | undefined, valIn: string | number) {\n const [val, type] = getValue(valIn)\n const value = animated || new Animated.Value(val)\n if (type) {\n interpolations.current.set(value, getInterpolated(value, type, val))\n }\n if (animated) {\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 if (animated['_value'] === val) {\n resolve()\n // avoid update when its the same\n return\n }\n animated.stopAnimation()\n Animated.spring(animated, {\n toValue: val,\n useNativeDriver: !isWeb,\n ...animationConfig,\n }).start(({ finished }) => {\n if (finished) {\n resolve()\n }\n })\n })\n }\n return value\n }\n\n function getValue(input: number | string) {\n if (typeof input !== 'string') {\n return [input] as const\n }\n const neg = input[0] === '-'\n if (neg) input = input.slice(1)\n const [_, number, after] = input.match(/([-0-9]+)(deg|%)/) ?? []\n return [+number * (neg ? -1 : 1), after] as const\n }\n\n const nonAnimatedStyle = {}\n for (const key in all) {\n const val = all[key]\n if (animatedStyleKey[key]) {\n if (key === 'transform') {\n // for now just support one transform key\n if (val) {\n for (const [index, transform] of val.entries()) {\n if (!transform) continue\n const tkey = Object.keys(transform)[0]\n animatedTranforms.current[index] = {\n [tkey]: update(tkey, animatedTranforms.current[index]?.[tkey], transform[tkey]),\n }\n }\n }\n } else {\n animateStyles.current[key] = update(key, animateStyles.current[key], val)\n }\n } else {\n nonAnimatedStyle[key] = val\n }\n }\n\n const animatedStyle = {\n ...Object.fromEntries(\n Object.entries({\n ...animateStyles.current,\n }).map(([k, v]) => [k, interpolations.current.get(v) || v])\n ),\n transform: animatedTranforms.current.map((r) => {\n const key = Object.keys(r)[0]\n const val = interpolations.current.get(r[key]) || r[key]\n return { [key]: val }\n }),\n }\n\n const args = [\n JSON.stringify(all),\n state.mounted,\n state.hover,\n state.press,\n state.pressIn,\n state.focus,\n delay,\n isPresent,\n onDidAnimate,\n presence?.exitVariant,\n presence?.enterVariant,\n ]\n\n useIsomorphicLayoutEffect(() => {\n //\n for (const runner of runners) {\n runner()\n }\n Promise.all(completions).then(() => {\n onDidAnimate?.()\n if (isExiting) {\n sendExitComplete?.()\n }\n })\n }, args)\n\n return useMemo(() => {\n return {\n style: [nonAnimatedStyle, animatedStyle],\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, args)\n },\n }\n}\n\nfunction getInterpolated(val: Animated.Value, postfix: string, next: number) {\n const cur = val['_value'] as number\n const inputRange = [cur, next]\n const outputRange = [`${cur}deg`, `${next}deg`]\n if (next < cur) {\n inputRange.reverse()\n outputRange.reverse()\n }\n return val.interpolate({\n inputRange,\n outputRange,\n })\n}\n\nfunction getAnimationConfig(key: string, animations: AnimationsConfig, animation?: AnimationProp) {\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"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -119,6 +119,11 @@ function createAnimations(animations) {
119
119
  });
120
120
  completions.push(promise);
121
121
  runners.push(() => {
122
+ if (animated["_value"] === val) {
123
+ resolve();
124
+ return;
125
+ }
126
+ animated.stopAnimation();
122
127
  Animated.spring(animated, {
123
128
  toValue: val,
124
129
  useNativeDriver: !isWeb,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/createAnimations.tsx"],
4
- "sourcesContent": ["import { PresenceContext, usePresence } from '@tamagui/animate-presence'\nimport {\n AnimatedNumberStrategy,\n AnimationDriver,\n AnimationProp,\n UniversalAnimatedNumber,\n isWeb,\n useEvent,\n useIsomorphicLayoutEffect,\n} from '@tamagui/core'\nimport { useContext, useEffect, useMemo, useRef } 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(initial: number): UniversalAnimatedNumber<Animated.Value> {\n const state = useRef(\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>(animations: A): AnimationDriver<A> {\n AnimatedView['displayName'] = 'AnimatedView'\n AnimatedText['displayName'] = 'AnimatedText'\n\n return {\n avoidClasses: true,\n animations,\n View: AnimatedView,\n Text: AnimatedText,\n useAnimatedNumber,\n useAnimatedNumberReaction,\n useAnimatedNumberStyle,\n useAnimations: (props, helpers) => {\n const { onDidAnimate, delay, getStyle, state } = helpers\n const [isPresent, sendExitComplete] = usePresence()\n const presence = useContext(PresenceContext)\n\n // const exitStyle = presence?.exitVariant\n // ? staticConfig.variantsParsed?.[presence.exitVariant]?.true || pseudos.exitStyle\n // : pseudos.exitStyle\n\n const isExiting = isPresent === false\n const isEntering = !state.mounted\n\n const all = getStyle({\n isExiting,\n isEntering,\n exitVariant: presence?.exitVariant,\n enterVariant: presence?.enterVariant,\n })\n\n const animateStyles = useRef<Record<string, Animated.Value>>({})\n const animatedTranforms = useRef<{ [key: string]: Animated.Value }[]>([])\n const interpolations = useRef(new WeakMap<Animated.Value, Animated.AnimatedInterpolation>())\n\n // TODO loop and create values, run them if they change\n\n const runners: Function[] = []\n const completions: Promise<void>[] = []\n\n function update(key: string, animated: Animated.Value | undefined, valIn: string | number) {\n const [val, type] = getValue(valIn)\n const value = animated || new Animated.Value(val)\n if (type) {\n interpolations.current.set(value, getInterpolated(value, type, val))\n }\n if (animated) {\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 Animated.spring(animated, {\n toValue: val,\n useNativeDriver: !isWeb,\n ...animationConfig,\n }).start(({ finished }) => {\n if (finished) {\n resolve()\n }\n })\n })\n }\n return value\n }\n\n function getValue(input: number | string) {\n if (typeof input !== 'string') {\n return [input] as const\n }\n const neg = input[0] === '-'\n if (neg) input = input.slice(1)\n const [_, number, after] = input.match(/([-0-9]+)(deg|%)/) ?? []\n return [+number * (neg ? -1 : 1), after] as const\n }\n\n const nonAnimatedStyle = {}\n for (const key in all) {\n const val = all[key]\n if (animatedStyleKey[key]) {\n if (key === 'transform') {\n // for now just support one transform key\n if (val) {\n for (const [index, transform] of val.entries()) {\n if (!transform) continue\n const tkey = Object.keys(transform)[0]\n animatedTranforms.current[index] = {\n [tkey]: update(tkey, animatedTranforms.current[index]?.[tkey], transform[tkey]),\n }\n }\n }\n } else {\n animateStyles.current[key] = update(key, animateStyles.current[key], val)\n }\n } else {\n nonAnimatedStyle[key] = val\n }\n }\n\n const animatedStyle = {\n ...Object.fromEntries(\n Object.entries({\n ...animateStyles.current,\n }).map(([k, v]) => [k, interpolations.current.get(v) || v])\n ),\n transform: animatedTranforms.current.map((r) => {\n const key = Object.keys(r)[0]\n const val = interpolations.current.get(r[key]) || r[key]\n return { [key]: val }\n }),\n }\n\n const args = [\n JSON.stringify(all),\n state.mounted,\n state.hover,\n state.press,\n state.pressIn,\n state.focus,\n delay,\n isPresent,\n onDidAnimate,\n presence?.exitVariant,\n presence?.enterVariant,\n ]\n\n useIsomorphicLayoutEffect(() => {\n //\n for (const runner of runners) {\n runner()\n }\n Promise.all(completions).then(() => {\n onDidAnimate?.()\n if (isExiting) {\n sendExitComplete?.()\n }\n })\n }, args)\n\n return useMemo(() => {\n return {\n style: [nonAnimatedStyle, animatedStyle],\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, args)\n },\n }\n}\n\nfunction getInterpolated(val: Animated.Value, postfix: string, next: number) {\n const cur = val['_value'] as number\n const inputRange = [cur, next]\n const outputRange = [`${cur}deg`, `${next}deg`]\n if (next < cur) {\n inputRange.reverse()\n outputRange.reverse()\n }\n return val.interpolate({\n inputRange,\n outputRange,\n })\n}\n\nfunction getAnimationConfig(key: string, animations: AnimationsConfig, animation?: AnimationProp) {\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"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { PresenceContext, usePresence } from '@tamagui/animate-presence'\nimport {\n AnimatedNumberStrategy,\n AnimationDriver,\n AnimationProp,\n UniversalAnimatedNumber,\n isWeb,\n useEvent,\n useIsomorphicLayoutEffect,\n} from '@tamagui/core'\nimport { useContext, useEffect, useMemo, useRef } 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(initial: number): UniversalAnimatedNumber<Animated.Value> {\n const state = useRef(\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>(animations: A): AnimationDriver<A> {\n AnimatedView['displayName'] = 'AnimatedView'\n AnimatedText['displayName'] = 'AnimatedText'\n\n return {\n avoidClasses: true,\n animations,\n View: AnimatedView,\n Text: AnimatedText,\n useAnimatedNumber,\n useAnimatedNumberReaction,\n useAnimatedNumberStyle,\n useAnimations: (props, helpers) => {\n const { onDidAnimate, delay, getStyle, state } = helpers\n const [isPresent, sendExitComplete] = usePresence()\n const presence = useContext(PresenceContext)\n\n // const exitStyle = presence?.exitVariant\n // ? staticConfig.variantsParsed?.[presence.exitVariant]?.true || pseudos.exitStyle\n // : pseudos.exitStyle\n\n const isExiting = isPresent === false\n const isEntering = !state.mounted\n\n const all = getStyle({\n isExiting,\n isEntering,\n exitVariant: presence?.exitVariant,\n enterVariant: presence?.enterVariant,\n })\n\n const animateStyles = useRef<Record<string, Animated.Value>>({})\n const animatedTranforms = useRef<{ [key: string]: Animated.Value }[]>([])\n const interpolations = useRef(new WeakMap<Animated.Value, Animated.AnimatedInterpolation>())\n\n // TODO loop and create values, run them if they change\n\n const runners: Function[] = []\n const completions: Promise<void>[] = []\n\n function update(key: string, animated: Animated.Value | undefined, valIn: string | number) {\n const [val, type] = getValue(valIn)\n const value = animated || new Animated.Value(val)\n if (type) {\n interpolations.current.set(value, getInterpolated(value, type, val))\n }\n if (animated) {\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 if (animated['_value'] === val) {\n resolve()\n // avoid update when its the same\n return\n }\n animated.stopAnimation()\n Animated.spring(animated, {\n toValue: val,\n useNativeDriver: !isWeb,\n ...animationConfig,\n }).start(({ finished }) => {\n if (finished) {\n resolve()\n }\n })\n })\n }\n return value\n }\n\n function getValue(input: number | string) {\n if (typeof input !== 'string') {\n return [input] as const\n }\n const neg = input[0] === '-'\n if (neg) input = input.slice(1)\n const [_, number, after] = input.match(/([-0-9]+)(deg|%)/) ?? []\n return [+number * (neg ? -1 : 1), after] as const\n }\n\n const nonAnimatedStyle = {}\n for (const key in all) {\n const val = all[key]\n if (animatedStyleKey[key]) {\n if (key === 'transform') {\n // for now just support one transform key\n if (val) {\n for (const [index, transform] of val.entries()) {\n if (!transform) continue\n const tkey = Object.keys(transform)[0]\n animatedTranforms.current[index] = {\n [tkey]: update(tkey, animatedTranforms.current[index]?.[tkey], transform[tkey]),\n }\n }\n }\n } else {\n animateStyles.current[key] = update(key, animateStyles.current[key], val)\n }\n } else {\n nonAnimatedStyle[key] = val\n }\n }\n\n const animatedStyle = {\n ...Object.fromEntries(\n Object.entries({\n ...animateStyles.current,\n }).map(([k, v]) => [k, interpolations.current.get(v) || v])\n ),\n transform: animatedTranforms.current.map((r) => {\n const key = Object.keys(r)[0]\n const val = interpolations.current.get(r[key]) || r[key]\n return { [key]: val }\n }),\n }\n\n const args = [\n JSON.stringify(all),\n state.mounted,\n state.hover,\n state.press,\n state.pressIn,\n state.focus,\n delay,\n isPresent,\n onDidAnimate,\n presence?.exitVariant,\n presence?.enterVariant,\n ]\n\n useIsomorphicLayoutEffect(() => {\n //\n for (const runner of runners) {\n runner()\n }\n Promise.all(completions).then(() => {\n onDidAnimate?.()\n if (isExiting) {\n sendExitComplete?.()\n }\n })\n }, args)\n\n return useMemo(() => {\n return {\n style: [nonAnimatedStyle, animatedStyle],\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, args)\n },\n }\n}\n\nfunction getInterpolated(val: Animated.Value, postfix: string, next: number) {\n const cur = val['_value'] as number\n const inputRange = [cur, next]\n const outputRange = [`${cur}deg`, `${next}deg`]\n if (next < cur) {\n inputRange.reverse()\n outputRange.reverse()\n }\n return val.interpolate({\n inputRange,\n outputRange,\n })\n}\n\nfunction getAnimationConfig(key: string, animations: AnimationsConfig, animation?: AnimationProp) {\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"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -116,6 +116,11 @@ function createAnimations(animations) {
116
116
  });
117
117
  completions.push(promise);
118
118
  runners.push(() => {
119
+ if (animated["_value"] === val) {
120
+ resolve();
121
+ return;
122
+ }
123
+ animated.stopAnimation();
119
124
  Animated.spring(animated, {
120
125
  toValue: val,
121
126
  useNativeDriver: !isWeb,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/createAnimations.tsx"],
4
- "sourcesContent": ["import { PresenceContext, usePresence } from '@tamagui/animate-presence'\nimport {\n AnimatedNumberStrategy,\n AnimationDriver,\n AnimationProp,\n UniversalAnimatedNumber,\n isWeb,\n useEvent,\n useIsomorphicLayoutEffect,\n} from '@tamagui/core'\nimport { useContext, useEffect, useMemo, useRef } 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(initial: number): UniversalAnimatedNumber<Animated.Value> {\n const state = useRef(\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>(animations: A): AnimationDriver<A> {\n AnimatedView['displayName'] = 'AnimatedView'\n AnimatedText['displayName'] = 'AnimatedText'\n\n return {\n avoidClasses: true,\n animations,\n View: AnimatedView,\n Text: AnimatedText,\n useAnimatedNumber,\n useAnimatedNumberReaction,\n useAnimatedNumberStyle,\n useAnimations: (props, helpers) => {\n const { onDidAnimate, delay, getStyle, state } = helpers\n const [isPresent, sendExitComplete] = usePresence()\n const presence = useContext(PresenceContext)\n\n // const exitStyle = presence?.exitVariant\n // ? staticConfig.variantsParsed?.[presence.exitVariant]?.true || pseudos.exitStyle\n // : pseudos.exitStyle\n\n const isExiting = isPresent === false\n const isEntering = !state.mounted\n\n const all = getStyle({\n isExiting,\n isEntering,\n exitVariant: presence?.exitVariant,\n enterVariant: presence?.enterVariant,\n })\n\n const animateStyles = useRef<Record<string, Animated.Value>>({})\n const animatedTranforms = useRef<{ [key: string]: Animated.Value }[]>([])\n const interpolations = useRef(new WeakMap<Animated.Value, Animated.AnimatedInterpolation>())\n\n // TODO loop and create values, run them if they change\n\n const runners: Function[] = []\n const completions: Promise<void>[] = []\n\n function update(key: string, animated: Animated.Value | undefined, valIn: string | number) {\n const [val, type] = getValue(valIn)\n const value = animated || new Animated.Value(val)\n if (type) {\n interpolations.current.set(value, getInterpolated(value, type, val))\n }\n if (animated) {\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 Animated.spring(animated, {\n toValue: val,\n useNativeDriver: !isWeb,\n ...animationConfig,\n }).start(({ finished }) => {\n if (finished) {\n resolve()\n }\n })\n })\n }\n return value\n }\n\n function getValue(input: number | string) {\n if (typeof input !== 'string') {\n return [input] as const\n }\n const neg = input[0] === '-'\n if (neg) input = input.slice(1)\n const [_, number, after] = input.match(/([-0-9]+)(deg|%)/) ?? []\n return [+number * (neg ? -1 : 1), after] as const\n }\n\n const nonAnimatedStyle = {}\n for (const key in all) {\n const val = all[key]\n if (animatedStyleKey[key]) {\n if (key === 'transform') {\n // for now just support one transform key\n if (val) {\n for (const [index, transform] of val.entries()) {\n if (!transform) continue\n const tkey = Object.keys(transform)[0]\n animatedTranforms.current[index] = {\n [tkey]: update(tkey, animatedTranforms.current[index]?.[tkey], transform[tkey]),\n }\n }\n }\n } else {\n animateStyles.current[key] = update(key, animateStyles.current[key], val)\n }\n } else {\n nonAnimatedStyle[key] = val\n }\n }\n\n const animatedStyle = {\n ...Object.fromEntries(\n Object.entries({\n ...animateStyles.current,\n }).map(([k, v]) => [k, interpolations.current.get(v) || v])\n ),\n transform: animatedTranforms.current.map((r) => {\n const key = Object.keys(r)[0]\n const val = interpolations.current.get(r[key]) || r[key]\n return { [key]: val }\n }),\n }\n\n const args = [\n JSON.stringify(all),\n state.mounted,\n state.hover,\n state.press,\n state.pressIn,\n state.focus,\n delay,\n isPresent,\n onDidAnimate,\n presence?.exitVariant,\n presence?.enterVariant,\n ]\n\n useIsomorphicLayoutEffect(() => {\n //\n for (const runner of runners) {\n runner()\n }\n Promise.all(completions).then(() => {\n onDidAnimate?.()\n if (isExiting) {\n sendExitComplete?.()\n }\n })\n }, args)\n\n return useMemo(() => {\n return {\n style: [nonAnimatedStyle, animatedStyle],\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, args)\n },\n }\n}\n\nfunction getInterpolated(val: Animated.Value, postfix: string, next: number) {\n const cur = val['_value'] as number\n const inputRange = [cur, next]\n const outputRange = [`${cur}deg`, `${next}deg`]\n if (next < cur) {\n inputRange.reverse()\n outputRange.reverse()\n }\n return val.interpolate({\n inputRange,\n outputRange,\n })\n}\n\nfunction getAnimationConfig(key: string, animations: AnimationsConfig, animation?: AnimationProp) {\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"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { PresenceContext, usePresence } from '@tamagui/animate-presence'\nimport {\n AnimatedNumberStrategy,\n AnimationDriver,\n AnimationProp,\n UniversalAnimatedNumber,\n isWeb,\n useEvent,\n useIsomorphicLayoutEffect,\n} from '@tamagui/core'\nimport { useContext, useEffect, useMemo, useRef } 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(initial: number): UniversalAnimatedNumber<Animated.Value> {\n const state = useRef(\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>(animations: A): AnimationDriver<A> {\n AnimatedView['displayName'] = 'AnimatedView'\n AnimatedText['displayName'] = 'AnimatedText'\n\n return {\n avoidClasses: true,\n animations,\n View: AnimatedView,\n Text: AnimatedText,\n useAnimatedNumber,\n useAnimatedNumberReaction,\n useAnimatedNumberStyle,\n useAnimations: (props, helpers) => {\n const { onDidAnimate, delay, getStyle, state } = helpers\n const [isPresent, sendExitComplete] = usePresence()\n const presence = useContext(PresenceContext)\n\n // const exitStyle = presence?.exitVariant\n // ? staticConfig.variantsParsed?.[presence.exitVariant]?.true || pseudos.exitStyle\n // : pseudos.exitStyle\n\n const isExiting = isPresent === false\n const isEntering = !state.mounted\n\n const all = getStyle({\n isExiting,\n isEntering,\n exitVariant: presence?.exitVariant,\n enterVariant: presence?.enterVariant,\n })\n\n const animateStyles = useRef<Record<string, Animated.Value>>({})\n const animatedTranforms = useRef<{ [key: string]: Animated.Value }[]>([])\n const interpolations = useRef(new WeakMap<Animated.Value, Animated.AnimatedInterpolation>())\n\n // TODO loop and create values, run them if they change\n\n const runners: Function[] = []\n const completions: Promise<void>[] = []\n\n function update(key: string, animated: Animated.Value | undefined, valIn: string | number) {\n const [val, type] = getValue(valIn)\n const value = animated || new Animated.Value(val)\n if (type) {\n interpolations.current.set(value, getInterpolated(value, type, val))\n }\n if (animated) {\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 if (animated['_value'] === val) {\n resolve()\n // avoid update when its the same\n return\n }\n animated.stopAnimation()\n Animated.spring(animated, {\n toValue: val,\n useNativeDriver: !isWeb,\n ...animationConfig,\n }).start(({ finished }) => {\n if (finished) {\n resolve()\n }\n })\n })\n }\n return value\n }\n\n function getValue(input: number | string) {\n if (typeof input !== 'string') {\n return [input] as const\n }\n const neg = input[0] === '-'\n if (neg) input = input.slice(1)\n const [_, number, after] = input.match(/([-0-9]+)(deg|%)/) ?? []\n return [+number * (neg ? -1 : 1), after] as const\n }\n\n const nonAnimatedStyle = {}\n for (const key in all) {\n const val = all[key]\n if (animatedStyleKey[key]) {\n if (key === 'transform') {\n // for now just support one transform key\n if (val) {\n for (const [index, transform] of val.entries()) {\n if (!transform) continue\n const tkey = Object.keys(transform)[0]\n animatedTranforms.current[index] = {\n [tkey]: update(tkey, animatedTranforms.current[index]?.[tkey], transform[tkey]),\n }\n }\n }\n } else {\n animateStyles.current[key] = update(key, animateStyles.current[key], val)\n }\n } else {\n nonAnimatedStyle[key] = val\n }\n }\n\n const animatedStyle = {\n ...Object.fromEntries(\n Object.entries({\n ...animateStyles.current,\n }).map(([k, v]) => [k, interpolations.current.get(v) || v])\n ),\n transform: animatedTranforms.current.map((r) => {\n const key = Object.keys(r)[0]\n const val = interpolations.current.get(r[key]) || r[key]\n return { [key]: val }\n }),\n }\n\n const args = [\n JSON.stringify(all),\n state.mounted,\n state.hover,\n state.press,\n state.pressIn,\n state.focus,\n delay,\n isPresent,\n onDidAnimate,\n presence?.exitVariant,\n presence?.enterVariant,\n ]\n\n useIsomorphicLayoutEffect(() => {\n //\n for (const runner of runners) {\n runner()\n }\n Promise.all(completions).then(() => {\n onDidAnimate?.()\n if (isExiting) {\n sendExitComplete?.()\n }\n })\n }, args)\n\n return useMemo(() => {\n return {\n style: [nonAnimatedStyle, animatedStyle],\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, args)\n },\n }\n}\n\nfunction getInterpolated(val: Animated.Value, postfix: string, next: number) {\n const cur = val['_value'] as number\n const inputRange = [cur, next]\n const outputRange = [`${cur}deg`, `${next}deg`]\n if (next < cur) {\n inputRange.reverse()\n outputRange.reverse()\n }\n return val.interpolate({\n inputRange,\n outputRange,\n })\n}\n\nfunction getAnimationConfig(key: string, animations: AnimationsConfig, animation?: AnimationProp) {\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"],
5
+ "mappings": "AAAA,SAAS,iBAAiB,mBAAmB;AAC7C;AAAA,EAKE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,YAAY,WAAW,SAAS,cAAc;AACvD,SAAS,gBAAgB;AAsBzB,MAAM,mBAAmB;AAAA,EACvB,WAAW;AAAA,EACX,SAAS;AACX;AAEO,MAAM,eAAe,SAAS;AAC9B,MAAM,eAAe,SAAS;AAE9B,SAAS,kBAAkB,SAA0D;AAC1F,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;AACL,YAAM,QAAQ,WAAW,KAAK;AAC9B,YAAM,QAAQ,YAAY;AAAA,IAC5B;AAAA,IACA,SAAS,MAAc,EAAE,SAAS,OAAO,IAAI,EAAE,MAAM,SAAS,GAAG;AAC/D,YAAM,MAAM,MAAM,QAAQ;AAC1B,UAAI,SAAS,UAAU;AACrB,YAAI,SAAS,IAAI;AAAA,MACnB,WAAW,SAAS,UAAU;AAC5B,cAAM,QAAQ,WAAW,KAAK;AAC9B,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,cAAM,QAAQ,WAAW,KAAK;AAC9B,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,iBAA6C,YAAmC;AAC9F,eAAa,iBAAiB;AAC9B,eAAa,iBAAiB;AAE9B,SAAO;AAAA,IACL,cAAc;AAAA,IACd;AAAA,IACA,MAAM;AAAA,IACN,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA,eAAe,CAAC,OAAO,YAAY;AACjC,YAAM,EAAE,cAAc,OAAO,UAAU,MAAM,IAAI;AACjD,YAAM,CAAC,WAAW,gBAAgB,IAAI,YAAY;AAClD,YAAM,WAAW,WAAW,eAAe;AAM3C,YAAM,YAAY,cAAc;AAChC,YAAM,aAAa,CAAC,MAAM;AAE1B,YAAM,MAAM,SAAS;AAAA,QACnB;AAAA,QACA;AAAA,QACA,aAAa,UAAU;AAAA,QACvB,cAAc,UAAU;AAAA,MAC1B,CAAC;AAED,YAAM,gBAAgB,OAAuC,CAAC,CAAC;AAC/D,YAAM,oBAAoB,OAA4C,CAAC,CAAC;AACxE,YAAM,iBAAiB,OAAO,oBAAI,QAAwD,CAAC;AAI3F,YAAM,UAAsB,CAAC;AAC7B,YAAM,cAA+B,CAAC;AAEtC,eAAS,OAAO,KAAa,UAAsC,OAAwB;AACzF,cAAM,CAAC,KAAK,IAAI,IAAI,SAAS,KAAK;AAClC,cAAM,QAAQ,YAAY,IAAI,SAAS,MAAM,GAAG;AAChD,YAAI,MAAM;AACR,yBAAe,QAAQ,IAAI,OAAO,gBAAgB,OAAO,MAAM,GAAG,CAAC;AAAA,QACrE;AACA,YAAI,UAAU;AACZ,gBAAM,kBAAkB,mBAAmB,KAAK,YAAY,MAAM,SAAS;AAE3E,cAAI;AACJ,gBAAM,UAAU,IAAI,QAAc,CAAC,QAAQ;AACzC,sBAAU;AAAA,UACZ,CAAC;AACD,sBAAY,KAAK,OAAO;AAExB,kBAAQ,KAAK,MAAM;AACjB,gBAAI,SAAS,cAAc,KAAK;AAC9B,sBAAQ;AAER;AAAA,YACF;AACA,qBAAS,cAAc;AACvB,qBAAS,OAAO,UAAU;AAAA,cACxB,SAAS;AAAA,cACT,iBAAiB,CAAC;AAAA,cAClB,GAAG;AAAA,YACL,CAAC,EAAE,MAAM,CAAC,EAAE,SAAS,MAAM;AACzB,kBAAI,UAAU;AACZ,wBAAQ;AAAA,cACV;AAAA,YACF,CAAC;AAAA,UACH,CAAC;AAAA,QACH;AACA,eAAO;AAAA,MACT;AAEA,eAAS,SAAS,OAAwB;AACxC,YAAI,OAAO,UAAU,UAAU;AAC7B,iBAAO,CAAC,KAAK;AAAA,QACf;AACA,cAAM,MAAM,MAAM,OAAO;AACzB,YAAI;AAAK,kBAAQ,MAAM,MAAM,CAAC;AAC9B,cAAM,CAAC,GAAG,QAAQ,KAAK,IAAI,MAAM,MAAM,kBAAkB,KAAK,CAAC;AAC/D,eAAO,CAAC,CAAC,UAAU,MAAM,KAAK,IAAI,KAAK;AAAA,MACzC;AAEA,YAAM,mBAAmB,CAAC;AAC1B,iBAAW,OAAO,KAAK;AACrB,cAAM,MAAM,IAAI;AAChB,YAAI,iBAAiB,MAAM;AACzB,cAAI,QAAQ,aAAa;AAEvB,gBAAI,KAAK;AACP,yBAAW,CAAC,OAAO,SAAS,KAAK,IAAI,QAAQ,GAAG;AAC9C,oBAAI,CAAC;AAAW;AAChB,sBAAM,OAAO,OAAO,KAAK,SAAS,EAAE;AACpC,kCAAkB,QAAQ,SAAS;AAAA,kBACjC,CAAC,OAAO,OAAO,MAAM,kBAAkB,QAAQ,SAAS,OAAO,UAAU,KAAK;AAAA,gBAChF;AAAA,cACF;AAAA,YACF;AAAA,UACF,OAAO;AACL,0BAAc,QAAQ,OAAO,OAAO,KAAK,cAAc,QAAQ,MAAM,GAAG;AAAA,UAC1E;AAAA,QACF,OAAO;AACL,2BAAiB,OAAO;AAAA,QAC1B;AAAA,MACF;AAEA,YAAM,gBAAgB;AAAA,QACpB,GAAG,OAAO;AAAA,UACR,OAAO,QAAQ;AAAA,YACb,GAAG,cAAc;AAAA,UACnB,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,eAAe,QAAQ,IAAI,CAAC,KAAK,CAAC,CAAC;AAAA,QAC5D;AAAA,QACA,WAAW,kBAAkB,QAAQ,IAAI,CAAC,MAAM;AAC9C,gBAAM,MAAM,OAAO,KAAK,CAAC,EAAE;AAC3B,gBAAM,MAAM,eAAe,QAAQ,IAAI,EAAE,IAAI,KAAK,EAAE;AACpD,iBAAO,EAAE,CAAC,MAAM,IAAI;AAAA,QACtB,CAAC;AAAA,MACH;AAEA,YAAM,OAAO;AAAA,QACX,KAAK,UAAU,GAAG;AAAA,QAClB,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN;AAAA,QACA;AAAA,QACA;AAAA,QACA,UAAU;AAAA,QACV,UAAU;AAAA,MACZ;AAEA,gCAA0B,MAAM;AAE9B,mBAAW,UAAU,SAAS;AAC5B,iBAAO;AAAA,QACT;AACA,gBAAQ,IAAI,WAAW,EAAE,KAAK,MAAM;AAClC,yBAAe;AACf,cAAI,WAAW;AACb,+BAAmB;AAAA,UACrB;AAAA,QACF,CAAC;AAAA,MACH,GAAG,IAAI;AAEP,aAAO,QAAQ,MAAM;AACnB,eAAO;AAAA,UACL,OAAO,CAAC,kBAAkB,aAAa;AAAA,QACzC;AAAA,MAEF,GAAG,IAAI;AAAA,IACT;AAAA,EACF;AACF;AAEA,SAAS,gBAAgB,KAAqB,SAAiB,MAAc;AAC3E,QAAM,MAAM,IAAI;AAChB,QAAM,aAAa,CAAC,KAAK,IAAI;AAC7B,QAAM,cAAc,CAAC,GAAG,UAAU,GAAG,SAAS;AAC9C,MAAI,OAAO,KAAK;AACd,eAAW,QAAQ;AACnB,gBAAY,QAAQ;AAAA,EACtB;AACA,SAAO,IAAI,YAAY;AAAA,IACrB;AAAA,IACA;AAAA,EACF,CAAC;AACH;AAEA,SAAS,mBAAmB,KAAa,YAA8B,WAA2B;AAChG,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,YAAY;AACxB,WAAO,KAAK;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;",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tamagui/animations-react-native",
3
- "version": "1.0.1-beta.190",
3
+ "version": "1.0.1-beta.191",
4
4
  "source": "src/index.ts",
5
5
  "sideEffects": [
6
6
  "./polyfill.js"
@@ -16,11 +16,11 @@
16
16
  "dist"
17
17
  ],
18
18
  "dependencies": {
19
- "@tamagui/animate-presence": "^1.0.1-beta.190",
20
- "@tamagui/core": "^1.0.1-beta.190"
19
+ "@tamagui/animate-presence": "^1.0.1-beta.191",
20
+ "@tamagui/core": "^1.0.1-beta.191"
21
21
  },
22
22
  "devDependencies": {
23
- "@tamagui/build": "^1.0.1-beta.190",
23
+ "@tamagui/build": "^1.0.1-beta.191",
24
24
  "react": "*",
25
25
  "react-dom": "*",
26
26
  "react-native": "*"
@@ -172,6 +172,12 @@ export function createAnimations<A extends AnimationsConfig>(animations: A): Ani
172
172
  completions.push(promise)
173
173
 
174
174
  runners.push(() => {
175
+ if (animated['_value'] === val) {
176
+ resolve()
177
+ // avoid update when its the same
178
+ return
179
+ }
180
+ animated.stopAnimation()
175
181
  Animated.spring(animated, {
176
182
  toValue: val,
177
183
  useNativeDriver: !isWeb,