Is there a simple way to animate the Polygon element from the react-native-svg library? I need to animate his shape by animating the points. I found few examples on how to animate Path element or Circle, but couldn't find anything regarding the Polygon. Thanks in advance.
2 Answers
Bit late to the party, but I've found a solution if you're still interested. It's not exactly 'simple', but it works. There's a library called React Native Reanimated, and it extends the functionality of Animated components substantially. Here's what I was able to achieve:
The reason animating Polygons isn't available out of the box is because the standard Animated API only handles simple values, namely individual numbers. The Polygon component in react-native-svg takes props of points, which is an array of each of the points, themselves array of x and y. For example:
<Polygon
strokeWidth={1}
stroke={strokeColour}
fill={fillColour}
fillOpacity={1}
points={[[firstPointX, firstPointY],[secondPointX, secondPointY]}
/>
React Native Reanimated allows you to animate even complex data types. In this case, there is useSharedValue, which functions almost identical to new Animated.value(), and a function called useAnimatedProps, where you can create your points (or whatever else you want to animate) and pass them to the component.
// import from the library
import Animated, {
useSharedValue,
useAnimatedProps,
} from 'react-native-reanimated';
// creates the animated component
const AnimatedPolygon = Animated.createAnimatedComponent(Polygon);
const animatedPointsValues = [
{x: useSharedValue(firstXValue), y: useSharedValue(firstYValue)},
{x: useSharedValue(secondXValue), y: useSharedValue(secondYValue)},
];
const animatedProps = useAnimatedProps(() => ({
points: data.map((_, i) => {
return [
animatedPointValues[i].x.value,
animatedPointValues[i].y.value,
];
}),
})),
Then in your render/return:
<AnimatedPolygon
strokeWidth={1}
stroke={strokeColour}
fill={fillColour}
fillOpacity={1}
animatedProps={animatedProps}
/>
Then whenever you update one of those shared values, the component will animate.
I'd recommend reading their docs and becoming familiar with the library, as it will open up a whole world of possibilities:
https://docs.swmansion.com/react-native-reanimated/
Also, the animations are handled in the native UI thread, and easily hit 60fps, yet you can write them in JS.
Good luck!

- 324
- 3
- 7
-
1thank you. To those of you looking at this solution, remember to add "import Animated from react-native-reanimated" and remove the" import Animated from react-native"!! – maxgalbu Sep 13 '21 at 18:39
-
1also, it looks like react-native-gesture-handler doesn't work well with react-native-svg. I reverted to use PanResponder for drag-n-dropping stuff with react-native-svg, and everything works – maxgalbu Sep 13 '21 at 18:42
react-native-reanimated also supports flat arrays for the Polygon points prop, so we can simplify the animation setup even more.
Full example which will animate the react-native-svg's Polygon when the points prop changes looks like this:
import React, { useEffect } from 'react'
import Animated, { useAnimatedProps, useSharedValue, withTiming } from 'react-native-reanimated'
import { Polygon } from 'react-native-svg'
interface Props {
points: number[]
}
const AnimatedPolygonInternal = Animated.createAnimatedComponent(Polygon)
export const AnimatedPolygon: React.FC<Props> = ({ points }: Props) => {
const sharedPoints = useSharedValue(points)
useEffect(() => {
sharedPoints.value = withTiming(points)
}, [points, sharedPoints])
const animatedProps = useAnimatedProps(() => ({
points: sharedPoints.value,
}))
return <AnimatedPolygonInternal fill="lime" animatedProps={animatedProps} />
}

- 181
- 8