motion について
インタラクティブな画面を開発する React 開発者向けのアニメーションスキルです。ジェスチャー、スクロール、レイアウト、終了時のアニメーションに加え、バンドルサイズやアクセシビリティの指針も扱います。
主な機能
- 01ジェスチャーとスクロールのアニメーション
- 02FLIPレイアウトと共有トランジション
- 03スプリング物理とSVGアニメーション
- 04AnimatePresenceによる終了時のアニメーション
- 05バンドルサイズの最適化ガイド
- 06動きを抑える設定へのアクセシビリティ対応
活用シーン
- 01ドラッグ&ドロップ画面の構築
- 02スクロール連動の表示や視差効果の追加
- 03ルートやレイアウトのトランジション
- 04Reactアプリのアニメーションバンドル最適化
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ marcioaltoe/ skills --skill motionインストール後、Claude Code で/motionを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
README.md.claude-plugin/plugin.jsonagents/openai.yamlreferences/common-patterns.mdmotion-vs-auto-animate.mdnextjs-integration.mdperformance-optimization.mdrules/motion.mdscripts/init-motion.shoptimize-bundle.shtemplates/layout-transitions.tsxmotion-nextjs-client.tsxmotion-vite-basic.tsxscroll-parallax.tsxui-components.tsx詳細
Motion アニメーションライブラリ
概要
Motion(パッケージ:motion、旧称:framer-motion)は、何千ものアプリケーションで本番環境に採用されている、業界標準の React アニメーションライブラリです。GitHub スター数は 30,200 件以上、公式サンプルは 300 件以上あり、少ないコードで高度なアニメーションを作成できる宣言的 API を提供します。
主な機能:
- ジェスチャー:ドラッグ、ホバー、タップ、パン、フォーカスに対応し、デバイスをまたいで利用できます
- スクロールアニメーション:ビューポートをトリガーにしたアニメーション、スクロール連動、視差効果
- レイアウトアニメーション:スムーズなレイアウト変更や共有要素のトランジションを実現する FLIP 手法
- スプリング物理:物理ベースのイージングによる、自然でカスタマイズ可能な動き
- SVG:パスのモーフィング、線の描画、属性のアニメーション
- 終了アニメーション:アンマウント時のトランジションを実現する AnimatePresence
- パフォーマンス:ハードウェアアクセラレーション、ScrollTimeline API、バンドルの最適化(2.3 KB~34 KB)
本番環境での検証済み:React 19.2、Next.js 16.1、Vite 7.3、Tailwind v4
このスキルを使うタイミング
✅ 次の場合は Motion を使用します:
複雑なインタラクション:
- ドラッグ&ドロップのインターフェース(並べ替え可能なリスト、カンバンボード、スライダー)
- 拡大・回転・色変更を伴うホバー状態
- バウンスやスクイーズ効果によるタップ時のフィードバック
- モバイル向け操作に適したパンジェスチャー
スクロールベースのアニメーション:
- 視差レイヤーを備えたヒーローセクション
- スクロールをトリガーにした表示(要素がビューポートに入るとフェードイン)
- スクロール位置に連動するプログレスバー
- スクロールに応じて変形するスティッキーヘッダー
レイアウトのトランジション:
- ルート間の共有要素のトランジション(カード → 詳細ページ)
- 高さを自動アニメーションする展開/折りたたみ
- スムーズな位置変更を伴うグリッド表示とリスト表示の切り替え
- アニメーション付き下線を備えたタブナビゲーション
高度な機能:
- SVG の線描画アニメーション
- 図形間のパスのモーフィング
- 自然なバウンスを実現するスプリング物理
- 調整されたシーケンス(段階的な表示)
- 背景のぼかしを伴うモーダルダイアログ
バンドルの最適化:
- 2.3 KB のアニメーションライブラリが必要な場合(useAnimate mini を使用)
- Motion を 34 KB から 4.6 KB に削減したい場合(LazyMotion)
❌ 次の場合は Motion を使用しないでください:
シンプルなリストアニメーション → 代わりに auto-animate スキルを使用します:
- Todo リストの追加/削除(auto-animate:3.28 KB、motion:34 KB)
- 検索結果のフィルタリング
- ショッピングカートの商品
- 通知トースト
- ジェスチャーのない基本的なアコーディオン
静的コンテンツ:
- ユーザーインタラクションやアニメーションが不要な場合
- クライアント側のインタラクティブ性がない、サーバーでレンダリングされるコンテンツ
Cloudflare Workers へのデプロイ → ✅ 修正済み(2024 年 12 月):
- 以前のビルド互換性の問題は解決済みです(GitHub issue #2918 は完了としてクローズ)
- Motion は Wrangler で直接動作するようになり、回避策は不要です
motionとframer-motionv12.23.24 の両方が正常に動作します
3D アニメーション → 専用の 3D ライブラリを使用します:
- WebGL には Three.js
- React と Three.js の組み合わせには React Three Fiber
インストール
最新の安定バージョン
# Using pnpm (recommended)
pnpm add motion
# Using npm
npm install motion
# Using yarn
yarn add motion
現在のバージョン:12.27.5(2026-01-21 に確認)
Cloudflare Workers についての注意:
# Both packages work with Cloudflare Workers (issue #2918 fixed Dec 2024)
pnpm add motion
# OR
pnpm add framer-motion # Same version, same API
パッケージ情報
- バンドルサイズ:
- フル機能の
motionコンポーネント:約 34 KB(圧縮後) LazyMotion+mコンポーネント:約 4.6 KBuseAnimatemini:2.3 KB(最小の React アニメーションライブラリ)useAnimatehybrid:17 KB
- フル機能の
- 依存関係:React 18 以降、または React 19 以降
- TypeScript:標準でサポート(@types パッケージは不要)
基本概念
1. AnimatePresence(終了アニメーション)
コンポーネントのアンマウント時にアニメーションを実行できます:
import { AnimatePresence } from "motion/react"
<AnimatePresence>
{isVisible && (
<motion.div
key="modal"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
>
Modal content
</motion.div>
)}
</AnimatePresence>
重要なルール:
- AnimatePresence はマウントされたままにする必要があります(条件分岐で囲まないでください)
- すべての子要素に一意の
keyprops が必要です - 条件分岐を AnimatePresence で囲みます。その逆ではありません
よくある間違い(終了アニメーションが再生されません):
// ❌ Wrong - AnimatePresence unmounts with condition
{isVisible && (
<AnimatePresence>
<motion.div>Content</motion.div>
</AnimatePresence>
)}
// ✅ Correct - AnimatePresence stays mounted
<AnimatePresence>
{isVisible && <motion.div key="unique">Content</motion.div>}
</AnimatePresence>
2. レイアウトアニメーション
特別な Props:
layout:FLIP レイアウトアニメーションを有効にしますlayoutId:別々の要素をつなげて、共有トランジションを実現しますlayoutScroll:スクロール可能なコンテナ内のアニメーションを修正します(Issue #5 を参照)layoutRoot:固定位置の要素のアニメーションを修正します(Issue #7 を参照)
<motion.div layout>
{isExpanded ? <FullContent /> : <Summary />}
</motion.div>
3. スクロールアニメーション
ビューポートをトリガーにする(whileInView)
<motion.div
initial={{ opacity: 0, y: 50 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true, margin: "-100px" }}
>
Fades in when 100px from entering viewport
</motion.div>
スクロールに連動する(useScroll)
import { useScroll, useTransform } from "motion/react"
const { scrollYProgress } = useScroll()
const y = useTransform(scrollYProgress, [0, 1], [0, -300])
<motion.div style={{ y }}>
Moves up 300px as user scrolls page
</motion.div>
パフォーマンス:利用可能な場合はネイティブの ScrollTimeline API を使用し、ハードウェアアクセラレーションを実現します。
統合ガイド
Vite + React + TypeScript
pnpm add motion
インポート:import { motion } from "motion/react"
Vite の設定は不要です。そのまま動作します。
Next.js App Router(推奨パターン)
重要な要件:Motion はクライアントコンポーネントでのみ動作します(サーバーコンポーネントでは動作しません)。
ステップ 1:クライアントコンポーネントのラッパーを作成する
src/components/motion-client.tsx:
"use client"
// Optimized import for Next.js (reduces client JS)
import * as motion from "motion/react-client"
export { motion }
ステップ 2:サーバーコンポーネントで使用する
src/app/page.tsx:
import { motion } from "@/components/motion-client"
export default function Page() {
return (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
>
This works in Server Component (wrapper is client)
</motion.div>
)
}
代替案:直接クライアントコンポーネントを使用する
"use client"
import { motion } from "motion/react"
export function AnimatedCard() {
return <motion.div>...</motion.div>
}
既知の問題(Next.js 15+ + React 19):
- React 19 は 2025 年 12 月時点で完全にサポートされています(StrictMode のエッジケースについては Issue #11 を参照)
- ほとんどの互換性問題は Motion 12.27.5 で解決されています
- AnimatePresence はソフトナビゲーションで失敗する場合があります
- Reorder コンポーネントは Next.js のルーティングおよびページレベルのスクロールと互換性がありません(Issue #10 を参照)
Next.js Pages Router
変更なしで動作します:
import { motion } from "motion/react"
export default function Page() {
return <motion.div>No "use client" needed</motion.div>
}
Tailwind CSS との統合
ベストプラクティス:それぞれのライブラリが得意なことを担当するようにします。
- Tailwind:
classNameによる静的スタイリングとレスポンシブスタイリング - Motion:Motion props によるアニメーション
<motion.button
className="bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700"
whileHover={{ scale: 1.1 }}
whileTap={{ scale: 0.95 }}
>
Tailwind styles + Motion animations
</motion.button>
⚠️ Tailwind のトランジションを削除してください:カクつきや競合の原因になります。
// ❌ Wrong - Tailwind transition conflicts with Motion
<motion.div className="transition-all duration-300" animate={{ x: 100 }} />
// ✅ Correct - Remove Tailwind transition
<motion.div animate={{ x: 100 }} />
理由:Motion はインラインスタイルまたはブラウザーのネイティブアニメーションを使用するため、どちらも Tailwind の CSS トランジションを上書きします。
Cloudflare Workers(✅ サポート済み)
ステータス:✅ 2024 年 12 月時点で修正済み(GitHub issue #2918 は完了としてクローズ)
インストール:
# Motion now works directly with Cloudflare Workers
pnpm add motion
インポート:
import { motion } from "motion/react"
**補足:**2024 年 12 月以前は Wrangler の ESM 解決に関する問題があり、回避策として framer-motion を使用する必要がありました。この問題は解決済みで、現在はどちらのパッケージも Cloudflare Workers で正しく動作します。
パフォーマンスの最適化
1. LazyMotion でバンドルサイズを削減する
問題:完全な motion コンポーネントは、圧縮後で約 34 KB です。
解決策:LazyMotion + m コンポーネントを使用すると 4.6 KB になります:
import { LazyMotion, domAnimation, m } from "motion/react"
function App() {
return (
<LazyMotion features={domAnimation}>
{/* Use 'm' instead of 'motion' */}
<m.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
>
Only 4.6 KB!
</m.div>
</LazyMotion>
)
}
仕組み:すべてをバンドルする代わりに、アニメーション機能を必要に応じて読み込みます。
代替案(最小サイズ):useAnimate mini(2.3 KB):
import { useAnimate } from "motion/react"
function Component() {
const [scope, animate] = useAnimate()
return <div ref={scope}>Smallest possible React animation</div>
}
2. ハードウェアアクセラレーション
変換に willChange を追加します:
<motion.div
style={{ willChange: "transform" }}
animate={{ x: 100, rotate: 45 }}
/>
次のプロパティにも追加します:opacity、backgroundColor、clipPath、filter
仕組み:ブラウザーにアニメーション向けの最適化を指示し、GPU コンポジットを使用します。
3. 大きなリスト → 仮想化を使用する
問題:50~100 個以上の項目をアニメーションすると、大幅に遅くなります。
解決策:
pnpm add react-window
# or
pnpm add react-virtuoso
# or
pnpm add @tanstack/react-virtual
パターン:
import { FixedSizeList } from 'react-window'
import { motion } from 'motion/react'
<FixedSizeList
height={600}
itemCount={1000}
itemSize={50}
>
{({ index, style }) => (
<motion.div style={style} layout>
Item {index}
</motion.div>
)}
</FixedSizeList>
理由:表示されている項目のみをレンダリングするため、DOM の更新とメモリー使用量を削減できます。
4. FLIP アニメーションには layout Prop を使用する
JavaScript で計算することなく、レイアウトの変更を自動でアニメーションします:
<motion.div layout>
{isExpanded ? <LargeContent /> : <SmallContent />}
</motion.div>
パフォーマンス:変換によってハードウェアアクセラレーションされるため、リフローや再描画は発生しません。
アクセシビリティ
prefers-reduced-motion を尊重する
import { MotionConfig } from "motion/react"
<MotionConfig reducedMotion="user">
<App />
</MotionConfig>
オプション:
"user":OS の設定を尊重します(推奨)"always":トランジションを常に即時にします"never":ユーザーの設定を無視します
注記:✅ 2023 年 1 月に修正済み(GitHub #1567)。MotionConfig は AnimatePresence と正しく動作するようになりました。
よくあるパターン
本番環境で使える5つのパターン:
- モーダルダイアログ - 背景とダイアログの退出アニメーションに
AnimatePresenceを使用 - アコーディオン -
height: "auto"で高さをアニメーション - ドラッグカルーセル -
drag="x"とdragConstraintsを使用 - スクロール時の表示 - ビューポートのマージンと
whileInViewを使用 - 視差効果のあるヒーローセクション -
useScroll+useTransformでレイヤー効果を実現
コード全体(15種類以上のパターン)は references/common-patterns.md を参照してください。
既知の問題と解決策
問題1:AnimatePresenceの退出アニメーションが動作しない
エラー:退出アニメーションが再生されず、コンポーネントが即座に消える 出典:GitHub Issue #3078
原因:AnimatePresence が条件分岐の中でラップされているか、key プロパティがありません。また、モーダル内のスタッガー表示された子要素に exit プロパティを定義すると、モーダルのアンマウントが妨げられる場合もあります(背景が表示されたままになります)。
解決策:
// ❌ Wrong - AnimatePresence wrapped in conditional
{isVisible && (
<AnimatePresence>
<motion.div>Content</motion.div>
</AnimatePresence>
)}
// ✅ Correct - AnimatePresence stays mounted
<AnimatePresence>
{isVisible && <motion.div key="unique">Content</motion.div>}
</AnimatePresence>
// ❌ Wrong - Staggered children with exit prevent modal removal
<AnimatePresence>
{isOpen && (
<Modal>
<motion.ul>
{items.map(item => (
<motion.li
key={item.id}
exit={{ opacity: 1, scale: 1 }} // ← Prevents modal unmount
>
{item.content}
</motion.li>
))}
</motion.ul>
</Modal>
)}
</AnimatePresence>
// ✅ Fix for modal - Remove exit from children or set duration: 0
<motion.li
key={item.id}
exit={{ opacity: 0, scale: 0.5, transition: { duration: 0 } }}
>
{item.content}
</motion.li>
問題2:大きなリストのパフォーマンス
症状:アニメーション付きの項目が50~100個以上あると、著しく遅くなり、ブラウザーがフリーズします。
解決策:仮想化を使用します:
pnpm add react-window
詳しいガイドは references/performance-optimization.md を参照してください。
問題3:Tailwindのトランジションとの競合
症状:アニメーションがカクつく、または動作しません。
解決策:transition-* クラスを削除します:
// ❌ Wrong
<motion.div className="transition-all" animate={{ x: 100 }} />
// ✅ Correct
<motion.div animate={{ x: 100 }} />
問題4:Next.jsでの "use client" の指定漏れ
症状:「motion is not defined」またはSSRエラーが発生してビルドに失敗します。
解決策:"use client" ディレクティブを追加します:
"use client"
import { motion } from "motion/react"
App Routerのパターンについては references/nextjs-integration.md を参照してください。
問題5:スクロール可能なコンテナーでのレイアウトアニメーション
症状:スクロールしたコンテナーから項目を削除すると、トランジションが不完全になります。
解決策:layoutScroll プロパティを追加します:
<motion.div layoutScroll className="overflow-auto">
{items.map(item => (
<motion.div key={item.id} layout>
{item.content}
</motion.div>
))}
</motion.div>
問題6:Cloudflare Workersのビルドエラー(✅ 解決済み)
ステータス:✅ 2024年12月に修正済み(GitHub issue #2918は完了としてクローズ)
以前の症状:motion パッケージの使用時に、WranglerのビルドがReactのインポートエラーで失敗していました。
現在の状況:MotionはCloudflare Workersで正常に動作するようになりました。回避策は不要です。
ビルドの問題が発生した場合:Motion v12.23.24以降とWrangler v3以降を使用していることを確認してください。
GitHub issue:#2918(2024年12月13日に完了としてクローズ)
問題7:固定位置要素でのレイアウトアニメーション
症状:固定位置要素のレイアウトアニメーションで、位置が正しく設定されません。
解決策:layoutRoot プロパティを追加します:
<motion.div layoutRoot className="fixed top-0 left-0">
<motion.div layout>Content</motion.div>
</motion.div>
問題8:layoutIdとAnimatePresenceによるアンマウント
症状:AnimatePresence 内の layoutId を持つ要素がアンマウントされません。
解決策:LayoutGroup でラップするか、退出アニメーションとレイアウトアニメーションの併用を避けます:
import { LayoutGroup } from "motion/react"
<LayoutGroup>
<AnimatePresence>
{items.map(item => (
<motion.div key={item.id} layoutId={item.id}>
{item.content}
</motion.div>
))}
</AnimatePresence>
</LayoutGroup>
問題9:AnimatePresenceでの動きを減らす設定(✅ 解決済み)
ステータス:✅ 2023年1月に修正済み(GitHub issue #1567はPR #1891によりクローズ)
以前の症状:MotionConfig の reducedMotion 設定がAnimatePresenceのアニメーションに反映されませんでした。
現在の状況:MotionConfig の reducedMotion はAnimatePresenceコンポーネントに正しく適用されるようになりました。設定はドキュメントどおりに動作します。
任意の手動制御:組み込みのサポートを超えるカスタム動作が必要な場合:
const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches
<motion.div
initial={{ opacity: prefersReducedMotion ? 1 : 0 }}
animate={{ opacity: 1 }}
transition={{ duration: prefersReducedMotion ? 0 : 0.3 }}
/>
GitHub issue:#1567(2023年1月13日に完了としてクローズ)
問題10:Reorderコンポーネントの制限
エラー:Reorderの自動スクロールが失敗する、またはNext.jsのルーティングで動作しない 出典:GitHub Issue #3469、#2183、#2101
原因:
- ページレベルのスクロール:Reorderの自動スクロールが動作するのは、
Reorder.Groupがoverflow: auto/scrollを持つ要素内にある場合のみです。ドキュメント自体がスクロール可能な場合は動作しません。 - Next.jsのルーティング:Next.jsのルーティングシステムと互換性がなく、ランダムに操作不能な状態になることがあります。
予防策:
// ❌ Wrong - Page-level scrolling (auto-scroll fails)
<body style={{ height: "200vh" }}>
<Reorder.Group values={items} onReorder={setItems}>
{/* Auto-scroll doesn't trigger at viewport edges */}
</Reorder.Group>
</body>
// ✅ Correct - Container with overflow
<div style={{ height: "300px", overflow: "auto" }}>
<Reorder.Group values={items} onReorder={setItems}>
{items.map(item => (
<Reorder.Item key={item.id} value={item}>
{item.content}
</Reorder.Item>
))}
</Reorder.Group>
</div>
// ✅ Alternative - Use DnD Kit for complex cases
// Motion docs officially recommend DnD Kit for:
// - Multi-row reordering
// - Dragging between columns
// - Page-level scrollable containers
// - Complex drag-and-drop interactions
// Install: pnpm add @dnd-kit/core @dnd-kit/sortable @dnd-kit/utilities
Next.jsの詳しいトラブルシューティングガイドは references/nextjs-integration.md を参照してください。
問題 11:React 19 StrictMode のドラッグバグ
エラー:ファイルツリーで上から下へドラッグすると、ドラッグ操作が正常に動作しません 発生元:GitHub Issue #3169
原因:React 19 + StrictMode が有効 + Ant Design コンポーネントの組み合わせでのみ発生します。ドラッグした要素の位置が崩れ、ずれて表示されます。React 18、または StrictMode を使用しない React 19 では発生しません。上から下へのドラッグにのみ影響し(下から上へのドラッグは正常に動作します)。
回避策:ドラッグ操作を使用する React 19 プロジェクトでは、一時的に StrictMode を無効にするか、StrictMode が重要な場合は React 18 を使用してください。Motion チームによる公式修正をお待ちください。
問題 12:拡大縮小されたコンテナ内でのレイアウトアニメーション
エラー:拡大縮小された親コンテナ内で、レイアウトアニメーションが誤った位置から開始します 発生元:GitHub Issue #3356
原因:レイアウトアニメーションシステムが、拡大縮小された座標を未拡大の座標として扱います。Motion のレイアウトアニメーションはピクセル単位で動作しますが、親の拡大縮小は視覚上の座標に影響します。この不一致によって、位置の計算エラーが発生します。
回避策(コミュニティによる回避策):
// Use transformTemplate to correct for parent scale
const scale = 2; // Parent's transform scale value
<div style={{ transform: `scale(${scale})` }}>
<motion.div
layout
transformTemplate={(latest, generated) => {
const match = /translate3d\((.+)px,\s?(.+)px,\s?(.+)px\)/.exec(generated);
if (match) {
const [, x, y, z] = match;
return `translate3d(${Number(x) / scale}px, ${Number(y) / scale}px, ${Number(z) / scale}px)`;
}
return generated;
}}
>
Content
</motion.div>
</div>
制限事項:レイアウトアニメーションにのみ有効で、ほかのトランスフォームは修正されません。また、親の拡大率を把握している必要があります。
問題 13:アンマウント時に AnimatePresence の終了状態が解除されない
エラー:終了アニメーション中に子要素がアンマウントされると、終了状態のままになります 発生元:GitHub Issue #3243
原因:AnimatePresence 内の子コンポーネントが終了アニメーションの開始直後にアンマウントされると、終了状態のままになります。コンポーネントが誤って「終了」状態にとどまります。
回避策:AnimatePresence が終了処理を行っている間は、motion コンポーネントをアンマウントしないでください。終了処理が完了するまで motion.div がマウントされた状態を保つようにしてください。条件付きレンダリングは、親である AnimatePresence の子要素にのみ使用してください。
問題 14:パーセント値によって Flex コンテナ内のレイアウトアニメーションが壊れる
エラー:レイアウトアニメーションがスムーズに動かず、瞬時に移動します 発生元:GitHub Issue #3401
原因:initial プロパティでパーセントベースの x 値を使用すると、コンテナが display flex と justify-content center を使用している場合に、レイアウトアニメーションが壊れます。Motion のレイアウトアニメーションはピクセル単位で動作しますが、CSS のパーセント指定のトランスフォームは要素または親要素を基準に解決されます。座標系の不一致によって、フレームの途中で位置が再計算されます。
回避策:アニメーションの前にパーセント値をピクセル値に変換してください。コンテナの幅を計算し、パーセント文字列ではなくピクセル値を使用してください。
問題 15:popLayout モードでのサブピクセル精度の損失
エラー:終了トランジションが始まる直前に 1px のレイアウトずれが発生します 発生元:GitHub Issue #3260
原因:AnimatePresence で mode popLayout を使用すると、終了する要素の寸法が取得され、インラインスタイルとして再適用されます。getBoundingClientRect で取得したサブピクセル値が最も近い整数に丸められるため、目に見えるレイアウトずれが発生します。テキストの折り返しが変わる場合もあります。
回避策:寸法には整数のピクセル値のみを使用するか、サブピクセル精度が重要なレイアウトでは popLayout を使用しないでください。完全な回避策はありません。
テンプレート
このスキルには、templates/ ディレクトリに 5 つの本番環境向けテンプレートが含まれています。
- motion-vite-basic.tsx - 一般的なアニメーションを含む Vite + React + TypeScript の基本セットアップ
- motion-nextjs-client.tsx - クライアントコンポーネントのラッパーを使用する Next.js App Router のパターン
- scroll-parallax.tsx - スクロールアニメーション、パララックス、ビューポートトリガー
- ui-components.tsx - モーダル、アコーディオン、カルーセル、共有下線付きタブ
- layout-transitions.tsx - FLIP レイアウトアニメーションと共有要素のトランジション
テンプレートをプロジェクトにコピーし、必要に応じてカスタマイズしてください。
参考資料
このスキルには、包括的なリファレンスガイドが4つ含まれています。
- motion-vs-auto-animate.md - 選択ガイド:Motion と AutoAnimate の使い分け
- performance-optimization.md - バンドルサイズ、LazyMotion、仮想化、ハードウェアアクセラレーション
- nextjs-integration.md - App Router と Pages Router、「use client」、既知の問題
- common-patterns.md - コード例をすべて掲載した上位15のパターン
詳しいガイドについては、references/ ディレクトリをご覧ください。
スクリプト
このスキルには、自動化スクリプトが2つ含まれています。
- init-motion.sh - フレームワークを検出してワンコマンドでセットアップ(Vite、Next.js、Cloudflare Workers)
- optimize-bundle.sh - 既存の Motion コードを LazyMotion に変換してバンドルサイズを削減
自動化ツールについては、scripts/ ディレクトリをご覧ください。
公式ドキュメント
- 公式サイト:https://motion.dev
- React ドキュメント:https://motion.dev/docs/react
- GitHub:https://github.com/motiondivision/motion(スター数30,200以上)
- サンプル:https://motion.dev/examples(ソースコード付きサンプル300以上)
- npm パッケージ:https://www.npmjs.com/package/motion
関連スキル
- auto-animate - リストの追加/削除/並べ替えなど、シンプルなアニメーション向け(3.28 KB 対 34 KB)
- tailwind-v4-shadcn - スタイル設定の統合
- nextjs - Next.js App Router のパターン
- cloudflare-worker-base - デプロイ(Motion は現在、完全に互換性があります)
比較:Motion と AutoAnimate
| 項目 | AutoAnimate | Motion |
|---|---|---|
| バンドルサイズ | 3.28 KB | 2.3 KB(mini)- 34 KB(full) |
| 用途 | シンプルなリストアニメーション | 複雑なジェスチャー、スクロール、レイアウト |
| API | 設定不要、1行 | 宣言的な props、多めの記述 |
| セットアップ | 単一の ref | Motion コンポーネント + props |
| ジェスチャー | ❌ 非対応 | ✅ ドラッグ、ホバー、タップ、パン |
| スクロールアニメーション | ❌ 非対応 | ✅ 視差、スクロール連動 |
| レイアウトアニメーション | ❌ 非対応 | ✅ FLIP、共有要素 |
| SVG | ❌ 非対応 | ✅ パスのモーフィング、線の描画 |
| Cloudflare Workers | ✅ 完全対応 | ✅ 完全対応(2024年12月に修正) |
| アクセシビリティ | ✅ prefers-reduced-motion を自動適用 | ✅ MotionConfig を手動で設定 |
目安:ケースの90%(リストアニメーション)には AutoAnimate、10%(複雑なインタラクション)には Motion を使用してください。
詳しい比較については、references/motion-vs-auto-animate.md をご覧ください。
トークン効率の指標
| 方法 | 使用トークン数 | 発生したエラー | 完了までの時間 |
|---|---|---|---|
| 手動セットアップ | ~30,000 | 3~5(AnimatePresence、Next.js、パフォーマンス) | ~2~3時間 |
| このスキルを使用 | ~5,000 | 0 ✅ | ~20~30分 |
| 削減率 | ~83% | 100% | ~85% |
防止したエラー:記録済みの35件のエラーを100%防止
パッケージバージョン(2026-01-21確認済み)
| パッケージ | バージョン | 状態 |
|---|---|---|
| motion | 12.27.5 | ✅ 最新の安定版 |
| framer-motion | 12.27.5 | ✅ motion と同じバージョン |
| react | 19.2.3 | ✅ 最新の安定版 |
| next | 16.1.1 | ✅ 最新の安定版 |
| vite | 7.3.1 | ✅ 最新の安定版 |
コントリビューション
問題を見つけた場合や提案がある場合:
- issue を作成:https://github.com/jezweb/claude-skills/issues
- 詳しい例については、テンプレートとリファレンスをご覧ください
本番環境でのテスト済み:✅ React 19.2 + Next.js 16.1 + Vite 7.3 + Tailwind v4 トークン削減率:~83% エラー防止率:100%(記録済みのエラー35件を防止) バンドルサイズ:2.3 KB(mini)- 34 KB(full)、LazyMotion で 4.6 KB まで最適化可能 アクセシビリティ:MotionConfig の reducedMotion サポート 最終確認日:2026-01-21 | スキルバージョン:3.1.0 | 変更内容:React 19/レイアウトアニメーション関連の問題を5件追加し、Motion 12.27.5 に更新