Mastering React Native Animations — Animating an SVG icon

Maria James
5 min readOct 11, 2023

--

This guide provides step-by-step instructions on transforming a static image into an interactive element within your React Native application.

Before we start coding, let’s grasp the essential steps for transforming a PNG into an animated SVG.

Step 1: PNG to SVG Conversion:

Select a suitable PNG from any sources such as FlatIcon

If you’re working with a PNG image, consider using websites like convertio.co to convert it to SVG.

This is the SVG representation of my converted PNG image

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="64.000000pt" height="64.000000pt" viewBox="0 0 64.000000 64.000000"
preserveAspectRatio="xMidYMid meet">

<g transform="translate(0.000000,64.000000) scale(0.100000,-0.100000)"
fill="#000000" stroke="none">
<path d="M177 563 c-8 -7 43 -103 55 -103 13 0 10 18 -12 60 -21 41 -33 53
-43 43z"/>
<path d="M76 461 c-7 -10 7 -22 51 -45 35 -18 53 -20 53 -8 0 14 -98 63 -104
53z"/>
<path d="M40 320 c0 -5 25 -10 55 -10 30 0 55 5 55 10 0 6 -25 10 -55 10 -30
0 -55 -4 -55 -10z"/>
<path d="M135 228 c-49 -26 -65 -40 -60 -49 7 -10 105 39 105 53 0 11 -21 10
-45 -4z"/>
<path d="M470 231 c0 -11 62 -51 79 -51 22 0 10 15 -29 38 -43 24 -50 26 -50
13z"/>
<path d="M196 131 c-14 -27 -22 -52 -17 -55 10 -7 22 7 45 51 35 70 10 73 -28
4z"/>
<path d="M400 169 c0 -21 44 -89 57 -89 10 0 7 14 -13 50 -26 47 -44 63 -44
39z"/>
<path d="M310 95 c0 -30 5 -55 10 -55 6 0 10 25 10 55 0 30 -4 55 -10 55 -5 0
-10 -25 -10 -55z"/>
</g>
</svg>

Step 2: SVG to JSX Conversion:

For optimal compatibility, it’s recommended to convert to JSX. You can easily achieve this using websites such as react-svgr.

This is the JSX snippet of my PNG image.

  <Svg
xmlns="http://www.w3.org/2000/svg"
width={85.333}
height={85.333}
viewBox="0 0 64 64"
{...props}
>
<Path d="M17.7 7.7C16.9 8.4 22 18 23.2 18c1.3 0 1-1.8-1.2-6-2.1-4.1-3.3-5.3-4.3-4.3zM7.6 17.9c-.7 1 .7 2.2 5.1 4.5 3.5 1.8 5.3 2 5.3.8 0-1.4-9.8-6.3-10.4-5.3zM4 32c0 .5 2.5 1 5.5 1s5.5-.5 5.5-1c0-.6-2.5-1-5.5-1S4 31.4 4 32zM13.5 41.2c-4.9 2.6-6.5 4-6 4.9.7 1 10.5-3.9 10.5-5.3 0-1.1-2.1-1-4.5.4zM47 40.9c0 1.1 6.2 5.1 7.9 5.1 2.2 0 1-1.5-2.9-3.8-4.3-2.4-5-2.6-5-1.3zM19.6 50.9c-1.4 2.7-2.2 5.2-1.7 5.5 1 .7 2.2-.7 4.5-5.1 3.5-7 1-7.3-2.8-.4zM40 47.1c0 2.1 4.4 8.9 5.7 8.9 1 0 .7-1.4-1.3-5-2.6-4.7-4.4-6.3-4.4-3.9zM31 54.5c0 3 .5 5.5 1 5.5.6 0 1-2.5 1-5.5s-.4-5.5-1-5.5c-.5 0-1 2.5-1 5.5z" />
</Svg>

Step 3: Adding Animations:

Now, it’s time to add animations to the SVG. The below code animates the SVG using React Native’s Animated.

import Svg, { Path } from "react-native-svg";

const animatedValue = new Animated.Value(0);

Animated.loop(
Animated.timing(animatedValue, {
toValue: 1,
duration: 1000,
useNativeDriver: true
})
).start();

const interpolateValue = animatedValue.interpolate({
inputRange: [0, 1],
outputRange: ["0deg", "360deg"]
});

