Webアニメーション
優れたWebの動きは、まずデザイン上の判断であり、次にライブラリ呼び出しです。以下のワークフローを順に実行し、ルールファイルは必要な手順のときだけ読み込んでください。
ワークフロー
1. ツールを選ぶ前にプロジェクトを読む
package.jsonを確認します。アニメーションライブラリがすでにインストールされている場合は、それを使用してください。 単一のエフェクトのために新しいライブラリを追加しないでください。- フレームワーク(React / Next.js App Router / Vue / Svelte / プレーンHTML)と、コンポーネントがサーバーでレンダリングされるかどうかを確認します(Next.jsでクライアントサイドモーションを使用するには
"use client"が必要です)。 - CSS変数やテーマファイルに既存のモーショントークン(duration、easing)がないか確認し、それらを再利用します。
2. モーションの目的を決める
すべてのアニメーションには役割があります。要素ごとに1つを選びます:
| 役割 | 例 | 標準的な時間 |
|---|---|---|
| フィードバック — アクションを確認する | ボタン押下、トグル、クリップボードコピー | 100–200ms |
| 方向性 — 要素の移動元や移動先を示す | モーダルがトリガーから開く、リストアイテムの並び替え、ルート変更 | 200–400ms |
| 注目 — 1つのものに焦点を当てる | ヒーローシーケンス、新しい通知 | 400–1200ms、1回限り |
| ナラティブ — スクロールに連動したストーリーを伝える | 固定表示の製品ウォークスルー、スクラブタイムライン | スクロール距離に依存 |
要素に役割がない場合は、アニメーションさせないでください。すべてのセクションをフェードアップさせるよりも、1つのオーケストレーションされた瞬間のほうが効果的です。duration、easing、振付、および「プレミアム感」チェックリストについては、rules/motion-design.mdを参照してください。
3. 仕事を果たせる最も軽量なツールを選ぶ
プラットフォームを優先し、次にライブラリを検討します:
| ニーズ | 使用するもの | ルールファイル |
|---|---|---|
| ホバー、フォーカス、プレス、単純なループ | CSS transitions / @keyframes | css-keyframes.md |
| ダイアログ、ポップオーバー、ドロップダウンの出現 および 消滅 | CSS @starting-style + transition-behavior: allow-discrete | css-keyframes.md |
| ページ/ルート遷移、状態間の共有要素モーフィング | View Transitions API | view-transitions.md |
| 単純なスクロール連動表示、プログレスバー、パララックス | CSS animation-timeline: view() / scroll() | scroll-animations.md |
| 固定セクション、スクラブ可能なマルチステップタイムライン、水平スクロール | GSAP + ScrollTrigger | gsap.md |
| テキスト分割 / ラインマスク見出し表示 | GSAP SplitText | gsap.md |
| React 出現/消滅、レイアウトおよび共有レイアウトアニメーション、ジェスチャー | Motion for React(motion/react) | framer-motion.md |
| フレームワーク不要の命令的アニメーション、スプリング | Motion(motion) | motion-one.md |
| GSAPを使わないSVG線描画とモーフィング | Anime.js v4(svg.createDrawable、svg.morphTo) | animejs.md |
| 関連性のない形状間の複雑なパスモーフィング | Flubber(またはGSAP MorphSVG) | flubber.md |
| After Effectsアニメーションの再生 | Lottie(dotLottie) | lottie.md |
| インタラクティブでステート駆動のイラストアニメーション | Rive | rive.md |
| アニメーション化されたチャート | D3 transitions | d3.md |
| 多数のインタラクティブな2D形状(エディター、図) | Konva | konva.md |
| 3D、パーティクル、シェーダー | Three.js / React Three Fiber | three-js.md |
選択が明確でない場合は、rules/choosing-library.mdを参照してください。
4. 非妥協ルールに従って実装する
以下のルールは、すべてのアニメーション、すべてのライブラリに適用されます:
transformとopacityをアニメーションさせる。width、height、top、left、marginをアニメーションさせるのは避けます。レイアウト変更にはscale/translate、FLIP(GSAP Flip、Motionlayout)、View Transitionsを使用してください。rules/performance.mdを参照。prefers-reduced-motionを尊重する。 移動を透明度フェードまたは瞬間的な変更に置き換えます。コンテンツの出現を完全に削除して非表示のままにしないでください。スクロールスクラブ効果は静的になるべきです。- JSが実行されるまでコンテンツを非表示にしない。 初期の非表示状態はJSで(または
.jsクラスの背後で)設定し、スクリプトが失敗してもコンテンツが表示されるようにします。SSRでは、最初のペイント前に初期スタイルを適用することで、表示→非表示のフラッシュを避けてください。 - クリーンアップする。 アンマウント時にアニメーションを元に戻すか強制終了します(
useGSAP、createScope().revert()、gsap.context)。ルート変更時にはScrollTriggerを強制終了します。 - インタラクションの応答性を維持する。 ユーザーがトリガーするものには中断可能なアニメーションを使用します。2回目のクリックが1回目の後ろでキューイングされてはなりません。アニメーションの終了を待つために入力をブロックしてはいけません。
- フォーカスをアニメーションで遠ざけない。 移動する要素は可視の
:focus-visible状態を維持する必要があり、アニメーションするダイアログはフォーカスを正しく移動させる必要があります。
5. 実際のブラウザで検証する
コードを読んだだけでアニメーションが完了したと報告しないでください。実際に実行して以下を確認します:
- アニメーションが再生され、最終状態がデザインと一致する(途中と静止時のスクリーンショット)。
- コンソールエラーがなく、開始時にレイアウトシフトが発生しない。
-
prefers-reduced-motion: reduceをエミュレートし、縮小版が機能し、コンテンツが表示されることを確認する。 - モバイル幅にリサイズする:固定セクションと分割テキストがまだ機能する(リサイズ時に再分割)。
- スクロール駆動の効果が下方向だけでなく上方向にも機能し、ページ途中での再読み込み後も機能する。
- パフォーマンスパネル:アニメーション中に長いフレームがなく、アニメーションプロパティによるレイアウト/ペイントスパイクがない。
最小限のスタート地点
// GSAP + ScrollTrigger (npm i gsap)
import gsap from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
gsap.registerPlugin(ScrollTrigger);
gsap.from(".card", {
y: 40, opacity: 0, duration: 0.8, ease: "expo.out", stagger: 0.08,
scrollTrigger: { trigger: ".cards", start: "top 80%" },
});
// Motion for React (npm i motion)
import { motion, AnimatePresence } from "motion/react";
<AnimatePresence>
{open && (
<motion.div
key="panel"
initial={{ opacity: 0, y: 8 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: 8 }}
transition={{ type: "spring", duration: 0.35, bounce: 0 }}
/>
)}
</AnimatePresence>
/* プラットフォームのみのスクロール表示:Chrome 115+、Safari 26+、Firefox 159+ */
@media (prefers-reduced-motion: no-preference) {
@supports (animation-timeline: view()) {
.reveal {
animation: reveal linear both;
animation-timeline: view();
animation-range: entry 10% cover 30%;
}
}
}
@keyframes reveal { from { opacity: 0; translate: 0 2rem; } }
ルールファイル
- rules/motion-design.md — duration、easing、振付、動きをプレミアムに感じさせるもの
- rules/choosing-library.md — 判断フロー、能力マトリックス、計測されたバンドルサイズ
- rules/performance.md — コンポジタ専用プロパティ、プロファイリング、
will-change、動きの抑制 - rules/scroll-animations.md — CSSスクロールタイムライン、ScrollTriggerパターン、スムーススクロール
- rules/view-transitions.md — 同一ドキュメントおよびクロスドキュメントのページ遷移
- rules/css-keyframes.md — transitions、
@keyframes、@starting-style、linear()easing - rules/gsap.md — タイムライン、ScrollTrigger、SplitText、Flip、
useGSAP - rules/framer-motion.md — Motion for React:variants、
AnimatePresence、layout、gestures - rules/motion-one.md — Motion vanilla JS:
animate、sequences、scroll、inView - rules/animejs.md — Anime.js v4:タイムライン、stagger、SVG描画とモーフィング
- rules/lottie.md — dotLottieプレーヤー、コントロール、イベント
- rules/rive.md — ステートマシンと入力
- rules/d3.md — データ結合transition
- rules/flubber.md — パスモーフィング
- rules/konva.md — キャンバス2D形状とトゥイーン
- rules/three-js.md — シーン、R3F、パフォーマンス
これらのテクニックの実用的な例はdemos/にあります。