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 in order 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.
Pre requisites
In order to succesfully complete this tutorial you are going to need:
Starting
The first thing we needo 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
- lottie-react-native
- lottie-ios
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 Files contains an imense catalogue of free animations you can browse in search for 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's page, just click in 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.
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
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 in order for our lottie file to be animated, is 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;
Why are we using useRef ?
Because we want our Animated Value to be created once, instead of everytime 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 ?
Well, 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 in order to fix this, you just have to check if your animation state is at the finish (1) or at 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
Top comments (1)
Awesome