return (
<Animated.View style={{ transform: [{ rotate: interpolateValue }] }}>
<Svg
xmlns="http://www.w3.org/2000/svg"
width={85.333}
height={85.333}
viewBox="0 0 64 64"
{...props}>
<Path d="M17.7 7.7C16.9 8.4 22 18 23.2 18c1.3 0 1-1.8-1.2-6-2.1-4.1-3.3-5.3-4.3-4.3zM7.6 17.9c-.7 1 .7 2.2 5.1 4.5 3.5 1.8 5.3 2 5.3.8 0-1.4-9.8-6.3-10.4-5.3zM4 32c0 .5 2.5 1 5.5 1s5.5-.5 5.5-1c0-.6-2.5-1-5.5-1S4 31.4 4 32zM13.5 41.2c-4.9 2.6-6.5 4-6 4.9.7 1 10.5-3.9 10.5-5.3 0-1.1-2.1-1-4.5.4zM47 40.9c0 1.1 6.2 5.1 7.9 5.1 2.2 0 1-1.5-2.9-3.8-4.3-2.4-5-2.6-5-1.3zM19.6 50.9c-1.4 2.7-2.2 5.2-1.7 5.5 1 .7 2.2-.7 4.5-5.1 3.5-7 1-7.3-2.8-.4zM40 47.1c0 2.1 4.4 8.9 5.7 8.9 1 0 .7-1.4-1.3-5-2.6-4.7-4.4-6.3-4.4-3.9zM31 54.5c0 3 .5 5.5 1 5.5.6 0 1-2.5 1-5.5s-.4-5.5-1-5.5c-.5 0-1 2.5-1 5.5z" />
</Svg>
</Animated.View>
);

Let’s break it down step by step:

import Svg, { Path } from "react-native-svg";
  • This line imports the necessary components from the react-native-svg library. Svg is used to create an SVG element, and Path is used to define the shape within the SVG.
const animatedValue = new Animated.Value(0);
  • This line initialises a new animated value called animatedValue with an initial value of 0. This value will be used to drive the animation.
Animated.loop(
Animated.timing(animatedValue, {
toValue: 1,
duration: 1000,
useNativeDriver: true
})
).start();
  • This section sets up the animation itself. It uses Animated.loop to create a looping animation, meaning it will continuously repeat.
  • Inside the loop, Animated.timing is used. This type of animation smoothly transitions a value over time. In this case, it transitions the animatedValue from 0 to 1 over a duration of 1000 milliseconds (1 second).
  • useNativeDriver: true is set for performance optimization, allowing the animation to be handled by the native thread.
const interpolateValue = animatedValue.interpolate({
inputRange: [0, 1],
outputRange: ["0deg", "360deg"]
});
  • This section creates an interpolation, which maps input values (in this case, animatedValue) to output values.
  • inputRange specifies the range of input values (in this case, from 0 to 1).
  • outputRange specifies the corresponding output values (from "0deg" to "360deg"). This means that as animatedValue goes from 0 to 1, the interpolation will output a string that represents degrees of rotation.
return (
<Animated.View style={{ transform: [{ rotate: interpolateValue }] }}>
<Svg
xmlns="http://www.w3.org/2000/svg"
width={85.333}
height={85.333}
viewBox="0 0 64 64"
{...props}>
<Path d="M17.7 7.7C16.9 8.4 22 18 23.2 18c1.3 0 1-1.8-1.2-6-2.1-4.1-3.3-5.3-4.3-4.3zM7.6 17.9c-.7 1 .7 2.2 5.1 4.5 3.5 1.8 5.3 2 5.3.8 0-1.4-9.8-6.3-10.4-5.3zM4 32c0 .5 2.5 1 5.5 1s5.5-.5 5.5-1c0-.6-2.5-1-5.5-1S4 31.4 4 32zM13.5 41.2c-4.9 2.6-6.5 4-6 4.9.7 1 10.5-3.9 10.5-5.3 0-1.1-2.1-1-4.5.4zM47 40.9c0 1.1 6.2 5.1 7.9 5.1 2.2 0 1-1.5-2.9-3.8-4.3-2.4-5-2.6-5-1.3zM19.6 50.9c-1.4 2.7-2.2 5.2-1.7 5.5 1 .7 2.2-.7 4.5-5.1 3.5-7 1-7.3-2.8-.4zM40 47.1c0 2.1 4.4 8.9 5.7 8.9 1 0 .7-1.4-1.3-5-2.6-4.7-4.4-6.3-4.4-3.9zM31 54.5c0 3 .5 5.5 1 5.5.6 0 1-2.5 1-5.5s-.4-5.5-1-5.5c-.5 0-1 2.5-1 5.5z" />
</Svg>
</Animated.View>
);
  • Finally, the animated value is applied to the rotate transform property of an Animated.View. This will cause the view (and its child components, in this case, the SVG) to rotate smoothly based on the interpolated value.

Overall, this code creates a looped animation that smoothly rotates a view using the Animated API in React Native.

--

--