Lottie animations in react native

This tutorial is also available as a video, you can check it out At YouTube:

Lottie is an easy way of developing Lightweight, scalable animations for websites and applications.
Lottie has been Introduced in 2017 by Airbnb. At the time, adding animations to an application was no easy task and ofently resulted in verbose and hard to maintain code, since engineers had to manually recreate the animations to use them. The other option was adding a gif or a video to replace the animation, which wasn’t as good as programming it, and also made bundle sizes heavy.

“After Effects animations in real time, and allows native apps to use animations as easily as they use static assets.” — Airbnb engineering, 2017

Lottie’s animations are exported directly from Adobe After Effects in JSON format. That is possible thanks to an AE (After Effects) extension called Bodymovin

Thanks to that, applications can have awesome animations, without the painstaking overhead of re-writing them.

But enough with introductions,Let’s build something with lottie, so you can understand its wonders in pratice.

What are we building

this awesome like interaction is what we will be building today. When it gets clicked, it’s gradually colored and filled. If it has already been clicked, we run the animation in reverse, returning the heart to its blank, initial state.

Prerequisites

To complete this tutorial you are going to need:

Starting

The first thing we need to do, is create a react native project, so navigate to your preferred folder and initialize a new react native application. I’m going to name my application “lottieTuto” but you can call yours whatever you like

npx react-native init lottieTuto

Once our application is created, navigate to it and install the following dependencies

you can do this using yarn, with the following command:

yarn add lottie-ios@3.1.8 lottie-react-native

Alternatively, you can use the following command to install them with npm

npm i --save lottie-ios@3.1.8 lottie-react-native

Finding animations

Lottie’s home page
Lottie’s home page

Lottie Files contains an immense catalog of free animations you can browse in search of the one that fits your app.

We will be using this one today, but feel free to take your time and delight yourself with the awesome animations available at Lottie files.

In the selected animation page, just click on the download button, and choose the Lottie JSON option.

Inside the application, we created earlier, create a folder called assets, and save the downloaded file into it.

Assets folder, with a file called like.json inside of it
Assets folder, with a file called like.json inside of it

Now we finally have everything we need to start coding our application

Updating the code

Inside App.js, replace the default code for the following one

//App.js

import React from 'react';
import {View, Text, StyleSheet} from 'react-native';

const App = () => {
return (
<View style={styles.styles}>
<Text>Hello Lottie!</Text>
</View>
);
};

const styles = StyleSheet.create({
main: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
});

export default App;

Now that we have the basic code we are going to work with, is time to import some dependencies:

  • LottieView
  • Our animation from the assets folder

then proceed to replace the existent

<Text>Hello Lottie!</Text>

with

//App.js
<LottieView source={like} />

after these changes, your code should look like this

//App.js
import React from 'react';
import {View, StyleSheet} from 'react-native';
import LottieView from 'lottie-react-native';
import like from './assets/like.json';

const App = () => {
return (
<View style={styles.styles}>
<LottieView source={like} />
</View>
);
};

const styles = StyleSheet.create({
main: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
});

export default App;

Warning: sometimes when you add LottieView into your code, it breaks your application. If this is happening to you all that you gotta do is reload your app and the error shall disappear

Now you should be seeing the file we downloaded

White page with black heart in the middle of it
White page with black heart in the middle of it

But our animation isn’t animated yet.

Animating our file

We have many ways of animating a Lottie file. The one we are going to use today is by using the progress prop.

The progress prop expects a value ranging from 0 (representing the animation’s start) to 1 (representing the animation’s end).

All that we need to do for our lottie file to be animated is to update this value at a steady pace for a specific range of time.

Thankfully for us react native’s Animated module handles this behavior for us.

To use it, we are going to need to import 2 things

  • useRef — from react
  • Animated — from react-native

with these 2 imports made, create the following constant

const progress = useRef(new Animated.Value(0)).current;

Because we want our Animated Value to be created once, instead of every time our component re-renders, and useRef is perfect for this kind of situation.

now we need to create a function that’s going to update progress’s value

//App.js
const handleLikeAnimation = () => {
Animated.timing(progress, {
toValue: 1,
duration: 1000,
useNativeDriver: true,
}).start();
};

what are we doing in this function exactly?

Animated.timing is the function responsible for updating our value from one value to another at a steady pace for a specific range of time.

It accepts two parameters, the first one is the value being updated. Note that this value must be an Animated.Value.

The second parameter is an object that must contain these 3 properties.

  • toValue — your final value
  • duration — the time required to your value to go from the original value to the final one
  • useNativeDriver — Check the docs (This one is a little too complex to be explained in one line 😅

We also need to wrap our LottieView inside a TouchableOpacity, since LottieView isn’t clickable itself we need a way to call our handleLikeAnimationFunction

after all these changes, this is how our code looks like

import React, {useRef} from 'react';
import {View, StyleSheet, Animated, TouchableOpacity} from 'react-native';
import LottieView from 'lottie-react-native';
import like from './assets/like.json';

const App = () => {
const progress = useRef(new Animated.Value(0)).current;

const handleLikeAnimation = () => {
Animated.timing(progress, {
toValue: 1,
duration: 1000,
useNativeDriver: true,
}).start();
};

return (
<View style={styles.main}>
<TouchableOpacity onPress={handleLikeAnimation} style={styles.opacity}>
<LottieView progress={progress} source={like} />
</TouchableOpacity>
</View>
);
};

const styles = StyleSheet.create({
main: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
opacity: {
width: 200,
height: 200,
},
});

export default App;

Once we have done that, when we click our Heart, its animation is triggered!

But theres one last thing missing. Once our animation has been triggered, pressing it again won’t do anything

Thankfully, that’s an easy fix.

That happens because our initial value is 0, and we are always updating it to be 1, even when it’s already 1. So to fix this, you just have to check if your animation state is at the finish (1) or the begining 0.

This is our application’s final code

import React, {useRef, useState} from 'react';
import {View, StyleSheet, Animated, TouchableOpacity} from 'react-native';
import LottieView from 'lottie-react-native';
import like from './assets/like.json';

const App = () => {
const progress = useRef(new Animated.Value(0)).current;
const [hasLiked, setHasLiked] = useState(false);

const handleLikeAnimation = () => {
const newValue = hasLiked ? 0 : 1;

Animated.timing(progress, {
toValue: newValue,
duration: 1000,
useNativeDriver: true,
}).start();

setHasLiked(!hasLiked);
};

return (
<View style={styles.main}>
<TouchableOpacity onPress={handleLikeAnimation} style={styles.opacity}>
<LottieView progress={progress} source={like} />
</TouchableOpacity>
</View>
);
};

const styles = StyleSheet.create({
main: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
opacity: {
width: 200,
height: 200,
},
});

export default App;

That’s it for today folks. I really hope this post has been helpful for you

If you enjoyed this tutorial, please consider subscribing to my youtube’s channel: https://www.youtube.com/channel/UC4HtvYKMv7uvcO3CwzCCSDg/featured

and following me on twitter: https://twitter.com/MobileMagic5

Originally published at https://dev.to on June 9, 2021.