Mastering React Native Animations — Animating an SVG icon
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, andPath
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 of0
. 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 theanimatedValue
from0
to1
over a duration of1000
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, from0
to1
).outputRange
specifies the corresponding output values (from"0deg"
to"360deg"
). This means that asanimatedValue
goes from0
to1
, 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 anAnimated.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.