How to Integrate Animation into a React.js Web Application

HomeInsightsBlogs | Last Updated December 21, 2021 - by bhupendra sharma under application engineering

Published onSeptember 28, 2021

Overview

Recently, I got an opportunity to work with a renowned client to develop an online education application targeting students from kindergarten to 2nd grade. During the discovery phase, the product team came with pointers that shaped the overall usability and accessibility of the application, i.e., a rich UI, audio instructions, and closed captioning (for students who can read).

In order to have a rich UI, the design team proposed using 2D & 3D animation, which makes the application intuitive and fun for kids.

As an architect, I needed to come up with an architectural implementation that allows the development team to implement the 2D & 3D animation and won’t impact performance, with the application working fluently at 1 MBPS speed as a benchmark.

I will now walk you through the process of integrating the 2D & 3D animation with React.js and view in browser.

Let’s Start with 2D Animations

Overview

Adobe After Effects can be an intuitive way to generate web animations, but there have historically been problems converting these animations to web apps. As a result, it is usually necessary to use a third-party program to import animations from After Effects.

One such program is Lottie, developed by Airbnb Design. It allows you to use these animations in real-time in a lightweight and flexible format. Lottie takes JSON data from an After Effects extension called Bodymovin and turns it into a usable animation for the web.

Implementation of Lottie reduces file size by 70 percent when compared to a GIF animation.

  1. Uncontrolled Lottie – Animations can be allowed to run freely or be manipulated by data in state.
  2. Controlled Lottie – Lottie can be manipulated in React to change some of their properties using data in state.

Prerequisites

To complete this implementation, you will need:

  1. React.js project with at least one demo page
  2. Sample Lottie file
    • We’ll be getting our sample animations from LottieFiles. Navigate to that site (https://lottiefiles.com) and create a free account.

Step 1: Install react-lottie Module

Install this module by using npm

npm install --save react-lottie

Step 2: Create Controlled Lotties

  • We need to define the required default options along with width and height
  • Provide the controlled props
    • isStopped – a boolean indicating whether the animation is active or not
    • isPaused – a boolean that indicates if the animation is paused or not
      See example below

      import React, { Component } from 'react';
      import Lottie from 'react-lottie';
      import animationData from '../lotties/sample.json';
      
      class ControlledLottie extends Component {
        state = { isStopped: false, isPaused: false };
      
        render() {
          .....
          const defaultOptions = {
            loop: true,
            autoplay: true,
            animationData: animationData,
            rendererSettings: {
              preserveAspectRatio: 'xMidYMid slice',
            },
          };
      
          return (
              .....
      
              .....
          );
        }
      }
      export default ControlledLottie;
      

Lottie Example

Let’s Understand 3D Animation Implementation

Overview

3D animation files delivered to the development team supports GLB format. Implementing GLB file format in React.js requires a third-party library called THREE.js.

THREE.js is a cross-browser JavaScript library and application programming interface (API). With THREE.js, users can create and display animated 3D computer graphics in a web browser using WebGL.

If you need to understand the THREE.js the fundamentals can be found here.

Things to Consider Before Implementing THREE.js

Though implementing 3D animation in react makes apps intuitive, I would recommend a few things to consider before implementing:

  • Make sure the GLB file is smaller in size. My recommendation is < 1MB
  • Always compress the GLB using DRACO compression
  • Unmount the props like mesh, scene, lights, color, etc.

Prerequisites

To complete this implementation, you will need:

  1. React.js project with at least one demo page
  2. Sample GLB file

Step 1: Install THREE.js Module

Install this module by using npm

npm install --save three

Step 2: Validate the GLB File

We need to validate the GLB file in the online loader (https://sandbox.babylonjs.com) and make sure that it matches the expectations of the product and design teams.

Step 3: Understand Key Props from the Design Team

This step is crucial and is where the design and development teams collaborate and finalize scenes, lights, and camera positions. Once finished, the animation will be as per expectation.

Step 4: Load the GLB file

There are multiple ways to load the GLB file in React.js, but we should first compress the GLB file as per my recommendation, since more animation results in a bigger file size, which might impact the application’s loading time and overall performance.

First, compress the GLB file to reduce the file size, then use DRACOLoader and GLTFLoader to load the GLB file.

import { LoadingManager } from 'three';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import { KTX2Loader } from 'three/examples/jsm/loaders/KTX2Loader.js';
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';
const manager = new LoadingManager();
    this.loader = new GLTFLoader()
      .setCrossOrigin('anonymous')
      .setDRACOLoader(
        new DRACOLoader(manager).setDecoderPath(),
      )
      .setKTX2Loader(new KTX2Loader(manager).detectSupport(this.renderer) );
);

Step 5: Loading and disposing of props

GLB assets tend to have a bigger file size and adversely impact browsers’ heap memory like chrome, where heap memory doesn’t garbage-collect automatically, unlike Safari and Firefox.

If there is an increase in heap memory, users can notice slowness in browser.

To avoid this, we need to implement loading and disposing of THREE.js props in react, so as soon as we navigate to a different page, dispose can trigger and release the memory.

To implement, we need to start with:

  • Declaration
    • In the component constructor, declare a series of empty collections that hold properties for lights, scene, camera, etc.
      constructor(props) {
          super(props);
      
          this.lights = [];
          this.clips = []; 
          this.renderer = null;
          this.loader = null;
          this.threeCollection = [];
          this.sceneCollection = [];
          this.requestAnimation = null;
        }
  • Assign the props on load
    • Use the async componentDidMount() function to assign all properties that are required to render the animation.
  • Dispose of the props
    • Use the componentWillUnmount() function to dispose of all properties used to render the animation along with the THREE.js object.

Three.Js Example

Below, you can see the sample. To view a full example, follow this link.

Quick Recap

  • The best recommended approach for 2D animation is Lottie implementation which is simple to implement.
  • Before implementing 3D animation, the product, design, and development teams must collaborate to finalize the lights, camera, positions, and animations.
  • Make use of the babylonejs sandbox to understand the 3D animation of the GLB file.
  • Compress the GLB file using the Draco compressor to reduce the file size.
  • Carry out proper implementation of loading and disposing of THREE.js props.

Read more from our Data & Application Engineering practice here.

Quick Recap

  • The best recommended approach for 2D animation is Lottie implementation which is simple to implement.
  • Before implementing 3D animation, the product, design, and development teams must collaborate to finalize the lights, camera, positions, and animations.
  • Make use of the babylonejs sandbox to understand the 3D animation of the GLB file.
  • Compress the GLB file using the Draco compressor to reduce the file size.
  • Carry out proper implementation of loading and disposing of THREE.js props.

Read more from our Data & Application Engineering practice here.

Bhupendra Sharma

Bhupendra is a Java Architect with over 12+ years of experience in consulting, architecture, integration and implementation of high-performing web, mobile applications for Banking, Insurance, Retail and Logistics domain. He is a value-adding techno-functional contributor who extends support in pre-sales support, requirements scoping, and proposal development.

Contact Us

We're not around right now. But you can send us an email and we'll get back to you, asap.

Not readable? Change text. captcha txt

Start typing and press Enter to search