React Native Animation is an interesting topic56 where a dull application could be converted into an interactive and beautiful app. When you first login into an application, the thing which impresses us the most is interface and its interactivity. Working with animations could look a bit overwhelming at first but it is essentially a process of just 3 steps.
In this guide you will learn about the basic principles of React Native animation. I have divided it into two sections. If you are a complete beginner, you can get ready to play with animations quickly by having minimal but most important information by going through section 1. But if you want to learn more, then feel free to proceed to section 2. After completing the first section, you will be able to work with animations. Happy animations & let’s get started.
This guide won’t teach you the concepts of React Native, else it will teach you react native animations. So, a prior knowledge of React Native is required. This article is written for version 0.63.
In this section, I included the three essential steps to work with animations. After completing this, you will be able to run animations in your app.
The first step involves the creation of animation variable. This variable defines the styling on the component throughout the whole animation lifecycle.
const animationVariable = useRef(new Animated.Value(0)).current;
I am setting the variable, animationVariable with initial value of 0. This is it. Step completed.
Since our variable is already defined, we now need a way to change the value of it. Why the animationVariable value needs to be changed? Because the change in this value derives the changes in the style properties of components which ultimately animates them.
For example, suppose an image needs to be scaled twice its size. We can do that by changing the value of animationVariable and interpolate the changes with the amount of scaling we require. Not understood? Worry not, we will see that in third step.
To change the value of animation variable, we use Spring and Timing functions of Animated component.
Animated.spring(animationVariable, {
toValue: 1,
useNativeDriver: true,
}).start();
Code Explanation –
Now we will use this animationVariable to change the style of component according to how we wish to animate it. Like in our earlier example, if we want to scale an Image or a View, we will do –
<Animated.View
style = {{
transform: [
{
scale : animationVariable.interpolate({
inputRange: [0, 1],
outputRange: [1, 2],
}),
},
],
}}
>
</Animated.View>
Code Explanation -
Now you know how React Native animation works. Here is an infographic to clear your understandings further.
import React, {useRef} from 'react';
import {Animated, Button, View} from 'react-native';
const App = () => {
const animationValue = useRef(new Animated.Value(0)).current;
const runAnimationOnClick = () => {
Animated.spring(animationValue, {
toValue: 1,
useNativeDriver: true,
}).start();
}
return (
<View>
<Animated.View
style = {{
height: 200,
width: 200,
backgroundColor: 'red',
transform: [
{
scale: animationValue.interpolate({
inputRange: [0, 1],
outputRange: [1, 2],
}),
},
],
}}
/>
<Button title="Scale Up" onPress={runAnimationOnClick} />
</View>
);
}
export default App;
In this tutorial we learned the three basic steps of working with React Native animation. First we create the animation variable. Second, we change the value of variable using spring or timing function. Third, we interpolate the variable into useful style values.
1. You can initialize any value for your animationVariable. We set 0 but doesn’t mean you have to do the same.
2. There are in total 6 components in react native which could be animated – Animated.View, Animated.Image, Animated.Text, Animated.ScrollView, Animated.FlatList, Animated.SectionList.
3. There are few types of animation function like Animated.timing(), Animated.spring() and Animated.decay(). Code snippets for these animation function are –
Animated.timing(animationValue, {
toValue: 1,
easing: Easing.back(),
duration: 2000
,
useNativeDriver: true,
}).start(({finished}) => {});
Note: React Native says that the default value of useNativeDriver is false, but actually you need to provide this property otherwise debugger will crash.
Easing defines the type of animation you want like bouncing, easeIn, easeOut, elastic etc.
{finished} parameter in start function helps in determining whether the animation is completed successfully or not. Because the function within start acts as a callback. It gets called either when animation got completed or interrupted in the middle. So, in case when you want to run something only when animation is completed, there you can use finished property within if condition.
duration defines how long will it take to change the value of animationValue from current to toValue. Like, in our case it will take 2000 ms (2 seconds) to change animationValue from 0 to 1.
Overall in summary, our animation will run for 2 seconds using easing.back (it will run the animation in opposite direction a bit and then move forward. Think of it like Lion taking few steps back before jumping. So, suppose you use this animation for scaling a View from 1 to 2 then the View first scale down a bit and then go to 2).
4. Sometimes you feel the need to combine animations together. For example, suppose you want to show 3 buttons in fadeIn style where 2nd button will start showing up only when first has reached half opacity. So, it will give the illusion of appearing buttons but with a delay.
I will show this effect with code demo. There are 4 composing animations provided by React Native – Animated.delay(), Animated.parallel(), Animated.sequence(), Animated.stagger().
5. Animated.sequence() is used to run different animations one after the other. So, suppose there are three boxes and you want to move them one after the other then we will use Animated.sequence(). See this code –
Animated.sequence([
Animated.timing(box1AnimationVariable, {
toValue: 1,
duration: 1000,
useNativeDriver: true,
}),
Animated.timing(box2AnimationVariable, {
toValue: 1,
duration: 1000,
useNativeDriver: true,
}),
]).start()
6. Animated.delay() is used with Animated.sequence and its purpose is to add a delay between two animations. For example, if you want to move the blue box after 1 second of completion of red box. Check this code snippet –
Animated.sequence([
Animated.timing(box1AnimationVariable, {
toValue: 1,
duration: 1000,
useNativeDriver: true,
}),
Animated.delay(1000),
Animated.timing(box2AnimationVariable, {
toValue: 1,
duration: 1000,
useNativeDriver: true,
}),
]).start()
7. Animated.parallel() is similar to Animated.sequence() but here all the animations will run at the same time. Check out this code –
Animated.parallel([
Animated.timing(box1AnimationVariable, {
toValue: 1,
duration: 1000,
useNativeDriver: true,
}),
Animated.timing(box2AnimationVariable, {
toValue: 1,
duration: 1000,
useNativeDriver: true,
}),
]).start()
8. Animated.stagger() is pretty interesting. It runs the animations in parallel but with a fixed delay. Like the second animation will start after the provided delay of starting of first animation. Check the code –
Animated.stagger(200, [
Animated.timing(box1AnimationVariable, {
toValue: 1,
duration: 1000,
useNativeDriver: true,
}),
Animated.timing(box2AnimationVariable, {
toValue: 1,
duration: 1000,
useNativeDriver: true,
}),
]).start()
Code snippet for the button fading example is –
import * as React from 'react';
import { Animated, View, Button, Text, TouchableHighlight } from 'react-native';
export default function App() {
const button1AnimationValue = React.useRef(new Animated.Value(0)).current;
const button2AnimationValue = React.useRef(new Animated.Value(0)).current;
const button3AnimationValue = React.useRef(new Animated.Value(0)).current;
const buttonPressed = () => {
button1AnimationValue.setValue(0);
button2AnimationValue.setValue(0);
button3AnimationValue.setValue(0);
Animated.stagger(100, [
Animated.timing(button1AnimationValue, {
toValue: 1,
duration: 300,
useNativeDriver: true,
}),
Animated.timing(button2AnimationValue, {
toValue: 1,
duration: 300,
useNativeDriver: true,
}),
Animated.timing(button3AnimationValue, {
toValue: 1,
duration: 300,
useNativeDriver: true,
}),
]).start(({finished}) => {})
}
return (
<View style={{alignItems: 'center'}}>
<Animated.View style={{
marginTop: 5,
marginBottom: 5,
opacity: button1AnimationValue.interpolate({
inputRange: [0, 1],
outputRange: [0, 1],
}),
}}>
<Button title={'Button 1'} color={'red'} />
</Animated.View>
<Animated.View style={{
marginTop: 5,
marginBottom: 5,
opacity: button2AnimationValue.interpolate({
inputRange: [0, 1],
outputRange: [0, 1],
}),
}}>
<Button title={'Button 2'} color={'cyan'} />
</Animated.View>
<Animated.View style={{
marginTop: 5,
marginBottom: 5,
opacity: button3AnimationValue.interpolate({
inputRange: [0, 1],
outputRange: [0, 1],
}),
}}>
<Button title={'Button 2'} color={'green'} />
</Animated.View>
<Button title={'Run Animation'} onPress={buttonPressed} />
<Text>Total fadein animation completes in 300ms but there is staggering delay of 100ms. So, second button will start fading in after 100ms of first button.</Text>
</View>
);
}
9. You can set useNativeDriver: true only in case of few styles like translate, scale, rotate, opacity but you can’t use native drivers for changing width and height of the components. In that case you will have to set it to false.
10. interpolate can be used for some non-numeric output ranges. For example, you can use it over colors and angles range. Check the code below –
backgroundColor: animationValue.interpolate({
inputRange: [0, 1],
outputRange: ['rgb(255,0,0)', 'rgb(0,0,255)'],
}),
This interpolation will change the background color from red to blue by passing through different color ranges in between.
Another example of interpolation of angles might look like this –
rotateX: animationValue.interpolate({
inputRange: [0, 1],
outputRange: ['0deg', '90deg'],
}),
This interpolation will rotate the component in x direction from 0deg to 90deg.
That’s it, we reached the end. In this article we learned about how react native animation works and what are the different functions we need to remember. If you want to gain more in depth knowledge about each topic, you can refer to the official documentation of React Native from here – https://reactnative.dev/docs/animations
Previously published at https://www.akashmittal.com/react-native-animation-easy-step-by-step-guide/