アニメーションシステムアーキテクト は何をしますか?
Framer Motion、GSAP、View Transitions API、スプリング物理を使用して、パフォーマンスが高くアクセシブルなアニメーションシステムを構築します。
アクティベーショントリガー
有効化するタイミング: ページ遷移、レイアウトアニメーション、スクロールトリガーアニメーション、マイクロインタラクション、スプリング物理、motion.div、gsap.to、View Transition API、共有要素トランジション、スaggeredリストアニメーション。
使用しないタイミング: CSSのみのホバー/フォーカスエフェクト -- 代わりに css-in-js-architect を使用。Canvas/WebGL レンダリング -- 代わりに creative-coding-expert を使用。Lottieファイルの再生 -- 代わりに標準のLottie統合を使用。
クイックスタート
- エンジンを選択 -- React宣言的ならFramer Motion、タイムライン重視または非ReactならGSAP、ページ間ナビゲーションならView Transitions API。
- transform と opacity のみをアニメーション -- これらはコンポジットスレッド(GPU)で動作し、レイアウトスラッシングを回避します。
will-changeは控えめに -- アニメーション中の要素にのみ適用し、完了後に削除します。prefers-reduced-motionを尊重 -- 設定しているユーザーにはすべてのアニメーションを無効化または簡略化します。- DevToolsでプロファイリング -- Performanceタブ > アニメーション中のレイアウトシフトを確認。
コア機能
| ドメイン | 技術 | 主要パターン |
|---|---|---|
| 宣言的React | Framer Motion 11+、motion コンポーネント | レイアウトアニメーション、AnimatePresence、バリアント |
| タイムラインアニメーション | GSAP 3.12+、ScrollTrigger | スクロール駆動シーケンス、ピン留め、スクラブ |
| ページ遷移 | View Transitions API、Next.js useViewTransition | クロスページ共有要素トランジション |
| スプリング物理 | Framer Motion スプリング、react-spring | 自然なイージング、割り込み可能なアニメーション |
| マイクロインタラクション | CSSトランジション + Framer Motion | ボタンフィードバック、ホバー状態、ローディングインジケーター |
| スクロール駆動 | CSS animation-timeline: scroll()、GSAP ScrollTrigger | パララックス、進捗インジケーター、スクロールで表示 |
アーキテクチャパターン
パターン1: Framer Motion レイアウトアニメーション
import { motion, AnimatePresence, LayoutGroup } from 'framer-motion';
function FilterableGrid({ items, filter }: Props) {
const filtered = items.filter(item => item.category === filter);
return (
<LayoutGroup>
<motion.div layout className="grid grid-cols-3 gap-4">
<AnimatePresence mode="popLayout">
{filtered.map(item => (
<motion.div
key={item.id}
layout // 位置の変化をアニメーション
initial={{ opacity: 0, scale: 0.8 }}
animate={{ opacity: 1, scale: 1 }}
exit={{ opacity: 0, scale: 0.8 }}
transition={{ type: 'spring', stiffness: 300, damping: 25 }}
>
<Card item={item} />
</motion.div>
))}
</AnimatePresence>
</motion.div>
</LayoutGroup>
);
}
パターン2: ページナビゲーションのための View Transitions API
// app/components/TransitionLink.tsx
'use client';
import { useRouter } from 'next/navigation';
import { useCallback } from 'react';
export function TransitionLink({ href, children }: { href: string; children: React.ReactNode }) {
const router = useRouter();
const handleClick = useCallback((e: React.MouseEvent) => {
e.preventDefault();
if (!document.startViewTransition) {
router.push(href);
return;
}
document.startViewTransition(() => {
router.push(href);
});
}, [href, router]);
return <a href={href} onClick={handleClick}>{children}</a>;
}
/* view-transition-name による共有要素トランジション */
.product-image {
view-transition-name: product-hero;
}
::view-transition-old(product-hero) {
animation: fade-and-scale 0.3s ease-out;
}
::view-transition-new(product-hero) {
animation: fade-and-scale 0.3s ease-in reverse;
}
パターン3: Reduced Motion の尊重
import { useReducedMotion } from 'framer-motion';
function AnimatedComponent() {
const shouldReduce = useReducedMotion();
return (
<motion.div
initial={{ opacity: 0, y: shouldReduce ? 0 : 20 }}
animate={{ opacity: 1, y: 0 }}
transition={shouldReduce
? { duration: 0 }
: { type: 'spring', stiffness: 260, damping: 20 }
}
>
Content
</motion.div>
);
}
┌─ アニメーション意思決定ツリー ────────────────────┐
│ │
│ prefers-reduced-motion? │
│ ├── YES → インスタントな透過フェードのみ(モーション無し)│
│ └── NO → フルスプリング/トランスフォームアニメーション │
│ │
│ 何をアニメーションする? │
│ ├── transform/opacity → GPUコンポジット(良好) │
│ ├── width/height → レイアウトスラッシング(回避) │
│ └── box-shadow → ペイントのみ(許容範囲) │
└───────────────────────────────────────────────────┘
アンチパターン
width、height、top、leftのアニメーション -- 毎フレームレイアウトの再計算を引き起こします。代わりにtransform: translate/scaleを使用して60fpsを維持しましょう。- 全ての要素に
will-changeを指定 -- レイヤーがGPUに過剰に昇格され、メモリ使用量が増加します。アニメーション中の要素にのみ適用しましょう。 prefers-reduced-motionを無視 -- モーションに敏感なユーザーが吐き気や発作を引き起こす可能性があります。必ずこのメディアクエリをチェックし尊重しましょう。- マイクロインタラクションのアニメーション時間が500msを超える -- UIがもっさりした印象になります。ボタン/ホバーフィードバックは200ms未満、ページ遷移は400ms未満に抑えましょう。
requestAnimationFrameや ScrollTrigger を使用せずにスクロール中にアニメーション -- カクつきの原因になります。スクロール駆動アニメーションにはGSAP ScrollTrigger または CSSanimation-timeline: scroll()を使用しましょう。
品質チェックリスト
- すべてのアニメーションが
transformとopacity(コンポジターに優しいプロパティ)を使用している -
prefers-reduced-motionがuseReducedMotionまたはCSSメディアクエリで尊重されている - マイクロインタラクションが200ms未満、ページ遷移が400ms未満である
- マウント/アンマウントアニメーションに
AnimatePresenceが使用されている - レイアウトアニメーションにFramer Motionの
layoutプロパティが使用されている(手動の位置計算ではない) -
will-changeがアニメーション中のみ適用され、完了後に削除されている - Chrome DevToolsのPerformanceパネルでカクつきがない(16msを超える長いフレームがない)
- アニメーションが割り込み可能である(固定キーフレーム+
easeではなく、スプリング物理を使用) - View Transitions APIに未対応ブラウザ向けのフォールバックがある
- スクロール駆動アニメーションに
animation-timelineまたは ScrollTrigger が使用されている(スクロールイベントリスナーではない)