要素の切り替え(Transition)

フェード・スライド・スケールなどのコンテンツ切り替えアニメーションをFramer Motion / React Spring / GSAP / CSS Transitionで実装・比較

🔗 このページはFramer Motion / React Spring / GSAP / CSS Transitionを使ったReact実装です。バニラJSでの実装はCSSアニメーションの制御ページを参照してください。
Framer Motion

読み込み中...

tsx
'use client';
import { useState } from 'react';
import { motion, AnimatePresence } from 'framer-motion';

const ITEMS = ['春 🌸', '夏 🌿', '秋 🍂', '冬 ❄️'];

export default function TransitionDemo() {
  const [current, setCurrent] = useState(0);

  return (
    <>
      {/* フェード切り替え */}
      <AnimatePresence mode="wait">
        <motion.div
          key={current}
          initial={{ opacity: 0 }}
          animate={{ opacity: 1 }}
          exit={{ opacity: 0 }}
          transition={{ duration: 0.3 }}
        >
          {ITEMS[current]}
        </motion.div>
      </AnimatePresence>

      {/* スライド切り替え(右から) */}
      <AnimatePresence mode="wait">
        <motion.div
          key={current}
          initial={{ opacity: 0, x: 60 }}
          animate={{ opacity: 1, x: 0 }}
          exit={{ opacity: 0, x: -60 }}
          transition={{ duration: 0.3, ease: 'easeInOut' }}
        >
          {ITEMS[current]}
        </motion.div>
      </AnimatePresence>

      {/* スケール切り替え */}
      <AnimatePresence mode="wait">
        <motion.div
          key={current}
          initial={{ opacity: 0, scale: 0.85 }}
          animate={{ opacity: 1, scale: 1 }}
          exit={{ opacity: 0, scale: 0.85 }}
          transition={{ duration: 0.3 }}
        >
          {ITEMS[current]}
        </motion.div>
      </AnimatePresence>

      <div>
        {ITEMS.map((_, i) => (
          <button key={i} onClick={() => setCurrent(i)}>{i}</button>
        ))}
      </div>
    </>
  );
}

jQueryで書くとこうなる

jQueryでは .fadeOut() のコールバック内で次のコンテンツを .fadeIn() する方法が一般的でした。Reactでは Framer Motion の AnimatePresence・React Spring の useTransition・GSAP の timeline().call() を使うことで、退場アニメーション完了後に次のコンテンツを表示する処理を宣言的・直感的に書けます。
js
// フェードで切り替え
$('#content-old').fadeOut(300, function () {
  $('#content-new').fadeIn(300);
});

// スライドで切り替え
$('#content-old').slideUp(300, function () {
  $('#content-new').slideDown(300);
});

// hide/show で即時切り替え(アニメーションなし)
$('#content-old').hide();
$('#content-new').show();

// animate() でカスタム切り替え
$('#content-old').animate({ opacity: 0 }, 300, function () {
  $(this).hide();
  $('#content-new').css({ opacity: 0 }).show().animate({ opacity: 1 }, 300);
});
💡 上記のデモは、React / Next.jsです。Next.jsの基本セットアップは 公式ドキュメントを参照してください。

実装方法の比較

項目Framer MotionReact SpringGSAPCSS Transition
退場アニメーションAnimatePresence + exitで自動制御useTransitionのleaveで退場アニメーションを定義timeline().to()で退場→call()→入場の順序を明示的に制御DOMに残したままopacityで隠す
切り替えタイミングmode="wait"で退場完了後に入場exitBeforeEnterで退場完了後に入場timeline()内でset/call/toを並べて順序を制御同時遷移のみ(前後の制御が困難)
keyによる制御keyが変わると自動でexit→enterが走るuseTransitionの第1引数が変わると自動でleave→enterが走る手動でfrom/toのrefを管理してtimeline()で実装手動でクラス付け外しが必要
設定コスト高:framer-motionのインストールが必要高:@react-spring/webのインストールが必要中:gsap + @gsap/reactのインストールが必要低:追加ライブラリ不要
実装のシンプルさ宣言的で直感的宣言的・from/enter/leaveの3段階で定義命令的だが順序が読みやすいクラス管理が煩雑になりやすい

