Lottie 完全ガイド - After EffectsアニメーションをWebで再生

Lottie 完全ガイド - After EffectsアニメーションをWebで再生

作成日:
更新日:

Lottieとは

Lottieは、Airbnbが開発したオープンソースのアニメーションライブラリです。Adobe After Effectsで作成したアニメーションをJSONファイルとしてエクスポートし、Web、iOS、Android、React Nativeなど様々なプラットフォームでネイティブにレンダリングできます。

なぜLottieが選ばれるのか

従来、Webでリッチなアニメーションを実現するには、GIF、動画、またはCSSアニメーションを使用する必要がありました。しかし、これらにはそれぞれ課題がありました:

形式課題
GIFファイルサイズが大きい、色数制限、透過品質が低い
動画 (MP4/WebM)ファイルサイズが大きい、透過が難しい、ループ処理が面倒
CSSアニメーション複雑なアニメーションの実装が困難、デザイナーとの連携が難しい

Lottieはこれらの問題を解決します:

特徴詳細
軽量ベクターベースでファイルサイズが小さい(GIFの1/10以下も可能)
高品質解像度に依存せず、どのサイズでも鮮明
透過対応完璧なアルファチャンネルサポート
制御可能再生、停止、速度変更、特定フレームへのジャンプが可能
インタラクティブユーザー操作に応じたアニメーション制御が容易

Lottieのエコシステム

After Effects → Bodymovin (プラグイン) → JSON → lottie-web / DotLottie
                                            ↓
                                    Web / iOS / Android / React Native
  • Bodymovin: After EffectsからLottie JSON形式でエクスポートするプラグイン
  • LottieFiles: Lottieアニメーションの共有プラットフォーム、無料素材も豊富
  • lottie-web: AirbnbのオリジナルWebライブラリ
  • DotLottie: LottieFilesによる新しい最適化フォーマット(.lottie拡張子)

セットアップ

lottie-web のインストール

Shell
npm install lottie-web

CDNを使用する場合

HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/lottie-web/5.12.2/lottie.min.js"></script>

DotLottie React(推奨)

React/Next.jsプロジェクトでは、LottieFilesが提供する@lottiefiles/dotlottie-reactが最新かつ推奨されています。

Shell
npm install @lottiefiles/dotlottie-react

基本的な使い方

lottie-web での基本実装

JavaScript
import lottie from 'lottie-web';
 
const animation = lottie.loadAnimation({
  container: document.getElementById('animation'), // DOM要素
  renderer: 'svg',     // 'svg' | 'canvas' | 'html'
  loop: true,          // ループ再生
  autoplay: true,      // 自動再生
  path: 'animation.json'  // JSONファイルのパス
});

loadAnimation のオプション

オプション説明
containerElementアニメーションをレンダリングするDOM要素
rendererstringレンダリング方式('svg', 'canvas', 'html')
loopboolean/numberループ回数(trueで無限、数値で指定回数)
autoplayboolean自動再生するかどうか
pathstringJSONファイルのURL
animationDataobjectJSONデータを直接渡す場合
namestringアニメーションの識別名
rendererSettingsobjectレンダラー固有の設定

レンダラーの選択

レンダラー特徴使いどころ
svg高品質、スケーラブル、イベント対応デフォルト、ほとんどのケースに最適
canvasパフォーマンスに優れる複雑なアニメーション、多数の要素
htmlDOM要素を使用、インタラクション容易クリック可能な要素が必要な場合

デモ:基本的なアニメーション

以下のデモでは、Lottieの基本的な読み込みと再生を確認できます。アニメーションはLottieFilesから読み込まれたサンプルを使用しています。

確認できるオプション

  • loop: オン/オフでループ再生を切り替え
  • autoplay: オン/オフで自動再生を切り替え
  • renderer: SVG / Canvas / HTML の切り替えによる描画方式の違い

それぞれのオプションを切り替えて、動作の違いを確認してみてください。特にrendererの違いは、アニメーションの複雑さやブラウザの対応状況によって最適な選択が変わります。

基本的なLottieアニメーション

lottie.loadAnimation() で JSONファイルを読み込み、SVG/Canvas/HTML形式でレンダリングします。

