mcpField
U
ui-animation

ui-animation

github.com/lukasstricklerデザイン・UI453 回インストール35 週間前に更新
リポジトリ

ui-animation について

UI アニメーション設計のワークフロー型スキルです。タイミング、Motion と CSS/Tailwind の手法、アクセシビリティ、性能を案内し、画面遷移やジェスチャー、レイアウト変更を実装する開発者向けです。

主な機能

  1. 01アニメーション種別に応じた手法選択
  2. 02イージングと時間の指針
  3. 03Motion のジェスチャーとレイアウト遷移
  4. 04視差効果を減らす設定への配慮
  5. 05性能とフォーカスの確認
  6. 06再利用可能なアニメーション例

活用シーン

  1. 01モーダルやドロップダウンの表示・終了効果
  2. 02ジェスチャー操作やレイアウト変更のアニメーション
  3. 03視差効果を減らすユーザー向けの調整
  4. 04アニメーション性能とフォーカス動作の確認

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/lukasstrickler/ai-dev-atelier --skill ui-animation

インストール後、Claude Code で/ui-animationを入力して読み込まれたか確認します。

同梱ファイルreferences/recipes.md

詳細

UI アニメーション

適切なタイミング、アクセシビリティ、パフォーマンスを備えた、洗練された UI アニメーションです。

クイックスタート

手法の選択:

  • シンプルなトランジション? → CSS/Tailwind(transition-*、animate-*)
  • アンマウントを伴う表示/非表示? → Motion と AnimatePresence
  • ジェスチャー駆動? → Motion のスプリング
  • レイアウト変更? → Motion の layout プロパティ

基本の流れ: イージングの決定ツリー → 期間のガイドライン → 実装 → アクセシビリティの追加 → 検証

基本原則

  1. 自然な動き:物理法則を模倣します。線形イージングは避けてください。一定の速度で動くものはありません。
  2. 目的を持たせる:すべてのアニメーションに意味を持たせてください。利点を説明できない場合は削除します。
  3. 速くする:UI アニメーションは 300ms 未満にします。ホバー効果は 150ms 未満にします。500ms を超えると遅く感じられます。
  4. 中断可能にする:ジェスチャー駆動のアニメーションにはスプリングを使います。中断を自然に処理できます。
  5. アクセシブルにする:常に prefers-reduced-motion を尊重します。これは必須です。

ワークフロー

ステップ 1:アニメーションの種類を分類する
種類例手法
マイクロインタラクションボタンの押下、切り替え、チェックボックスCSS/Tailwind
表示/非表示モーダル、トースト、ドロップダウンMotion と AnimatePresence
レイアウト変更アコーディオン、並べ替え、展開Motion の layout プロパティ
共有要素タブインジケーター、カードの展開Motion の layoutId
ジェスチャードラッグ、スワイプ、引っ張って更新Motion のスプリング
ステップ 2:タイミングを選択する
  1. 以下のイージングの決定ツリーを使って曲線を選択します
  2. 期間のガイドラインを使ってタイミングを選択します
  3. ジェスチャーには、スプリングアニメーションの設定を使います
ステップ 3:実装する
  1. コピーして使えるパターンを references/recipes.md で確認します
  2. ステップ 2 で選んだタイミングを適用します
  3. アンマウントされる要素を AnimatePresence で囲みます

デザインのスクリーンショットやモックアップから開始する場合は、ui_to_artifact を使います。想定した UI と実装済みの UI を比較するには、ui_diff_check を使います。

ステップ 4:アクセシビリティ(必須)
  1. useReducedMotion() または motion-safe: で prefers-reduced-motion を確認します
  2. 動きを抑える設定を使うユーザー向けに、不透明度のみの表現へ簡略化します
  3. フォーカスのタイミングを確認します(アニメーションの開始後にフォーカスを移動します)
ステップ 5:検証する
  • 終了アニメーションが実行される(即座にアンマウントされない)
  • opacity: 0 の要素に pointerEvents: none が設定されている
  • アニメーションの開始前ではなく、開始後にフォーカスが移動する
  • アニメーション対象が transform と opacity のみである

イージング

決定ツリー
What triggers the animation?
│
├─ User action (click, tap, open)?
│  └─ Use: ease-out (fast start, slow end = responsive)
│
├─ Element moving on-screen (tab switch, reorder)?
│  └─ Use: ease-in-out (accelerate then decelerate)
│
├─ Continuous/looping (spinner, marquee)?
│  └─ Use: linear (constant speed appropriate here)
│
├─ Gesture-based (drag, swipe, pull)?
│  └─ Use: Spring animation (physics-based, interruptible)
│
└─ Hover/focus effect?
   └─ Use: CSS ease, 150ms (subtle, immediate)
