reactjsreact-nativereact-native-svg

How to animate react-native-svg Polygon element?


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.


Solution

  • 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:

    enter image description here

    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!