lottie.loadAnimation({
  container: element,
  renderer: 'svg',
  loop: true,
  autoplay: true,
  path: 'animation.json'
})
✓ loop: true✓ autoplay: true✓ renderer: svg

Lottieアニメーションの読み込み元について補足すると、pathで外部URLを指定する方法と、animationDataでJSONデータを直接渡す方法があります。バンドルサイズを抑えたい場合はpathで遅延読み込みし、初期表示の速度を優先する場合はanimationDataで埋め込む、というように使い分けます。


再生コントロール

Lottieアニメーションは、様々なメソッドで細かく制御できます。

主要なコントロールメソッド

JavaScript
const anim = lottie.loadAnimation({...});
 
// 再生制御
anim.play();           // 再生
anim.pause();          // 一時停止
anim.stop();           // 停止(最初のフレームに戻る)
 
// 速度制御
anim.setSpeed(2);      // 2倍速
anim.setSpeed(0.5);    // 0.5倍速
 
// 方向制御
anim.setDirection(1);  // 順方向
anim.setDirection(-1); // 逆方向
 
// フレーム移動
anim.goToAndStop(30, true);  // 30フレーム目で停止
anim.goToAndPlay(0, true);   // 最初から再生
 
// 情報取得
const frames = anim.totalFrames;      // 総フレーム数
const duration = anim.getDuration(false); // 秒単位の長さ
const current = anim.currentFrame;    // 現在のフレーム

デモ:再生コントロール

以下のデモでは、Lottieアニメーションの様々なコントロール機能を試すことができます。

利用可能なコントロール

  • 再生/一時停止: play() / pause()
  • 停止: stop() - 最初のフレームに戻る
  • 速度変更: setSpeed() - 0.5x〜2.0xまで調整
  • フレーム移動: goToAndStop() - 特定のフレームにジャンプ
  • 逆再生: setDirection(-1) - 逆方向に再生

再生コントロール

Frame: 0Total: 0

使用しているメソッド:

play()pause()stop()setSpeed()setDirection()goToAndStop()

コントロール機能を使いこなすことで、ユーザーのアクションに応じたインタラクティブなアニメーションを実装できます。例えば、ページ読み込み時は自動再生し、ユーザーがスクロールしてビューポート外に出たら一時停止する、といった制御が簡単に実現できます。

ヒント: goToAndStop(frame, true)の第二引数はフレーム単位かどうかを指定します。trueでフレーム番号、falseで秒数を指定します。


セグメント再生

playSegments()メソッドを使用すると、アニメーションの特定の区間のみを再生できます。これは、1つのアニメーションファイルに複数の状態(通常、ホバー、クリックなど)を含める場合に非常に便利です。

基本的な使い方

JavaScript
// 単一セグメント:フレーム10〜30を再生
anim.playSegments([10, 30], true);
 
// 複数セグメント:順番に再生
anim.playSegments([[0, 15], [30, 45]], false);

パラメータ

パラメータ説明
segments[start, end] または [[start1, end1], [start2, end2], ...]
forceFlagtrue: 即座に切り替え、false: 現在のセグメント完了後に切り替え

実用例:ボタンの状態アニメーション

JavaScript
const buttonAnim = lottie.loadAnimation({...});
 
// 通常状態: 0-15フレーム
// ホバー状態: 15-30フレーム
// クリック状態: 30-45フレーム
 
button.addEventListener('mouseenter', () => {
  buttonAnim.playSegments([15, 30], true);
});
 
button.addEventListener('mouseleave', () => {
  buttonAnim.playSegments([0, 15], true);
});
 
button.addEventListener('click', () => {
  buttonAnim.playSegments([30, 45], true);
});

デモ:セグメント再生

以下のデモでは、playSegments()メソッドを使用して、アニメーションの特定区間のみを再生する機能を確認できます。

セグメント再生の活用シーン

  1. 複数状態のボタン: 通常→ホバー→クリック状態を1つのファイルに含める
  2. ローディングインジケーター: 開始→ループ→終了を個別に制御
  3. ステップアニメーション: 各ステップを区間として定義し、ユーザーの進行に合わせて再生

