lottie-animations
WebおよびReactアプリケーション向けのAfter Effectsアニメーションレンダリングを実現するスキルです。LottieアニメーションやJSONベクターアニメーション、インタラクティブなアイコン演出、マイクロインタラクション、ローディングアニメーションの実装時に使用します。lottie-web・lottie-react・dotLottie・bodymovinなどのライブラリやAfter EffectsのJSONエクスポートに関するタスクでトリガーされ、スクロール連動やインタラクティブアニメーションではGSAP ScrollTriggerやFramer Motionと組み合わせて活用できます。
description の原文を見る
After Effects animation rendering for web and React applications. Use this skill when implementing Lottie animations, JSON vector animations, interactive animated icons, micro-interactions, or loading animations. Triggers on tasks involving Lottie, lottie-web, lottie-react, dotLottie, After Effects JSON export, bodymovin, animated SVG alternatives, or designer-created animations. Complements GSAP ScrollTrigger and Framer Motion for scroll-driven and interactive animations.
SKILL.md 本文
Lottie アニメーション
概要
Lottie は After Effects アニメーションを web、iOS、Android、React Native でリアルタイムにレンダリングするライブラリです。Airbnb によって開発され、デザイナーが静的アセットをシップするのと同じくらい簡単にアニメーションをシップできます。アニメーションは After Effects から Bodymovin プラグインを使用して JSON ファイルとしてエクスポートされ、最小限のパフォーマンスオーバーヘッドでネイティブにレンダリングされます。
Lottie を使用する場合:
- ピクセルパーフェクトな忠実度が必要なデザイナー作成アニメーション
- 複雑なアニメーションアイコンとマイクロインタラクション
- ローディングアニメーションと進捗インジケーター
- オンボーディングシーケンスとチュートリアルアニメーション
- マーケティングアニメーションとプロモーションコンテンツ
- GIF/ビデオの代替で、より小さいファイルサイズとスケーラビリティ
主な利点:
- ベクトルベース (品質を損なわずにスケーラブル)
- GIF またはビデオよりも大幅に小さいファイルサイズ
- ランタイムで編集可能 (色、速度、セグメント)
- After Effects 経由でフルデザイナーコントロール
- クロスプラットフォームレンダリングの一貫性
- インタラクティブコントロール (再生、一時停止、シーク、ループ)
コアコンセプト
Lottie フォーマットタイプ
1. JSON Lottie (.json)
- オリジナルの Lottie フォーマット
- Bodymovin プラグイン経由で After Effects からエクスポート
- 人間が読める JSON 構造
- より大きいファイルサイズ (非圧縮)
- すべてのプラットフォーム全体で広くサポート
2. dotLottie (.lottie)
- モダンな圧縮フォーマット
- JSON + アセットを含む ZIP アーカイブ
- 1 つのファイルに複数のアニメーションとテーマをサポート
- より小さいファイルサイズ (最大 90% 削減)
- 本番環境での使用を推奨
ライブラリオプション
lottie-web (オリジナルライブラリ):
import lottie from 'lottie-web';
lottie.loadAnimation({
container: document.getElementById('lottie-container'),
renderer: 'svg', // or 'canvas', 'html'
loop: true,
autoplay: true,
path: 'animation.json' // or animationData: jsonData
});
@lottiefiles/dotlottie-web (モダン、推奨):
import { DotLottie } from '@lottiefiles/dotlottie-web';
new DotLottie({
canvas: document.getElementById('canvas'),
src: 'animation.lottie',
autoplay: true,
loop: true
});
@lottiefiles/dotlottie-react (React 統合):
import { DotLottieReact } from '@lottiefiles/dotlottie-react';
<DotLottieReact
src="animation.lottie"
loop
autoplay
style={{ height: 300 }}
/>
lottie-react (代替 React ラッパー):
import Lottie from 'lottie-react';
import animationData from './animation.json';
<Lottie animationData={animationData} loop={true} />
アニメーションデータソース
1. LottieFiles (lottie.host)
- 100,000 以上の無料アニメーション
- 直接 URL 埋め込み
- CDN ホスティング
2. ローカル JSON/dotLottie ファイル
- アプリケーションにバンドル
- より良いパフォーマンス (ネットワークリクエストなし)
- バージョン管理に適している
3. After Effects エクスポート
- カスタムデザイナーアニメーション
- Bodymovin プラグインが必要
- エクスポート設定はファイルサイズに重要
一般的なパターン
1. dotLottie-web を使用した基本的な HTML 統合
<!DOCTYPE html>
<html>
<head>
<style>
#canvas {
width: 400px;
height: 400px;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script type="module">
import { DotLottie } from 'https://cdn.jsdelivr.net/npm/@lottiefiles/dotlottie-web/+esm';
new DotLottie({
canvas: document.getElementById('canvas'),
src: 'https://lottie.host/4db68bbd-31f6-4cd8-84eb-189de081159a/IGmMCqhzpt.lottie',
autoplay: true,
loop: true
});
</script>
</body>
</html>
2. コントロール付き React コンポーネント
import React from 'react';
import { DotLottieReact } from '@lottiefiles/dotlottie-react';
const AnimatedButton = () => {
const [dotLottie, setDotLottie] = React.useState(null);
const handlePlay = () => dotLottie?.play();
const handlePause = () => dotLottie?.pause();
const handleStop = () => dotLottie?.stop();
const handleSeek = (frame) => dotLottie?.setFrame(frame);
return (
<div>
<DotLottieReact
src="button-animation.lottie"
loop
autoplay={false}
dotLottieRefCallback={setDotLottie}
style={{ height: 200 }}
/>
<div>
<button onClick={handlePlay}>Play</button>
<button onClick={handlePause}>Pause</button>
<button onClick={handleStop}>Stop</button>
<button onClick={() => handleSeek(30)}>Seek to frame 30</button>
</div>
</div>
);
};
3. イベントリスナーとライフサイクルフック
import React, { useEffect } from 'react';
import { DotLottieReact } from '@lottiefiles/dotlottie-react';
const EventDrivenAnimation = () => {
const [dotLottie, setDotLottie] = React.useState(null);
useEffect(() => {
if (!dotLottie) return;
const onLoad = () => console.log('Animation loaded');
const onPlay = () => console.log('Animation started');
const onPause = () => console.log('Animation paused');
const onComplete = () => console.log('Animation completed');
const onFrame = ({ currentFrame }) => console.log('Frame:', currentFrame);
dotLottie.addEventListener('load', onLoad);
dotLottie.addEventListener('play', onPlay);
dotLottie.addEventListener('pause', onPause);
dotLottie.addEventListener('complete', onComplete);
dotLottie.addEventListener('frame', onFrame);
return () => {
dotLottie.removeEventListener('load', onLoad);
dotLottie.removeEventListener('play', onPlay);
dotLottie.removeEventListener('pause', onPause);
dotLottie.removeEventListener('complete', onComplete);
dotLottie.removeEventListener('frame', onFrame);
};
}, [dotLottie]);
return (
<DotLottieReact
src="animation.lottie"
loop
autoplay
dotLottieRefCallback={setDotLottie}
/>
);
};
4. lottie-react によるスクロール駆動アニメーション
import Lottie from 'lottie-react';
import robotAnimation from './robot.json';
const ScrollAnimation = () => {
const interactivity = {
mode: 'scroll',
actions: [
{
visibility: [0, 0.2],
type: 'stop',
frames: [0]
},
{
visibility: [0.2, 0.45],
type: 'seek',
frames: [0, 45]
},
{
visibility: [0.45, 1.0],
type: 'loop',
frames: [45, 60]
}
]
};
return (
<Lottie
animationData={robotAnimation}
style={{ height: 300 }}
interactivity={interactivity}
/>
);
};
5. ホバートリガーセグメント再生
import { useLottie, useLottieInteractivity } from 'lottie-react';
import likeButton from './like-button.json';
const HoverAnimation = () => {
const lottieObj = useLottie({
animationData: likeButton
});
const Animation = useLottieInteractivity({
lottieObj,
mode: 'cursor',
actions: [
{
position: { x: [0, 1], y: [0, 1] },
type: 'loop',
frames: [45, 60]
},
{
position: { x: -1, y: -1 },
type: 'stop',
frames: [45]
}
]
});
return <div style={{ height: 300, border: '2px solid black' }}>{Animation}</div>;
};
6. マルチアニメーションとテーマサポート
import { DotLottieReact } from '@lottiefiles/dotlottie-react';
import React, { useState, useEffect } from 'react';
const ThemedAnimation = () => {
const [dotLottie, setDotLottie] = useState(null);
const [animations, setAnimations] = useState([]);
const [themes, setThemes] = useState([]);
const [currentAnimationId, setCurrentAnimationId] = useState('');
const [currentThemeId, setCurrentThemeId] = useState('');
useEffect(() => {
if (!dotLottie) return;
const onLoad = () => {
setAnimations(dotLottie.manifest.animations || []);
setThemes(dotLottie.manifest.themes || []);
setCurrentAnimationId(dotLottie.activeAnimationId);
setCurrentThemeId(dotLottie.activeThemeId);
};
dotLottie.addEventListener('load', onLoad);
return () => dotLottie.removeEventListener('load', onLoad);
}, [dotLottie]);
return (
<div>
<DotLottieReact
src="multi-animation.lottie"
dotLottieRefCallback={setDotLottie}
animationId={currentAnimationId}
themeId={currentThemeId}
/>
{themes.length > 0 && (
<select value={currentThemeId} onChange={(e) => setCurrentThemeId(e.target.value)}>
{themes.map((theme) => (
<option key={theme.id} value={theme.id}>{theme.id}</option>
))}
</select>
)}
{animations.length > 0 && (
<select value={currentAnimationId} onChange={(e) => setCurrentAnimationId(e.target.value)}>
{animations.map((anim) => (
<option key={anim.id} value={anim.id}>{anim.id}</option>
))}
</select>
)}
</div>
);
};
7. パフォーマンス用 Web Worker (DotLottieWorker)
import { DotLottieWorker } from '@lottiefiles/dotlottie-web';
// アニメーションレンダリングを web worker にオフロード
new DotLottieWorker({
canvas: document.getElementById('canvas'),
src: 'heavy-animation.lottie',
autoplay: true,
loop: true,
workerId: 'worker-1' // ワーカーで複数のアニメーションをグループ化
});
// 別のワーカーに複数のアニメーション
new DotLottieWorker({
canvas: document.getElementById('canvas-2'),
src: 'animation-2.lottie',
autoplay: true,
loop: true,
workerId: 'worker-2'
});
統合パターン
GSAP ScrollTrigger との統合
import Lottie from 'lottie-react';
import gsap from 'gsap';
import ScrollTrigger from 'gsap/ScrollTrigger';
import animationData from './animation.json';
gsap.registerPlugin(ScrollTrigger);
const GSAPLottieIntegration = () => {
const lottieRef = React.useRef();
React.useEffect(() => {
const anim = lottieRef.current;
if (!anim) return;
// Lottie をスクロールと同期
gsap.to(anim, {
scrollTrigger: {
trigger: '#animation-section',
start: 'top center',
end: 'bottom center',
scrub: 1,
onUpdate: (self) => {
const frame = Math.floor(self.progress * (anim.totalFrames - 1));
anim.goToAndStop(frame, true);
}
}
});
}, []);
return (
<div id="animation-section" style={{ height: '200vh' }}>
<Lottie
lottieRef={lottieRef}
animationData={animationData}
autoplay={false}
loop={false}
/>
</div>
);
};
Framer Motion との統合
import { motion } from 'framer-motion';
import { DotLottieReact } from '@lottiefiles/dotlottie-react';
const MotionLottie = () => {
return (
<motion.div
initial={{ opacity: 0, scale: 0.8 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ duration: 0.6 }}
>
<DotLottieReact
src="animation.lottie"
loop
autoplay
style={{ height: 400 }}
/>
</motion.div>
);
};
Vue 3 統合
<script setup>
import { DotLottieVue } from '@lottiefiles/dotlottie-vue';
</script>
<template>
<DotLottieVue
style="height: 500px; width: 500px"
autoplay
loop
src="https://path-to-animation.lottie"
/>
</template>
Svelte 統合
<script lang="ts">
import { DotLottieSvelte } from '@lottiefiles/dotlottie-svelte';
import type { DotLottie } from '@lottiefiles/dotlottie-svelte';
let dotLottie: DotLottie | null = null;
function play() {
dotLottie?.play();
}
</script>
<DotLottieSvelte
src="animation.lottie"
loop={true}
autoplay={true}
dotLottieRefCallback={(ref) => dotLottie = ref}
/>
<button on:click={play}>Play</button>
パフォーマンス最適化
ファイルサイズの最適化
1. After Effects のエクスポート設定:
- 「使用されていない画像をスキップ」を有効にする
- 可能な場合、フォントではなく「グリフ」を使用
- パスを簡略化 (Illustrator でポイント数を削減)
- 大量のデータを生成するエフェクト (パーティクル、ノイズ) を避ける
- ベクターレイヤーではなくシェイプレイヤーを使用
2. 圧縮:
- 自動圧縮のために dotLottie フォーマット (.lottie) を使用
- JSON を Lottie オプティマイザーツールで実行
- 不要なメタデータを削除
3. レイジーロード:
const LazyLottie = () => {
const [shouldLoad, setShouldLoad] = React.useState(false);
React.useEffect(() => {
const observer = new IntersectionObserver((entries) => {
if (entries[0].isIntersecting) {
setShouldLoad(true);
}
});
observer.observe(document.getElementById('lottie-trigger'));
return () => observer.disconnect();
}, []);
return (
<div id="lottie-trigger">
{shouldLoad && <DotLottieReact src="animation.lottie" loop autoplay />}
</div>
);
};
ランタイムパフォーマンス
1. レンダラー選択:
// SVG: 最高品質、複雑なアニメーションでは遅い
// Canvas: より優れたパフォーマンス、ラスター化
// HTML: サポート限定、シンプルなアニメーションにのみ使用
// 複雑なアニメーションではキャンバスを優先
new DotLottie({
canvas: document.getElementById('canvas'),
src: 'animation.lottie',
autoplay: true,
loop: true,
renderConfig: {
devicePixelRatio: window.devicePixelRatio || 1
}
});
2. Web Workers:
// 重いアニメーションをワーカーにオフロード
import { DotLottieWorker } from '@lottiefiles/dotlottie-web';
new DotLottieWorker({
canvas: document.getElementById('canvas'),
src: 'heavy-animation.lottie',
autoplay: true,
loop: true
});
3. モバイル最適化:
// モバイル上の品質を低下させる
const isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
new DotLottie({
canvas: document.getElementById('canvas'),
src: isMobile ? 'animation-low.lottie' : 'animation-high.lottie',
autoplay: true,
loop: true,
renderConfig: {
devicePixelRatio: isMobile ? 1 : window.devicePixelRatio
}
});
よくある落とし穴
1. 不適切なクリーンアップによるメモリリーク
問題: コンポーネントのアンマウント時に Lottie インスタンスを破棄しない。
解決策:
const SafeAnimation = () => {
const [dotLottie, setDotLottie] = React.useState(null);
React.useEffect(() => {
return () => {
// アンマウント時に常にインスタンスを破棄
dotLottie?.destroy();
};
}, [dotLottie]);
return <DotLottieReact src="animation.lottie" dotLottieRefCallback={setDotLottie} />;
};
2. イベントリスナーのクリーンアップ
問題: イベントリスナーが削除されず、複数のハンドラーが発生する。
解決策:
useEffect(() => {
if (!dotLottie) return;
const handleComplete = () => console.log('Complete');
dotLottie.addEventListener('complete', handleComplete);
// クリーンアップ関数を返す必須
return () => {
dotLottie.removeEventListener('complete', handleComplete);
};
}, [dotLottie]);
3. 大きなファイルサイズ
問題: エクスポートされた JSON ファイルがシンプルなアニメーションで 500KB 以上。
解決策:
- After Effects コンポジション (レイヤー、キーフレームを削減) を簡略化
- 圧縮のために dotLottie フォーマットを使用
- Bodymovin エクスポート設定を確認 (不要な場合は「式を含める」を無効化)
- エクスポート前に未使用アセットを削除
- Lottie オプティマイザーツールを使用: https://lottiefiles.com/tools/lottie-editor
4. アニメーションパフォーマンス問題
問題: アニメーションが途切れたり、フレームがドロップする。
解決策:
- SVG から Canvas レンダラーに切り替え
- web worker レンダリングのために
DotLottieWorkerを使用 - After Effects で複雑さを削減 (レイヤー数を削減、シェイプを簡略化)
- モバイルで devicePixelRatio を低下させる
- 同時に多くのプロパティをアニメーション化するのを避ける
5. 不正なパス/URL 参照
問題: CORS またはパスが不正なためアニメーションが読み込まれない。
解決策:
// ローカルインポートに animationData を使用 (バンドルアプリに最適)
import animationData from './animation.json';
<Lottie animationData={animationData} />
// または外部 URL にパスを使用 (CORS ヘッダーが必要)
<DotLottieReact src="https://example.com/animation.lottie" />
// Next.js の場合、public/ フォルダに配置
<DotLottieReact src="/animations/animation.lottie" />
6. After Effects エクスポート互換性
問題: 一部の After Effects 機能が Lottie にエクスポートされない。
サポートされていない機能:
- レイヤーエフェクト (ドロップシャドウ、グロー) - 代わりにシェイプレイヤーを使用
- ブレンディングモード (サポート限定)
- 3D レイヤー
- 式 (部分的なサポート)
- トラックマット (部分的なサポート)
解決策:
- エクスポートを頻繁にテスト
- エクスポート前に LottieFiles プレビューを使用
- Bodymovin 互換性を確認: https://airbnb.io/lottie/#/supported-features
- 可能な場合、エフェクトをシェイプに変換
リソース
このスキルに含まれるもの:
scripts/
generate_lottie_component.py- React/Vue/Svelte Lottie コンポーネントボイラープレートを生成optimize_lottie.py- Lottie JSON ファイルサイズを最適化
references/
api_reference.md- lottie-web、lottie-react、dotlottie-web の完全な API ドキュメントafter_effects_export.md- After Effects からのアニメーションエクスポートガイドperformance_guide.md- パフォーマンス最適化戦略の詳細ガイド
assets/
starter_lottie/- Lottie の例を含む完全な React + Vite スターターテンプレートexamples/- 実世界の Lottie アニメーションパターンと使用事例
関連スキル
- gsap-scrolltrigger - ページスクロールと同期したスクロール駆動 Lottie アニメーション用
- motion-framer - Lottie をラップするレイアウトアニメーション用に Framer Motion と組み合わせ
- animated-component-libraries - Lottie アニメーションを含める可能性のある事前構築コンポーネント
- threejs-webgl - Lottie の 2D 機能を超えた 3D アニメーション用
- react-three-fiber - 複雑な 3D アニメーションシーン用の代替手段
ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- freshtechbro
- ライセンス
- MIT
- 最終更新
- 不明
Source: https://github.com/freshtechbro/claudedesignskills / ライセンス: MIT
関連スキル
doubt-driven-development
重要な判断はすべて、本番環境への展開前に新しい視点から対抗的レビューを実施します。速度より正確性が重要な場合、不慣れなコードを扱う場合、本番環境・セキュリティに関わるロジック・取り消し不可の操作など影響度が高い場合、または後でバグを修正するよりも今検証する方が効率的な場合に活用してください。
apprun-skills
TypeScriptを使用したAppRunアプリケーションのMVU設計に関する総合的なガイダンスが得られます。コンポーネントパターン、イベントハンドリング、状態管理(非同期ジェネレータを含む)、パラメータと保護機能を備えたルーティング・ナビゲーション、vistestを使用したテストに対応しています。AppRunコンポーネントの設計・レビュー、ルートの配線、状態フローの管理、AppRunテストの作成時に活用してください。
desloppify
コードベースのヘルスチェックと技術負債の追跡ツールです。コード品質、技術負債、デッドコード、大規模ファイル、ゴッドクラス、重複関数、コードスメル、命名規則の問題、インポートサイクル、結合度の問題についてユーザーが質問した場合に使用してください。また、ヘルススコアの確認、次の改善項目の提案、クリーンアップ計画の作成をリクエストされた際にも対応します。29言語に対応しています。
debugging-and-error-recovery
テストが失敗したり、ビルドが壊れたり、動作が期待と異なったり、予期しないエラーが発生したりした場合に、体系的な根本原因デバッグをガイドします。推測ではなく、根本原因を見つけて修正するための体系的なアプローチが必要な場合に使用してください。
test-driven-development
テスト駆動開発により実装を進めます。ロジックの実装、バグの修正、動作の変更など、あらゆる場面で活用できます。コードが正常に動作することを証明する必要がある場合、バグ報告を受けた場合、既存機能を修正する予定がある場合に使用してください。
incremental-implementation
変更を段階的に実施します。複数のファイルに影響する機能や変更を実装する場合に使用してください。大量のコードを一度に書こうとしている場合や、タスクが一度では完結できないほど大きい場合に活用します。