AnimatePresence mode="wait" のポイント

  • AnimatePresence で囲むことで、コンポーネントのアンマウント時にも exit アニメーションが実行される
  • mode="wait" を指定すると、前の要素の exit アニメーション完了後に次の要素の initial → animate が始まる
  • key が変わると同じコンポーネントでも別要素として扱われ、exit → enter が自動で走る
  • • CSS Transitionでは退場完了のタイミングを検知しにくく、setTimeout でアニメーション時間と同じ待機が必要になる

🤖 AIプロンプトテンプレート

Next.js + Framer Motion でコンテンツの要素の切り替えを実装してください。
- ボタンクリックでコンテンツをフェード・スライド・スケールで切り替え
- AnimatePresence の mode="wait" を使って退場アニメーション完了後に入場させる
- key を使ってコンテンツの切り替えを検知する
- TypeScript / Tailwind CSS v4 を使用

⚠️ このプロンプトはあくまでたたき台です。AIの回答はモデルやバージョン、会話の文脈によって毎回異なります。意図通りに動かない場合は、条件を追記・修正してお使いください。

React Spring useTransition のポイント

  • useTransition(key, config) は第1引数の値が変わるとleave→enterアニメーションが自動で走る
  • from(初期値)・enter(入場後)・leave(退場時)の3段階でアニメーションを定義する
  • exitBeforeEnter: true でFramer Motionの mode="wait" 相当の動作になる
  • • レンダー関数で item(遷移中のキー値)を使って、退場要素と入場要素を個別に描画できる

🤖 AIプロンプトテンプレート

Next.js + React Spring でコンテンツの要素の切り替えを実装してください。
- useTransition を使ってコンテンツをフェード・スライド・スケールで切り替え
- exitBeforeEnter: true で退場アニメーション完了後に入場させる
- from / enter / leave でアニメーションの3段階を定義する
- 使用ライブラリ: @react-spring/web
- TypeScript / Tailwind CSS v4 を使用

⚠️ このプロンプトはあくまでたたき台です。AIの回答はモデルやバージョン、会話の文脈によって毎回異なります。意図通りに動かない場合は、条件を追記・修正してお使いください。

GSAP timeline のポイント

  • gsap.timeline().to() .set() .call() をチェーンして順番に実行する(Framer の mode="wait" を手動で再現)
  • .call(() => setCurrent(next)) でアニメーションの途中で React の state 更新を挟める
  • .set(el, { x: 40 }) で入場前の初期位置を瞬時にリセットしてから .to() でフェードインする
  • animating.current フラグで連打を防ぎ、onComplete で解除する実装が堅牢

🤖 AIプロンプトテンプレート

Next.js + GSAP でコンテンツの要素の切り替えを実装してください。
- useGSAP フックと contextSafe を使ってボタンクリックで切り替えをトリガー
- gsap.timeline() でフェード・スライド・スケールの退場→入場をシーケンシャルに実装
- .call() で state 更新を挟み、.set() で入場前の初期位置をリセットする
- fade / slide / scale のバリアントを切り替えるUIを実装する
- 使用ライブラリ: gsap, @gsap/react
- TypeScript / Tailwind CSS v4 を使用

⚠️ このプロンプトはあくまでたたき台です。AIの回答はモデルやバージョン、会話の文脈によって毎回異なります。意図通りに動かない場合は、条件を追記・修正してお使いください。

ページ・コンテンツの切り替えアニメーション(Transition)は、ビューやルートが変わるときに視覚的な連続性を与えるアニメーション効果。

ページ遷移・タブの切り替え・ステップフォームの進行・スライドショーなど、ユーザーが別のコンテンツに移動するときのUXを滑らかにしたい場面で使われる。

主なバリエーション
  • フェード型
  • スライド型(左右・上下)
  • スケール型(ズームイン/アウト)
  • フリップ型(3D回転)
  • 共有要素遷移型(Hero Animation)