セグメント再生

00 frames

playSegments([start, end], forceFlag)を使用して、アニメーションの特定区間のみを再生できます。

// 特定のセグメントを再生
anim.playSegments([30, 60], true);

// 複数セグメントを連続再生
anim.playSegments([[0, 30], [60, 90]]);

このデモでは、異なるセグメントボタンをクリックすることで、アニメーションの異なる区間が再生されます。forceFlagパラメータの効果も確認できます:

  • true: 現在の再生を中断して、すぐに新しいセグメントを再生
  • false: 現在のセグメント再生が完了してから、新しいセグメントを再生

この機能を使うことで、1つのLottieファイルに複数のアニメーション状態を含め、状況に応じて切り替えることができます。これにより、HTTPリクエスト数を削減し、ファイル管理も簡素化できます。


インタラクティブアニメーション

Lottieの真の力は、ユーザーインタラクションに応じてアニメーションを動的に制御できることです。

マウス位置でフレームを制御

JavaScript
const anim = lottie.loadAnimation({
  ...options,
  autoplay: false
});
 
element.addEventListener('mousemove', (e) => {
  const rect = element.getBoundingClientRect();
  const x = e.clientX - rect.left;
  const progress = x / rect.width;
  const frame = progress * anim.totalFrames;
  anim.goToAndStop(frame, true);
});

トグルアニメーション

JavaScript
let isActive = false;
 
button.addEventListener('click', () => {
  if (isActive) {
    anim.setDirection(-1);
  } else {
    anim.setDirection(1);
  }
  anim.play();
  isActive = !isActive;
});

デモ:インタラクティブアニメーション

以下のデモでは、ユーザーの入力(マウス操作、クリック)に応じてLottieアニメーションを動的に制御する方法を確認できます。

インタラクションの種類

  1. マウス位置追従: マウスのX座標に応じてアニメーションフレームが変化
  2. クリックでトグル: クリックするたびに再生方向が反転
  3. ホバー効果: マウスオーバーで再生、マウスアウトで逆再生

インタラクティブアニメーション

← マウスを左右に動かしてください →

ホバー連動コード
// マウス位置でフレームを制御
element.addEventListener('mousemove', (e) => {
  const rect = element.getBoundingClientRect();
  const progress = (e.clientX - rect.left) / rect.width;
  const frame = progress * anim.totalFrames;
  anim.goToAndStop(frame, true);
});
インタラクティブの活用例
  • • ホバー時のアイコンアニメーション
  • • スクロール位置に連動した進捗表示
  • • トグルスイッチのON/OFF演出
  • • フォーム送信時のフィードバック

インタラクティブアニメーションは、マイクロインタラクションの実装に最適です。例えば:

  • ハンバーガーメニューのトグル: 3本線→×印へのモーフィング
  • いいねボタン: ハートが弾むアニメーション
  • スイッチコントロール: オン/オフの切り替え

これらは従来CSSやSVGアニメーションで実装されていましたが、Lottieを使うことでデザイナーがAfter Effectsで複雑なアニメーションを作成し、エンジニアはそれを読み込んで制御するだけで済みます。デザインと実装の分離が明確になり、チームの生産性が向上します。


スクロール連動アニメーション

スクロール位置に応じてLottieアニメーションを制御することで、印象的なストーリーテリングやプログレス表示が可能になります。

基本的な実装

JavaScript
const anim = lottie.loadAnimation({
  ...options,
  autoplay: false
});
 
const container = document.querySelector('.scroll-container');
 
container.addEventListener('scroll', () => {
  const scrollTop = container.scrollTop;
  const scrollHeight = container.scrollHeight - container.clientHeight;
  const progress = scrollTop / scrollHeight;
  const frame = progress * anim.totalFrames;
  anim.goToAndStop(frame, true);
});

パフォーマンス最適化

スクロールイベントは高頻度で発火するため、requestAnimationFrameを使用してパフォーマンスを最適化します。

JavaScript
let ticking = false;
 
container.addEventListener('scroll', () => {
  if (!ticking) {
    requestAnimationFrame(() => {
      const progress = container.scrollTop / 
        (container.scrollHeight - container.clientHeight);
      const frame = progress * anim.totalFrames;
      anim.goToAndStop(frame, true);
      ticking = false;
    });
    ticking = true;
  }
});

