React-LottieでReactに簡単にアニメーションを導入する

Airbnbが提供するLottieというライブラリを使うと、Webアプリに簡単にアニメーションを追加することができます。Lottieは日本でも数年前から使われているようで、検索すればそれなりに情報が出てきます。そこでLottie自体の説明は控えめに、Reactでの利用方法を簡単に書いてみることにします。

尚、LottieはUI/UXデザイナー向けの分野になりますが、ここでは第三者の作成した素材を利用するため、Adobe系ソフトは不要で読み進めることができます。

Lottieとは

After Effectsの拡張機能であるBodymovinからアニメーションをJSONデータでエクスポートして、Webやネイティブアプリ上で利用できるようにしたライブラリのこと。サイズが小さく、Webアプリケーションでも問題なく動作するのが特徴です。

LottieFiles

LottieFilesはLottieのコミュニティサイトです。多くのアニメーションが公開・共有されています。今回はこのサービスで公開されている素材を利用します。

preview

ログインして適当なアニメーションをクリックすると、アニメーションの背景色などをカスタマイズできます。上部のDownload JSONを押してローカルにJSONファイルを保存しておきます。

Reactで利用する

自身のアプリケーションにreact-lottieをインストールします。


yarn add react-lottie

プロジェクト上の好きな位置に先程DLしたJSONファイルを配置します。そして、利用するためのコンポーネントファイルを作成します。


import React from "react";
import Lottie from "react-lottie";
import animationData from "./data/5056-delivery-latest.json";

const MyComponent = () => {
  const defaultOptions = {
    loop: true,
    autoplay: true,
    animationData,
    rendererSettings: {
      preserveAspectRatio: "xMidYMid slice"
    }
  };

  return (
    <>
      <h1>Lottie</h1>
      <Lottie options={defaultOptions} height={500} width={500} />
    </>
  );
};

export default MyComponent;

Lottieコンポーネントはいくつかのオプションが用意されています。ここでは以下のデフォルトオプションと、jsx上のpropsで横幅と高さを設定しています。

  • loop:ループ
  • autoplay:自動再生
  • animationData:アニメーションのデータファイル
  • rendererSettings:レンダリング設定
    • preserveAspectRatio:アスペクト比

このコンポーネントをメインコードで利用すれば、その位置でアニメーションが再生されます。

Sandboxに例を用意したので、プレビューできます。

デフォルトではアニメーションをクリックすると再生・停止が切り替わりますが、isStoppedisPausedというpropsをLottieコンポーネントに与えることで、コードから再生停止を操作することもできます。

イベントリスナー

Lottieコンポーネントはイベントリスナーにも対応しており、コールバック処理も可能です。実装するにはeventListeners propを付与するだけです。

以下は、completeイベント時にcallback内に記述した関数が実行されます。


 <Lottie
    ...
    eventListeners={[{
      eventName: 'complete',
      callback: obj => console.log(obj);
    }]}
 />

completeの場合は、Lottieをloop: falseにしておく必要があります。また、complete時にLottieコンポーネントがマウントされたままだと、アニメーション要素をクリックする度コールバック関数は呼ばれるようです。

次にイベントリスナーを使ったサンプルを取り上げてみます。

イベントリスナを使用したサンプル

2つのチェックボックスがあり、両方が選択されている状態で送信ボタンを押すと、アニメーションが挿入されるというものを取り上げます。アニメーションは1回のみ実行され、再生が終わればイベントリスナーを使ってアニメーションを画面上から取り除きます。

コード全文はSanxboxに置いてあるので、以降は要点だけ書いていきます。

コード解説

フォームの状態管理にはreact-use-form-stateというCustom hookを使用しています。


const [formState, { checkbox }] = useFormState({ val: [] });

// return内抜粋
<input {...checkbox('val', 'todo1')} />

ここではvalにチェックボックスの値が格納されます。例えば1つのチェックボックスにチェックを入れると、val内の配列は['todo1']となります。これを使いフォーム送信時にチェックボックスがすべて選択されているかを確認します。


// フォーム送信時のイベントハンドラ
const handleClick = e => {
  e.preventDefault();
  if (formState.values.val.length === cnt && visible === false) {
    updateVisible(!visible);
  }
};

cntはチェックボックスの総数が格納されています。visibleは下記のコードを参照して頂ければわかるように、アニメーションの表示/非表示を切り替える単なる状態変数で、updateVisibleはその更新関数です。この2つはReact Contextを使用しています。


{visible === true ? <Animation /> : null}

あとは実際に読み込まれるAnimationコンポーネントを定義します。


// Animation.jsx 抜粋

<Lottie
    options={defaultOptions}
    width={400}
    height={400}
    eventListeners={[{
        eventName: 'complete',
        callback: obj => {
          if (visible === true) {
            console.log(obj);
            updateVisible(!visible);
          }
        }
    }]}
/>

このコンポーネントファイル内でも、React Contextが使われています。アニメーションの再生が完了したら、visibleの値をupdateVisibleで更新しています。これにより、アニメーションがアンマウントされます。

このように簡単にアニメーションをコードから操作できるので、使い勝手が良いです。