DEV Community

Cover image for Lottie animations in react native
gabrielEloy
gabrielEloy

Posted on

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 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

a blank heart animation that gets clicked, and is gradually filled with the color red

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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

npm i --save lottie-ios@3.1.8 lottie-react-native
Enter fullscreen mode Exit fullscreen mode

Finding animations

Lottie files website
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.

Downloading lottie JSON

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.

assets folder with a file called like.json inside 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;
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

with

//App.js
<LottieView source={like} />
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

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

Blank Heart

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;
Enter fullscreen mode Exit fullscreen mode

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();
  };
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

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)

Collapse
 
ebe_nezer profile image
Ebenezer

Awesome