デモ:スクロール連動

以下のデモでは、スクロール位置に応じてLottieアニメーションのフレームが変化します。スクロールバーを動かすと、アニメーションの進行度が連動して変化することを確認できます。

スクロール連動アニメーションの活用例

  • ストーリーテリング: スクロールに合わせてイラストが展開
  • 製品紹介: スクロールで製品が組み立てられていく様子を表現
  • データビジュアライゼーション: スクロール位置でグラフが描画される
  • プログレス表示: ページの読了率を視覚的に表示

スクロール連動アニメーション

0%0%100%

↓ スクロールしてアニメーション

セクション 1

スクロール位置がアニメーションの進行度に変換されます。 スムーズな体験を提供するために、 requestAnimationFrame と組み合わせることをお勧めします。

セクション 2

スクロール位置がアニメーションの進行度に変換されます。 スムーズな体験を提供するために、 requestAnimationFrame と組み合わせることをお勧めします。

セクション 3

スクロール位置がアニメーションの進行度に変換されます。 スムーズな体験を提供するために、 requestAnimationFrame と組み合わせることをお勧めします。

セクション 4

スクロール位置がアニメーションの進行度に変換されます。 スムーズな体験を提供するために、 requestAnimationFrame と組み合わせることをお勧めします。

セクション 5

スクロール位置がアニメーションの進行度に変換されます。 スムーズな体験を提供するために、 requestAnimationFrame と組み合わせることをお勧めします。

🎉 完了!
実装コード
// スクロール位置をアニメーションフレームに変換
const handleScroll = (e) => {
  const { scrollTop, scrollHeight, clientHeight } = e.target;
  const progress = scrollTop / (scrollHeight - clientHeight);
  const frame = progress * animation.totalFrames;
  animation.goToAndStop(frame, true);
};

// イベントリスナー登録
container.addEventListener('scroll', handleScroll);
パフォーマンスのヒント
  • requestAnimationFrame でスクロールイベントをデバウンス
  • CSS Scroll-driven Animations と組み合わせてよりスムーズに
  • renderer: 'canvas' で複雑なアニメーションを最適化
現在の状態
Progress:0.0%
Frame:0

実装のポイント

// スクロール位置を0〜1の範囲に正規化
const progress = scrollTop / (scrollHeight - clientHeight);
// 総フレーム数に掛けてフレーム番号を算出
const frame = progress * anim.totalFrames;
anim.goToAndStop(frame, true);

このデモではrequestAnimationFrameを使用してパフォーマンスを最適化しています。スクロールイベントは非常に高頻度で発火するため、フレームごとに1回だけ処理を行うようにすることで、スムーズな動作を維持しています。


イベントリスナー

Lottieアニメーションは、様々なイベントを発火します。これらを活用することで、アニメーションの状態に応じた処理が可能になります。

利用可能なイベント

イベント発火タイミング
completeループなしのアニメーションが完了した時
loopCompleteループの1サイクルが完了した時
enterFrame各フレームが描画された時
segmentStartセグメントの再生が開始された時
DOMLoadedDOMに要素が追加された時
destroyアニメーションが破棄された時

使用例

JavaScript
const anim = lottie.loadAnimation({...});
 
// アニメーション完了時
anim.addEventListener('complete', () => {
  console.log('アニメーション完了');
});
 
// 各フレーム描画時
anim.addEventListener('enterFrame', (e) => {
  console.log('現在のフレーム:', e.currentTime);
});
 
// ロード完了時
anim.addEventListener('DOMLoaded', () => {
  console.log('アニメーションがロードされました');
  console.log('総フレーム数:', anim.totalFrames);
});
 
// イベントリスナーの削除
anim.removeEventListener('complete', handler);

複数アニメーションの管理

ページ内に複数のLottieアニメーションがある場合、効率的な管理が重要です。

グローバルメソッド

JavaScript
// すべてのアニメーションを制御
lottie.play();        // すべて再生
lottie.pause();       // すべて一時停止
lottie.stop();        // すべて停止
lottie.setSpeed(2);   // すべての速度を変更
 