クイックリファレンス
用途CSSTailwind期間
モーダル/ドロワーの表示cubic-bezier(0.32, 0.72, 0, 1)ease-out duration-200200ms
モーダル/ドロワーの非表示cubic-bezier(0.32, 0.72, 0, 1)ease-out duration-150150ms
画面上の移動cubic-bezier(0.4, 0, 0.2, 1)ease-in-out duration-200200-300ms
ホバー効果easeease duration-150150ms
ボタンの押下—active:scale-[0.97]即時
プロ向けの曲線
名前値使用例
Vaul(バターのように滑らか)cubic-bezier(0.32, 0.72, 0, 1)シート、ドロワー、モーダル
強調cubic-bezier(0.2, 0, 0, 1)Material Design 3
キビキビした動きcubic-bezier(0.25, 1, 0.5, 1)すばやい UI トランジション

避けるもの:組み込みの ease-in。始まりが遅く、もたついて感じられます。

期間のガイドライン

種類期間備考
マイクロフィードバック100-150msボタンの押下、切り替え、チェックボックス
小さなトランジション150-250msツールチップ、アイコンの変形
中程度のトランジション200-300msモーダル、ポップオーバー、ドロップダウン
大きなトランジション300-400msページ遷移、複雑なレイアウト
最大<500ms例外:オンボーディング、データビジュアライゼーション

重要なルール:

  • 表示より非表示を速くする:表示 200ms → 非表示 150ms
  • ホバーは速くする:150ms 未満
  • 高頻度の操作は即時にする:キーボード操作、スクロールは 100ms 未満、またはアニメーションなし

スプリングアニメーション

Duration-based(推奨)

ほかの時間指定アニメーションと組み合わせやすくなります。visualDuration(目標に視覚的に到達するまでの時間)と bounce(0 = バウンスなし、1 = 強いバウンス)を使用します。

印象設定使用例
キビキビ{ duration: 0.3, bounce: 0.15 }タブ、ボタン、素早いフィードバック
標準{ duration: 0.4, bounce: 0.2 }モーダル、メニュー、一般的な UI
穏やか{ duration: 0.5, bounce: 0.25 }滑らかで、人間らしい動き
物理ベース(レガシー/上級者向け)

物理ライブラリとの統合時や、スプリングの動きを細かく制御する必要がある場合に使用します。

印象設定使用例
キビキビ{ stiffness: 400, damping: 30 }高頻度のインタラクション
標準{ stiffness: 300, damping: 20 }Framer Handshake の規約
穏やか{ stiffness: 120, damping: 14 }react-motion のプリセット

注意点:stiffness/damping/mass は duration/bounce を上書きします。どちらか一方の方法を選び、混在させないでください。

レイアウトアニメーション

layout プロパティ

layout を追加すると、位置やサイズの変化が自動的にアニメーションされます。テキストには layout="position" を使用してください(歪みを防ぎます)。

プロパティ値効果使用例
layout={true}位置とサイズをアニメーション柔軟にサイズが変わる要素のデフォルト
layout="position"移動のみをアニメーション引き伸ばしたくないテキスト/アイコン
layout="size"寸法のみをアニメーション固定位置にある展開式パネル
共有要素のトランジション(layoutId)

一致する layoutId を持つ要素は、表示時/非表示時に互いの間でアニメーションします。

重大な落とし穴:layoutId の値が重複すると、要素がページ上を瞬間移動します。コンテキストごとに一意の ID を使用するか、<LayoutGroup id="..."> で囲んでください。

レイアウトに関する注意点
  • テキストの歪み:テキスト要素には layout="position" を適用してください
  • 境界線の角丸:拡大縮小中に歪むことがあります。Motion が自動補正しますが、テストしてください
  • SVG 要素:layout は <path> では機能しません。手動でモーフィングしてください

ジェスチャーに関する注意点

問題解決策
タッチスクロールとの競合dragPropagation={false}
要素が元の位置に戻るdragConstraints と dragElastic を確認
慣性が不自然精密な UI では dragMomentum={false}
1 方向のみdragElastic={{ top: 0, bottom: 0.5 }}

スワイプで閉じる場合:距離と速度の両方を確認してください。ユーザーはフリックでも動作することを期待しています。

アクセシビリティ

prefers-reduced-motion(必須)
import { useReducedMotion } from "motion/react"

const shouldReduce = useReducedMotion()
const variants = shouldReduce 
  ? { opacity: 1 }                    // Fade only
  : { opacity: 1, scale: 1, y: 0 }    // Full animation

Tailwind:motion-safe:animate-pulse / motion-reduce:transition-none

ベストプラクティス:無効にするのではなく、簡略化してください。空間的な移動をなくし、不透明度は維持します。

フォーカス管理
  • アニメーション開始後にフォーカスを移動します:requestAnimationFrame(() => ref.focus())
  • 閉じるときは、トリガーにフォーカスを戻します
  • aria-live 領域内ではアニメーションを使用しないでください
タッチターゲット
規格サイズTailwind物理サイズ
Material Design48×48 dpmin-h-12 min-w-12約9mm(推奨)
Apple HIG44×44 ptmin-h-11 min-w-11約7mm
WCAG 2.2(AA)24×24 pxmin-h-6 min-w-6約5mm(最小)

