lottie について
Webインターフェースの開発者向けLottieアニメーション実装スキルです。Reactを含む実装で、形式、性能、操作性、アクセシビリティ、読み込み、クリーンアップを扱います。
主な機能
- 01dotLottie形式の指針
- 02遅延読み込みとレンダラー選択
- 03アニメーションと画像の最適化
- 04インタラクティブな再生パターン
- 05モーション抑制とエラー時の代替表示
- 06読み込みとクリーンアップの実践
活用シーン
- 01Reactの画面へのLottie追加
- 02アニメーションの読み込みと描画コスト削減
- 03スクロール連動や区間再生の実装
- 04モーション抑制設定への対応
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ mindrally/ skills --skill lottieインストール後、Claude Code で/lottieを入力して読み込まれたか確認します。
詳細
Lottie アニメーションのガイドライン
Lottie アニメーション、Web パフォーマンス、JavaScript のエキスパートとして、Lottie アニメーションを実装する際は以下のガイドラインに従ってください。
基本原則
dotLottie 形式を使用する
.json形式よりも.lottie(dotLottie)形式を優先してください。ファイルサイズを最大 90% 削減できます- dotLottie は画像やフォントなどのすべてのアセットを、単一の圧縮ファイルにまとめます
- lottiefiles.com の無料 dotLottie コンバーターを使用してください
インストール
# For React
npm install @lottiefiles/dotlottie-react
# For vanilla JS
npm install @lottiefiles/dotlottie-web
React での実装
基本的な使い方
import { DotLottieReact } from "@lottiefiles/dotlottie-react";
function Animation() {
return (
<DotLottieReact
src="/animations/loading.lottie"
loop
autoplay
/>
);
}
アニメーションの再生を制御する
import { DotLottieReact } from "@lottiefiles/dotlottie-react";
import { useState } from "react";
function ControlledAnimation() {
const [dotLottie, setDotLottie] = useState(null);
const dotLottieRefCallback = (dotLottie) => {
setDotLottie(dotLottie);
};
return (
<>
<DotLottieReact
src="/animation.lottie"
dotLottieRefCallback={dotLottieRefCallback}
/>
<button onClick={() => dotLottie?.play()}>Play</button>
<button onClick={() => dotLottie?.pause()}>Pause</button>
<button onClick={() => dotLottie?.stop()}>Stop</button>
</>
);
}
パフォーマンスの最適化
遅延読み込み
import { useEffect, useRef, useState } from "react";
import { DotLottieReact } from "@lottiefiles/dotlottie-react";
function LazyLottie({ src }) {
const [isVisible, setIsVisible] = useState(false);
const containerRef = useRef(null);
useEffect(() => {
const observer = new IntersectionObserver(
([entry]) => {
if (entry.isIntersecting) {
setIsVisible(true);
observer.disconnect();
}
},
{ rootMargin: "100px" }
);
if (containerRef.current) {
observer.observe(containerRef.current);
}
return () => observer.disconnect();
}, []);
return (
<div ref={containerRef}>
{isVisible && <DotLottieReact src={src} autoplay loop />}
</div>
);
}
適切なレンダラーを選ぶ
// SVG renderer - best quality, good for simple animations
<DotLottieReact src="/animation.lottie" renderer="svg" />
// Canvas renderer - better performance for complex animations
<DotLottieReact src="/animation.lottie" renderer="canvas" />
// Use canvas for:
// - Complex animations with many elements
// - Lower-powered devices
// - Animations with filters/effects
DOM 要素を減らす
- After Effects で同一のグラフィック要素を再利用する
- パスを単純化し、キーフレームを減らす
- 不要なレイヤーを避ける
- アニメーションあたりの DOM 要素数を 1000 未満に抑える
アニメーションデザインのベストプラクティス
パフォーマンスに負荷のかかる機能を避ける
AVOID:
- Masks (use alpha matte sparingly)
- Complex blur effects
- 3D layers
- Expressions
- Uncompressed images
- Large image assets
PREFER:
- Simple shapes (fills, strokes)
- Transform animations (position, scale, rotation)
- Opacity changes
- Path animations
アニメーション内の画像を最適化する
- Compress images to match display size
- If max display is 400x400, don't use 1000x1000 images
- Use vector graphics when possible
- Consider converting images to shapes
インタラクティブ機能
カーソル/マウス操作
<DotLottieReact
src="/hover-animation.lottie"
playMode="hover"
/>
スクロールに連動したアニメーション
import { useScroll, useTransform } from "motion/react";
function ScrollLottie() {
const { scrollYProgress } = useScroll();
const [dotLottie, setDotLottie] = useState(null);
useEffect(() => {
if (!dotLottie) return;
const unsubscribe = scrollYProgress.on("change", (progress) => {
dotLottie.setFrame(progress * dotLottie.totalFrames);
});
return unsubscribe;
}, [dotLottie, scrollYProgress]);
return (
<DotLottieReact
src="/scroll-animation.lottie"
dotLottieRefCallback={setDotLottie}
autoplay={false}
/>
);
}
セグメント再生
function SegmentAnimation() {
const [dotLottie, setDotLottie] = useState(null);
const playSegment = (start, end) => {
dotLottie?.setSegment(start, end);
dotLottie?.play();
};
return (
<>
<DotLottieReact
src="/multi-state.lottie"
dotLottieRefCallback={setDotLottie}
autoplay={false}
/>
<button onClick={() => playSegment(0, 30)}>State 1</button>
<button onClick={() => playSegment(30, 60)}>State 2</button>
</>
);
}
アクセシビリティ
動きを減らす設定を尊重する
function AccessibleAnimation() {
const prefersReducedMotion = window.matchMedia(
"(prefers-reduced-motion: reduce)"
).matches;
if (prefersReducedMotion) {
return <img src="/static-fallback.svg" alt="Animation description" />;
}
return (
<DotLottieReact
src="/animation.lottie"
autoplay
loop
aria-label="Decorative loading animation"
/>
);
}
フォールバックを用意する
function AnimationWithFallback() {
const [hasError, setHasError] = useState(false);
if (hasError) {
return <img src="/fallback.gif" alt="Animation" />;
}
return (
<DotLottieReact
src="/animation.lottie"
autoplay
onError={() => setHasError(true)}
/>
);
}
読み込み戦略
大きなアニメーションにはプリローダーを使用する
function AnimationWithPreloader() {
const [isLoaded, setIsLoaded] = useState(false);
return (
<div className="animation-container">
{!isLoaded && (
<img src="/first-frame.webp" alt="" className="preloader" />
)}
<DotLottieReact
src="/large-animation.lottie"
onLoad={() => setIsLoaded(true)}
style={{ opacity: isLoaded ? 1 : 0 }}
autoplay
/>
</div>
);
}
ファイルサイズのガイドライン
| アニメーションの複雑さ | 目標サイズ | DOM 要素の最大数 |
|---|---|---|
| シンプルなアイコン | < 10KB | < 100 |
| UI アニメーション | < 50KB | < 500 |
| 複雑なシーン | < 150KB | < 1500 |
| ヒーローアニメーション | < 300KB | < 2500 |
クリーンアップ
React で適切にクリーンアップする
useEffect(() => {
return () => {
dotLottie?.destroy();
};
}, [dotLottie]);
ベストプラクティスのまとめ
- ファイルサイズを小さくするため、dotLottie 形式を使用する
- ビューポート内にないアニメーションは遅延読み込みする
- 複雑なアニメーションには canvas レンダラーを使用する
- マスク、ぼかし、エクスプレッションを避ける
- 画像アセットを圧縮して最適化する
- 動きを減らす設定を尊重する
- エラー時に表示する静的なフォールバックを用意する
- アンマウント時にアニメーションをクリーンアップする
- DOM 要素数を少なく保つ
- 大きなアニメーションにはプリローダーを使用する
コメント
Markdown 対応