// 特定のアニメーションを名前で制御
lottie.play('myAnimation');
lottie.stop('myAnimation');

配列で管理

JavaScript
const animations = [];
 
containers.forEach((container, index) => {
  const anim = lottie.loadAnimation({
    container,
    renderer: 'svg',
    loop: true,
    autoplay: true,
    path: paths[index],
    name: `anim-${index}`
  });
  animations.push(anim);
});
 
// 一括操作
animations.forEach(anim => anim.pause());
 
// 特定のアニメーションを操作
animations[2].play();

Intersection Observer との連携

画面外のアニメーションを一時停止することで、パフォーマンスとバッテリー消費を最適化できます。

JavaScript
const observer = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    const anim = animations.find(a => a.wrapper === entry.target);
    if (anim) {
      if (entry.isIntersecting) {
        anim.play();
      } else {
        anim.pause();
      }
    }
  });
}, { threshold: 0.1 });
 
containers.forEach(container => observer.observe(container));

デモ:複数アニメーション管理

以下のデモでは、ページ内に複数のLottieアニメーションがある場合の管理方法を確認できます。

管理のポイント

  1. 一括制御: すべてのアニメーションを同時に再生/停止
  2. 個別制御: 特定のアニメーションのみを操作
  3. Intersection Observer連携: 画面に見えているアニメーションのみ再生

複数アニメーションの管理

速度:

Checkmark

Loading

Notification

Heart

複数アニメーションの一括制御
// すべてのアニメーションインスタンスを配列で管理
const animations = [];

containers.forEach((container, index) => {
  animations[index] = lottie.loadAnimation({
    container,
    renderer: 'svg',
    loop: true,
    autoplay: true,
    path: paths[index]
  });
});

// 一括操作
animations.forEach(anim => anim.play());
animations.forEach(anim => anim.setSpeed(2));

// または lottie のグローバルメソッドを使用
lottie.play();        // すべてのアニメーションを再生
lottie.pause();       // すべてのアニメーションを一時停止
lottie.setSpeed(2);   // すべてのアニメーションの速度を変更
メモリ管理のベストプラクティス
  • • 不要になったアニメーションは destroy() で破棄
  • • 画面外のアニメーションは pause() で停止
  • • Intersection Observer と組み合わせて可視時のみ再生

複数のアニメーションを効率的に管理することは、パフォーマンスとバッテリー消費の観点から非常に重要です。画面外のアニメーションを再生し続けると、CPUとGPUのリソースを無駄に消費します。

ベストプラクティス

  • ビューポート外のアニメーションはpause()で一時停止
  • ユーザーがページを離れたらstop()で完全停止
  • コンポーネントのアンマウント時は必ずdestroy()を呼び出す
  • nameプロパティを活用して、アニメーションを識別しやすくする

特にモバイルデバイスでは、バッテリー消費に直結するため、Intersection Observerとの連携は必須と言えます。


React/Next.js での実装

DotLottieReact(推奨)

TypeScript
'use client';
 
import { DotLottieReact } from '@lottiefiles/dotlottie-react';
import { useRef } from 'react';
 
export function LottieComponent() {
  const dotLottieRef = useRef(null);
 
  return (
    <DotLottieReact
      src="https://lottie.host/xxx.lottie"
      loop
      autoplay
      dotLottieRefCallback={(dotLottie) => {
        dotLottieRef.current = dotLottie;
      }}
    />
  );
}

カスタムコントロール付き

TypeScript
'use client';
 
import { DotLottieReact } from '@lottiefiles/dotlottie-react';
import { useRef, useState } from 'react';
 
export function ControlledLottie() {
  const dotLottieRef = useRef(null);
  const [isPlaying, setIsPlaying] = useState(true);
 
  const handleToggle = () => {
    if (isPlaying) {
      dotLottieRef.current?.pause();
    } else {
      dotLottieRef.current?.play();
    }
    setIsPlaying(!isPlaying);
  };
 
  return (
    <div>
      <DotLottieReact
        src="/animations/my-animation.lottie"
        loop
        autoplay
        dotLottieRefCallback={(dotLottie) => {
          dotLottieRef.current = dotLottie;
        }}
      />
      <button onClick={handleToggle}>
        {isPlaying ? 'Pause' : 'Play'}
      </button>
    </div>
  );
}