理由:成人の指先の平均幅は約9mmです。7mm未満のターゲットでは「ファットフィンガー」エラーが発生します。クロスプラットフォームでは Material の 48dp を、iOS 固有の最小サイズには Apple の 44pt を使用してください。

パフォーマンス

基本ルール
  1. transform と opacity のみをアニメーションさせる—GPU で高速化されます
  2. アニメーションさせないもの:width、height、top、left、margin、padding
  3. will-change は控えめに使う—アニメーション中のみ使用し、終了後に削除します
  4. ぼかしの目安:
    • ≤10px:アニメーションに安全です
    • 11~20px:モバイル/4K ではカクつくことがあります。十分にテストしてください
    • 20px:リアルタイム効果では避け、あらかじめぼかした画像を使用してください

  5. シンプルなトランジションには、JS より CSS を優先します
主な落とし穴
  • 高さのアニメーション:animate={{ height }} ではなく、layout プロパティを使用します
  • 見えないのにクリックできる:opacity: 0 でもクリックを受け付けます。pointerEvents: "none" を追加してください
  • あらゆる場所での will-change:レイヤーが過剰に生成され、モバイルでクラッシュします

詳しい例については、references/recipes.md を参照してください。

例

references/recipes.md に、カテゴリ別のコピー&ペースト可能なパターンをまとめています。

  • 一般的な UI パターン:ボタンの押下、モーダルの表示/終了、エラー時の揺れ、段階的に表示するリスト、アコーディオン
  • タッチとインタラクション:アクセシブルなタッチターゲット、タッチデバイスでのホバー、即時表示のツールチップ
  • レイアウトアニメーション:layout プロパティ、layoutId による共有要素、衝突の修正
  • Radix UI との統合:forceMount パターン、asChild、起点を考慮したポップオーバー
  • アクセシビリティ:フォーカスのタイミング、フォーカスの復元、視差効果の低減に対応したバリアント
  • パフォーマンス:高さのアニメーション(layout を使用)、見えないのにクリックできる問題の修正、will-change
  • 終了パターン:forwardRef を使った popLayout、SSR のハイドレーション(initial={false})
  • ジェスチャー:速度チェックを使ったスワイプによる閉じる操作、弾性のあるドラッグ境界

AnimatePresence

モード動作用途
sync(デフォルト)表示と終了を同時に実行クロスフェード、オーバーレイ
wait終了の完了後に表示ページ遷移、タブ
popLayout終了する要素をフローから除外リスト項目の削除(layout と併用)
終了アニメーションの落とし穴

終了アニメーションには AnimatePresence が必要です。使用しない場合、アンマウントは即座に行われます。

// ❌ Exit never runs
{isOpen && <motion.div exit={{ opacity: 0 }}>...</motion.div>}

// ✅ Wrap in AnimatePresence
<AnimatePresence>
  {isOpen && <motion.div exit={{ opacity: 0 }}>...</motion.div>}
</AnimatePresence>

SSR:ページ読み込み時のアニメーションを防ぐには、<AnimatePresence initial={false}> を使用します。

アンチパターン

避けること代わりにすること理由
scale(0) から開始scale(0.9) 以上「ポンッ」と飛び出すような効果を防ぎます
UI に linear を使用ease-out またはスプリング線形の動きは機械的に感じられます
500ms を超えるアニメーション300ms 未満にするもたついて感じられます
ツールチップの遅延を常に同じにする最初は 400ms、以降は 0msユーザーのメンタルモデルに合います
視差効果の低減への対応を省略常に motion-safe: を使用アクセシビリティ
レイアウトプロパティをアニメーションtransform: scale() を使用パフォーマンス
過剰なバウンスbounce: 0-0.2プロらしくない印象になります

tailwindcss-animate

Tailwind v4:キーフレームは設定ファイルではなく、CSS の @theme で定義します。

カテゴリクラス
表示animate-in fade-in zoom-in-95 slide-in-from-top
終了animate-out fade-out zoom-out-95 slide-out-to-top
タイミングdelay-150 duration-500
フィルモードfill-mode-forwards fill-mode-backwards

他のスキルとの連携

タイミングスキル理由
実装後code-qualityコードがチェックに合格することを確認します
再利用可能なパターンdocs-writeコンポーネント API を文書化します
コミット前git-commitfeat(ui): または style: を使用します
統合に関する問題search最新のパターンを調べます

出力

  • 成果物:コード変更のみ(.ada/ の出力なし)
  • 変更内容:コンポーネントのアニメーション、CSS/Tailwind のスタイル、Motion の設定
  • 種類:ワークフロースキル(ガイダンスのみ。スクリプトなし)

参考資料

内部
  • references/recipes.md - コピー&ペースト可能なパターン、統合例、詳しい落とし穴
外部

コメント