React Native comes with an awesome Animated API to create smooth and performant animations in your app. It is included with react native which means no dependencies or installations with great cross platform support!
It’s already amazing.
I will be using some simple functions from the Animated API to get you started, after which reading the official documentation here will make much more sense.
Animated.Value
- Holds an animation state.
- It is always a javascript Number
- Animations react to changes in this value
Animated.View
- A component that can be animated
- This view reacts to changes in an
Animated.Value
- Behaves exactly like a normal
<View />
but with superpowers
Animated.timing
- tweens an animated value to a final value
- takes in config like duration, easing, etc.
useRef
- it returns a mutable object whose value will not change across re-renders.
- it holds its value in the
.current
property
Setup
- create a ref object using
useRef
- put an animated value with some initial value in the ref object
- pick a view you want to animate, and wrap it in an
Animated.View
import React, { useRef } from "react";
import { View, Animated } from "react-native";
const App = () => {
const anim = useRef(new Animated.Value(1));
return (
<View style={{ flex: 1 }}>
<Animated.View>
{/* Any component that needs to be animated */}
</Animated.View>
</View>
);
};
export default app;
The Heartbeat
A heartbeat animation like this has 3 main steps
- increase size
- go back to original size
- loop back to step 1
Translating this to react native looks something like this -
Modifying size
To increase the size based on a factor, react native has a transform property called “scale” in View styles. A scale
value of 2
means the element will be enlarged to twice it’s size.
eg. <View style={{transform: [scale: 2]}}> {...} </View>
Running animations in sequence
The heart beat animation needs to first increase size, then decrease it. Animated.timing
is used to do the individual animation. Animated.sequence
takes an array of animations and runs them one after the other.
eg. Animated.sequence([Animated.timing(...), Animated.timing(...),])
Making an animation loop
To make our scale animation loop indefinitely, we must use Animated.loop
. It takes an animation and loops it infinitely(by default) or for a set number of times if specified
eg. Animated.loop(Animated.timing(...))
Final config
// makes the sequence loop
Animated.loop(
// runs given animations in a sequence
Animated.sequence([
// increase size
Animated.timing(anim.current, {
toValue: 1.2,
duration: 200,
}),
// decrease size
Animated.timing(anim.current, {
toValue: 1,
duration: 200,
}),
])
).start();
The Shake
A shake animation is usually used to denote an error state. MacOS uses this in a lot of places when the user does something wrong like an incorrect password. A shake animation is very similar to the heartbeat animation above. You can try to breakdown the animation into smaller steps yourself before proceeding.
4 main steps -
- move element to the left a tiny bit
- move element to the right a tiny bit
- move element back the the original position
- loop 2 times (increase this number for a longer duration)
moving an element horizontally
To move an element horizontally, react native has a transform property called “translateX” in View styles. A translateX
value of 2
means the element will be moved to the right by 2 units and -ve values move it to the left.
eg. <View style={{transform: [translateX: 2]}}> {...} </View>
Final config
// makes the sequence loop
Animated.loop(
// runs the animation array in sequence
Animated.sequence([
// shift element to the left by 2 units
Animated.timing(anim.current, {
toValue: -2,
duration: 50,
}),
// shift element to the right by 2 units
Animated.timing(anim.current, {
toValue: 2,
duration: 50,
}),
// bring the element back to its original position
Animated.timing(anim.current, {
toValue: 0,
duration: 50,
}),
]),
// loops the above animation config 2 times
{ iterations: 2 }
).start();
The documentation will be easier to follow if you are comfortable with smaller animations and the basic Animated APIs.
The key is to breakdown your animations into smaller steps and thinking of them in terms of being small Animated.timing
components interacting with each other. Intermediate animated APIs like interpolate, easing, gestures, etc provide a lot of control over animations in react native.
Reach out if you’d like more of such content! :)