lottie-web を直接使用する場合

TypeScript
'use client';
 
import { useEffect, useRef } from 'react';
import lottie, { AnimationItem } from 'lottie-web';
 
export function LottieDirect() {
  const containerRef = useRef<HTMLDivElement>(null);
  const animationRef = useRef<AnimationItem | null>(null);
 
  useEffect(() => {
    if (!containerRef.current) return;
 
    animationRef.current = lottie.loadAnimation({
      container: containerRef.current,
      renderer: 'svg',
      loop: true,
      autoplay: true,
      path: '/animations/my-animation.json',
    });
 
    return () => {
      animationRef.current?.destroy();
    };
  }, []);
 
  return <div ref={containerRef} />;
}

パフォーマンス最適化

ファイルサイズの削減

  1. 不要なレイヤーを削除: After Effectsで使用していないレイヤーを削除
  2. パスの簡略化: 複雑なパスを可能な限り単純化
  3. 圧縮: gzip圧縮でさらにサイズを削減
  4. DotLottie形式: .lottie形式はJSONより約50%小さい

レンダリングの最適化

JavaScript
// Canvas レンダラーを使用(複雑なアニメーションに有効)
lottie.loadAnimation({
  container: element,
  renderer: 'canvas',
  rendererSettings: {
    clearCanvas: true,
    progressiveLoad: true,
    hideOnTransparent: true,
  }
});

メモリ管理

JavaScript
// 不要になったアニメーションは必ず破棄
animation.destroy();
 
// React/Vue のクリーンアップ
useEffect(() => {
  const anim = lottie.loadAnimation({...});
  return () => anim.destroy();
}, []);

Lazy Loading

JavaScript
// Intersection Observer でビューポート内に入った時のみロード
const observer = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      lottie.loadAnimation({
        container: entry.target,
        ...
      });
      observer.unobserve(entry.target);
    }
  });
});

LottieFiles の活用

LottieFilesは、Lottieアニメーションの作成・共有・発見のためのプラットフォームです。

無料アニメーション

LottieFilesには数万点の無料アニメーションが公開されています。検索してダウンロードし、自分のプロジェクトで使用できます。

Lottie Editor

ブラウザ上でLottieアニメーションを編集できます:

  • 色の変更
  • レイヤーの表示/非表示
  • 速度調整
  • トリミング

DotLottie

.lottie形式は、JSON + 必要なアセットを1つのファイルにまとめた最適化フォーマットです。

JavaScript
// DotLottie の読み込み
import { DotLottie } from '@lottiefiles/dotlottie-web';
 
const dotLottie = new DotLottie({
  canvas: document.getElementById('canvas'),
  src: 'animation.lottie',
  autoplay: true,
  loop: true,
});

まとめ

Lottieは、Webアニメーションの実装を大きく変えるライブラリです。After Effectsのパワフルなアニメーション機能をそのままWebに持ち込むことができ、デザイナーとデベロッパーの連携もスムーズになります。

Lottieの強み

強み詳細
デザイナーフレンドリーAfter Effectsでアニメーションを作成、エンジニアリング知識不要
軽量・高品質ベクターベースで解像度非依存、ファイルサイズも小さい
インタラクティブユーザー操作に応じた動的な制御が可能
クロスプラットフォームWeb, iOS, Android, React Nativeで同じアニメーションを使用
豊富なエコシステムLottieFiles, DotLottie, 各種ライブラリ

使いどころ

  • ローディングアニメーション
  • マイクロインタラクション(ボタン、アイコン)
  • オンボーディング・チュートリアル
  • 空の状態(Empty State)の表現
  • ストーリーテリング型のコンテンツ

次のステップ

  1. LottieFilesで無料アニメーションを探す
  2. 基本的な再生コントロールを実装
  3. インタラクティブな要素を追加
  4. パフォーマンスの最適化

Lottieを活用して、ユーザー体験を向上させる魅力的なアニメーションを実装しましょう!


参考リンク