Closed matinzd closed 1 week ago
UPDATE:
I passed number[]
and the issue got resolved and now it works both on iOS and Android. But if I just pass number
, the shared value will break the Android side. So it seems SVGText API is not consistent for reanimated in Android and iOS.
const animatedTextProps = useAnimatedProps(() => {
return {
x: [position.value],
y: [position.value],
}
})
Maybe we need a cast check here:
@tomekzaw
Yeah, it is due to how codegen works. Unfortunately the native side can only accept one type for each prop, so we had to stick with passing an array for all the props that could be either number
or number[]
. So as long as the codegen is not upgraded to be able to pass different types for a prop, you have to pass array with one element instead of just element for all those props. Does it answer your question?
Yeah, it is due to how codegen works. Unfortunately the native side can only accept one type for each prop, so we had to stick with passing an array for all the props that could be either
number
ornumber[]
. So as long as the codegen is not upgraded to be able to pass different types for a prop, you have to pass array with one element instead of just element for all those props. Does it answer your question?
Yeah of course. I could fix it by just passing one element array. Isn't it better maybe to update types and document to just accept number[]
? This was very misleading to me.
But at the first place, why do we need array for positionX
? Can't it be just double
value? What is the reason behind it? Because I am not that familiar with the codebase.
Isn't it better maybe to update types and document to just accept number[]?
You can pass a number as long as you don't use react-native-reanimated
because we take care of the prop so it is parsed properly on the JS side, but reanimated
skips this part.
But at the first place, why do we need array for positionX?
If you pass an array for the x
prop in svg standard, it makes next elements start at the points passed in that array. You can play with it in your elements. Does it answer your questions?
Isn't it better maybe to update types and document to just accept number[]?
You can pass a number as long as you don't use
react-native-reanimated
because we take care of the prop so it is parsed properly on the JS side, butreanimated
skips this part.But at the first place, why do we need array for positionX?
If you pass an array for the
x
prop in svg standard, it makes next elements start at the points passed in that array. You can play with it in your elements. Does it answer your questions?
Ah cool! Thank you. I see.
I think i'm facing this same issue with a circle-fill animation, I'm using react-native-reanimated@3.5.4 and react-native-svg@13.14.0 my code is something like this:
const animatedFill = useAnimatedProps(() => { return { fill: interpolateColor( color.value, [ UPLOAD_STATE.IDLE, UPLOAD_STATE.INITIALIZE, UPLOAD_STATE.UPLOADING, UPLOAD_STATE.SUCCESS, UPLOAD_STATE.ERROR, ], [mainColor, "#EEE683", "#D4A418", happyColor, deleteBtnColor] ), }; }); return ( <Svg height={svgSize} width={svgSize} style={{ position: "relative", shadowColor: mainColor, shadowOffset: { width: 0, height: 3, }, shadowOpacity: 0.17, shadowRadius: 3.05, elevation: 4, }}> <AnimatedCircle cx={svgSize / 2} cy={svgSize / 2} r={R} strokeWidth={0} animatedProps={animatedFill} /> </Svg> )}
I think i'm facing this same issue with a circle-fill animation, I'm using react-native-reanimated@3.5.4 and react-native-svg@13.14.0 my code is something like this:
const animatedFill = useAnimatedProps(() => { return { fill: interpolateColor( color.value, [ UPLOAD_STATE.IDLE, UPLOAD_STATE.INITIALIZE, UPLOAD_STATE.UPLOADING, UPLOAD_STATE.SUCCESS, UPLOAD_STATE.ERROR, ], [mainColor, "#EEE683", "#D4A418", happyColor, deleteBtnColor] ), }; }); return ( <Svg height={svgSize} width={svgSize} style={{ position: "relative", shadowColor: mainColor, shadowOffset: { width: 0, height: 3, }, shadowOpacity: 0.17, shadowRadius: 3.05, elevation: 4, }}> <AnimatedCircle cx={svgSize / 2} cy={svgSize / 2} r={R} strokeWidth={0} animatedProps={animatedFill} /> </Svg> )}
I managed to fix my issue like this, maybe it will help you in your case:
I had to pass every value natively thanks to createAnimatedPropAdapter
to avoid cast/parse issues
import Animated, {
createAnimatedPropAdapter,
useAnimatedProps,
useSharedValue,
processColor
} from "react-native-reanimated";
import Svg, { Circle, Path } from "react-native-svg"
import { mixColor } from "react-native-redash";
const AnimatedHeart = Animated.createAnimatedComponent(Path);
const heartColorTransition = useSharedValue(0);
const animatedHeartProps = useAnimatedProps(
() => {
return {
stroke: mixColor(heartColorTransition.value, "#131338", "#D9414E"),
fill: mixColor(heartColorTransition.value, "transparent", "#D9414E"),
}
},
[],
createAnimatedPropAdapter(
(props) => {
if ("fill" in props) {
// eslint-disable-next-line react/prop-types
props.fill = { type: 0, payload: processColor(props.fill as string) }
}
if ("stroke" in props) {
// eslint-disable-next-line react/prop-types
props.stroke = { type: 0, payload: processColor(props.stroke as string) }
}
},
["fill", "stroke"]
)
);
<Svg width={24} height={24} viewBox="0 0 24 24">
<AnimatedHeart
d="M7.018 3.007a4.81 4.81 0 012.724.682 5.182 5.182 0 011.942 2.125c.133.27.499.27.633 0a5.166 5.166 0 011.942-2.125 4.804 4.804 0 012.723-.682c1.387.075 2.741.799 3.654 1.911C21.55 6.034 22 7.522 22 9.027c0 1.301-.448 2.58-1.08 3.732-.632 1.155-1.474 2.185-2.387 3.15A27.615 27.615 0 0112 21a27.612 27.612 0 01-6.533-5.091c-.913-.965-1.755-1.994-2.387-3.15C2.45 11.609 2 10.33 2 9.028c0-1.505.45-2.994 1.365-4.109.912-1.111 2.266-1.836 3.653-1.911z"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={1.5}
animatedProps={animatedHeartProps}
/>
</Svg>
Bug
NOTE: I am not sure if this issue is related to
react-native-reanimated
orreact-native-svg
Passing
animatedProps
toAnimatedSvgText
will crash on Android.Environment info
React native info output:
Library version: 13.8.0 Reanimated version: 2.14.4
Steps To Reproduce
AnimatedSvgText
component withReanimated.createAnimatedComponent(Text)
animatedProps
Describe what you expected to happen:
Short, Self Contained, Correct (Compilable), Example