Wednesday, 13 March, 2019 UTC


Summary

So your designer just came up with an amazing new animation on Adobe After Effects for your web application, fantastic! Just one problem, how do you convert this to a format usable within your web app? No worries, the awesome folks at Airbnb Design have your back. Introducing, Lottie , a fantastic new technology that allows you to use these animations in real time in a lightweight and flexible format just as easily as static images.
How does this work you ask? Well, here's the explanation from Airbnb Design:
Lottie uses animation data exported as JSON files from an open-source After Effects extension called Bodymovin. The extension is bundled with a JavaScript player that can render the animations on the web. Lottie is amazing for 3 main reasons:
  • It makes use of Adobe Effects flexible features to come up with high quality animations
  • It allows you to manipulate your animation in whatever way you would like
  • The animations have a small file size as they are they are in vector format
In this article, we'll be looking at how we can leverage the power of Lottie to add more life to our React Applications. To do this, we'll be using an npm package called react-lottie to generate viewable animations from JSON files exported by Bodymovin. Since we'll be focusing on the app side of things, we won't look into how these animations are created in After Effects but rather use animations created and open sourced by designers on Lottiefiles. If you have animations on After effects that you would like to use, you can export them to JSON using the Bodymovin plugin for After Effects.
What we'll be building
For this tutorial, we'll build this application which consists of two types of Lotties, one regular one and another with controlled animations depending on certain values in state.
https://codesandbox.io/embed/github/austinroy/lottie-demo/tree/master/
Let's get started.
Creating our application
We'll be using create-react-app to create our app. If you don't have it installed yet run the following command to do so:
npm install --g create-react-app
Now let's create our application:
create-react-app lottie-demo
This will create some boilerplate code for our app and configure our react development environment. Open up the lottie-demo directory and let's get coding. Yarn is create-react-app's default package manager and it's what we'll use to handle our dependencies(or rather dependency since there's only one for this project) so it's worth looking into as well.
Now let's install our one and only dependency, react-lottie , to do this run this command in the terminal:
yarn add react-lottie
Great, we are all set to go, now let's add our animations.
Getting our Sample Lotties
We'll bve getting our sample animations from LottieFiles, so head over there and create a free account.
LottieFiles gives you access to a curated library of awesome animations from designers all over the globe, it also provides a platform to test, upload and share your own animations and is a great resource in general.
Simply browse through the animations, tweak the settings if necessary and when you are happy with what you have click Download JSON to get the animation. Now inside the src directory of our application create two more directories, components and lotties . These will hold or React components and Lottie animation data respectively. Place the downloaded JSON files inside the lotties directory.
Awesome, now we are ready to create components that display these animations.
Uncontrolled Lotties
Animations can be allowed to run freely or be manipulated by data in state. First, let's look at the first case and create an animation that simply imports and renders a lottie.
Create a file called UncontrolledLottie.jsx inside the components directory and place the following code inside it.
// UncontrolledLottie.jsx
import React, { Component } from 'react'
import Lottie from 'react-lottie'
import animationData from '../lotties/4203-take-a-selfie.json'

class UncontrolledLottie extends Component {

  render(){

    const defaultOptions = {
      loop: true,
      autoplay: true, 
      animationData: animationData,
      rendererSettings: {
        preserveAspectRatio: 'xMidYMid slice'
      }
    };

    return(
      <div>
        <h1>Lottie</h1>
        <p>Base animation free from external manipulation</p>
        <Lottie options={defaultOptions}
              height={400}
              width={400}
        />
      </div>
    )
  }
}

export default UncontrolledLottie
In this case, 4204-take-a-selfie.json is the JSON file of the lottie I had downloaded. Feel free to replace that with whichever you had downloaded. Now let's go through the information provided in the configuration. You will notice we pass an options prop to the Lottie component, this contains the configuration data for the animation to be rendered. This consists of
  • animationData - an Object with the exported animation data, in our case, the json file
  • autoplay - a boolean determining if it will start playing as soon as it is ready
  • loop - a boolean or number, this determines if the animation will repeat or how many times it should repeat
  • rendererSettings - configuration data for the renderer
These are just some of the options you can provide.
We also provide the dimensions(length and width) of out animation as props to Lottie.
Great, this animation is now ready for use by importing it into our App.js and will look like this: But first let's add our controlled Lottie.
Controlled lotties
Lotties can be manipulated in React to change some of their properties using data in state. In our case, we'll look at how we can play, stop and pause the animations in our lottie.
Let's create a file in components and name it ControlledLottie.jsx . Place the following code in that file
// ControlledLottie.jsx
import React, { Component } from 'react'
import Lottie from 'react-lottie'
import animationData from '../lotties/77-im-thirsty.json'

class ControlledLottie extends Component {
  state = {isStopped: false, isPaused: false}

  render(){
    const buttonStyle = {
      display: 'inline-block',
      margin: '10px auto',
      marginRight: '10px',
      border: 'none',
      color: 'white',
      backgroundColor: '#647DFF',
      borderRadius: '2px',
      fontSize: '15px'

    };

    const defaultOptions = {
      loop: true,
      autoplay: true, 
      animationData: animationData,
      rendererSettings: {
        preserveAspectRatio: 'xMidYMid slice'
      }
    };

    return(
      <div className="controlled">
        <h1>Controlled Lottie</h1>
        <p>Uses state manipulation to start, stop and pause animations</p>
        <Lottie options={defaultOptions}
              height={400}
              width={400}
              isStopped={this.state.isStopped}
              isPaused={this.state.isPaused}
        />
        <button style={buttonStyle} onClick={() => this.setState({isStopped: true})}>Stop</button>
        <button style={buttonStyle} onClick={() => this.setState({isStopped: false, isPaused: false })}>Play</button>
        <button style={buttonStyle} onClick={() => this.setState({isPaused: !this.state.isPaused})}>Pause</button>
      </div>
    )
  }
}

export default ControlledLottie
Let's analyse this code. At first glance it is pretty much identical to the code in ControlledLottie.jsx but there's a few key differences. We've added 3 buttons at the bottom along with their styling. These buttons are used to toggle the values of the data in state.
The Lottie component also has two more props:
  • isStopped - a boolean indicating whether the animation is active or not
  • isPaused - a boolean that indicates if the animation is paused or not
Here's whar our controlled lottie component will look like:
Both our animations are ready to use now so let's import them into App.js and display them in our app. Edit the code in App.js , importing our components and adding them inside the render function.
// App.js
import React, { Component } from 'react';
import './App.css';
import UncontrolledLottie from './components/UncontrolledLottie';
import ControlledLottie from './components/ControlledLottie';

class App extends Component {
  render() {
    return (
      <div className="App">
        <h1>REACT LOTTIES</h1>
        <div className="lotties">
          <UncontrolledLottie />
          <ControlledLottie />
        </div>
      </div>
    );
  }
}

export default App;
Let's style the our app to make it mobile responsive, we can do this using css grid. Add the following code to your App.css file.
.lotties{
  display: grid;
  grid-template-columns: auto auto;
}

@media only screen and (min-device-width : 320px) and (max-device-width: 480px){
  .lotties{
    display: grid;
    grid-template-columns: auto;
  }
}
This places our lotties in two columns that will be reduced to a single column on devices with a smaller width.
Now fire up the application and watch the magic happen.
yarn start
Your browser will open up and you should be able to see the two animations active. Clicking Pause will have the controlled animation freeze in it's current frame, clicking it again should resume it as well as clicking Play . Clicking Stop returns the animation to it's default position and holds it there. Pretty nice, right?
https://codesandbox.io/embed/github/austinroy/lottie-demo/tree/master/
Conclusion
Lottie can be used to really add life to an application, be it on web or mobile. They can be used to make applications more interactive and provide visually appealing feedback, for example animations indicating the state of certain processes. Lotties are also amazingly easy to use and extremely lightweight so they shouldn't have a massive impact on the perfomance of your application.