mcpField
L
lottie

lottie

github.com/mindrallyデザイン・UI2881.1k 回インストール3 週間前に更新
リポジトリ

lottie について

Webインターフェースの開発者向けLottieアニメーション実装スキルです。Reactを含む実装で、形式、性能、操作性、アクセシビリティ、読み込み、クリーンアップを扱います。

主な機能

  1. 01dotLottie形式の指針
  2. 02遅延読み込みとレンダラー選択
  3. 03アニメーションと画像の最適化
  4. 04インタラクティブな再生パターン
  5. 05モーション抑制とエラー時の代替表示
  6. 06読み込みとクリーンアップの実践

活用シーン

  1. 01Reactの画面へのLottie追加
  2. 02アニメーションの読み込みと描画コスト削減
  3. 03スクロール連動や区間再生の実装
  4. 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]);

ベストプラクティスのまとめ

  1. ファイルサイズを小さくするため、dotLottie 形式を使用する
  2. ビューポート内にないアニメーションは遅延読み込みする
  3. 複雑なアニメーションには canvas レンダラーを使用する
  4. マスク、ぼかし、エクスプレッションを避ける
  5. 画像アセットを圧縮して最適化する
  6. 動きを減らす設定を尊重する
  7. エラー時に表示する静的なフォールバックを用意する
  8. アンマウント時にアニメーションをクリーンアップする
  9. DOM 要素数を少なく保つ
  10. 大きなアニメーションにはプリローダーを使用する

コメント