DEV Community

Vikas Kumar
Vikas Kumar

Posted on • Originally published at geekyhub.in on

5 2

Animate SVG in React Native

Here, by animating SVG, I mean to change the property of SVG elements dynamically, which will look live-like.

In react native, we can generate/render an SVG using the react-native-svg library. A complex SVG comprises many more minor elements that could be animated individually. But here, for example, we will take only one piece, a circle.

The following code will draw a circle with a radius of 50 units.

<Svg width={200} height={200}>
  <Circle cx="55" cy="55" r="50" stroke="black" strokeWidth={5} />
</Svg>

Enter fullscreen mode Exit fullscreen mode

Suppose we want to animate it to become large and small. To achieve this, I will use React Native Reanimated. To learn more about it, you can check out its documentation.

Logically, I am trying to increase or decrease the radius.

Since the radius value is a prop, I will use useAnimatedProps. But, first of all, convert Circle to an animated component.

const AnimatedCircle = Animated.createAnimatedComponent(Circle);

Enter fullscreen mode Exit fullscreen mode

Now, I can re-write component as

<Svg width={200} height={200}>
  <AnimatedCircle cx="55" cy="55" r="50" stroke="black" strokeWidth={5} />
</Svg>

Enter fullscreen mode Exit fullscreen mode

Next step is to store the stroke width and radius. width can be stored in a simple constat, but for the radius we will use useSharedValue, so that it can be used by woklet to animate.

export default ()=>{
  const radius = useSharedValue(50);
  const strokeWidth = 5;

  return (
    <Svg width={200} height={200}>
      <AnimatedCircle
        cx={`${radius.value + strokeWidth}`}
        cy={`${radius.value + strokeWidth}`}
        r={`${radius.value}`}
        stroke="black"
        strokeWidth={strokeWidth}
      />
    </Svg>
  )
}

Enter fullscreen mode Exit fullscreen mode

Here, I need some event or action to trigger the radius change. I’ll use a button press. (withSpring is default provided animation which is not necessary to use but this looks cool 🤞)

<Button mode="contained" onPress={() => {
  if(radius.value < 80) {
  radius.value = withSpring(80)
  }else{
    radius.value = withSpring(50)
  }
}}>
  Press
</Button>

Enter fullscreen mode Exit fullscreen mode

You’ll notice that even after pressing the button, nothing happens. It is because change of sharedValue doesn’t trigger re-render of the react component. finally animated props comes into the picture. Instead of passing prop directly, we will pass it using animated prop.

const animatedProps = useAnimatedProps(() => ({
  cx: `${radius.value + strokeWidth}`,
  cy: `${radius.value + strokeWidth}`,
  r:`${radius.value}`
}));


<Svg width={200} height={200}>
  <AnimatedCircle
    animatedProps={animatedProps}
    stroke="black"
    strokeWidth={strokeWidth}
  />
</Svg>

Enter fullscreen mode Exit fullscreen mode

Result, is something like this.

This is a relatively simple example, but I hope I successfully demonstrated the possibilities. Here is the link of complete code of the result if you are interested.

AWS Q Developer image

Your AI Code Assistant

Automate your code reviews. Catch bugs before your coworkers. Fix security issues in your code. Built to handle large projects, Amazon Q Developer works alongside you from idea to production code.

Get started free in your IDE

Top comments (0)

Sentry mobile image

Improving mobile performance, from slow screens to app start time

Based on our experience working with thousands of mobile developer teams, we developed a mobile monitoring maturity curve.

Read more