mcpField
A
animate

animate

github.com/aladicfデザイン・UI562 回インストール8 週間前に更新
リポジトリ

animate について

目的に沿ったインターフェースのモーションを計画し、実装するデザインスキルです。パフォーマンスや入力方法、モーション低減への配慮とともに、フィードバックや操作の理解を改善します。

主な機能

  1. 01モーションの評価と計画
  2. 02時間、イージング、演出の指針
  3. 03モーション低減の代替案
  4. 04ジェスチャーとトランジションのパターン
  5. 05パフォーマンスを考慮した実装選択

活用シーン

  1. 01ボタンやフォーム送信へのフィードバック追加
  2. 02ページや状態の切り替えの円滑化
  3. 03ドロワー、ジェスチャー、段階的演出の設計
  4. 04モーション低減設定に応じたアニメーション調整

インストール

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

$npx skills add https://github.com/aladicf/better-react-web-ui --skill animate

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

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

reference/
animation-purpose.md
asymmetric-press-release.md
attribution-and-sources.md
avoid-css-variables-drag.md
blur-bridge-states.md
button-press-scale-097.md
clip-path-layout-free-reveals.md
clip-path-tab-transitions.md
custom-easing-curves.md
damp-drag-boundaries.md
drawer-500ms-duration.md
ease-in-out-on-screen-movement.md
ease-out-default.md
easing-context.md
entrance-animations.md
exit-animations.md
faster-improves-performance.md
gesture-interactions.md
hardware-accelerated-busy-main-thread.md
hover-gap-fill.md
immediate-feedback-actions.md
interaction-frequency.md
interruptible-animations.md
marketing-exception.md
micro-interactions.md
momentum-dismissal.md
never-scale-zero.md
no-animation-for-keyboard.md
opacity-reduced-motion-fallback.md
origin-aware-animations.md

詳細

機能を分析し、インターフェースの動作を遅く、騒がしく、芝居がかった印象にすることなく、わかりやすさ、フィードバック、体感速度、洗練度を高めるモーションを追加します。

必須の準備

frontend-design を読み、そのコンテキスト収集プロトコルに従ってください。利用可能なコンテキストを再利用し、重大な情報が不足している場合に限って質問してください。さらに、パフォーマンス上の制約も確認してください。 タイミング、イージング、振り付け、動きを減らす設定への対応については、モーションリファレンスを参照してください。 ファイル名を推測するのではなく、用途別に詳細なモーションライブラリを閲覧する場合は、animateリファレンスのインデックスを参照してください。 モーションで持ち上がり、押下、凹み、ドラッグ、レイヤー化による奥行きを表現する場合は、エレベーションシステムを参照してください。 アニメーションの判断がフォーカス、読み込み、トランジション、フィードバックの状態と関わる場合は、インタラクションリファレンスを参照してください。 モーションがボタン、タブ、ツールチップ、トースト、トグル、ドロワー、送信アクションなどのカスタムプリミティブに影響する場合は、コンポーネントの構造リファレンスを参照してください。 コンパクトなビューポート、粗いポインターのコンテキスト、または限られたビューポート領域に合わせてモーションを調整する必要がある場合は、レスポンシブデザインリファレンスを参照してください。 フレームワーク固有のアニメーションについて判断する前に、フレームワーク公式ドキュメントのリファレンスを参照してください。 Reactのトースト、ドロワー、テキストモーション、その他すでに優れたアクセラレーターがあるUIパターンに関わる場合は、React shadcnアクセラレーターのリファレンスを参照してください。 フレームワークのアニメーションライブラリを使わずに、Tailwindユーティリティ、Tailwind互換のキーフレーム、またはWAAPIでモーションを実現できるか判断するには、TailwindとWAAPIのモーションリファレンスを参照してください。 CSSのlinear()イージングトークン、Tailwindのモーショントークン、Reactコンポーネントのモーション例、またはView Transitionのイージングを定義する場合は、線形イージングパターンのリファレンスを参照してください。 複数要素のモーション、段階的な表示、リストの追加・削除・並べ替え、モーダルの重なり、ドロワーの連続動作、ルートの振り付け、または複雑なインタラクションフローを調整する場合は、モーションの振り付けリファレンスを参照してください。 モーションを時間ではなくスクロール位置に応じて進行させる場合は、スクロール駆動アニメーションのリファレンスを参照してください。 ページ状態間やDOMの変更時に、共有要素の連続性を保ちながらアニメーションさせる場合は、View Transitionsのリファレンスを参照してください。 このスキルのEmilに着想を得たモーションガイダンスの出典と経緯については、帰属と出典を参照してください。 モーションの種類別にまとめたガイダンスについては、開始アニメーション、終了アニメーション、ジェスチャー操作、マイクロインタラクションを参照してください。 モーションカーブを選ぶ場合は、イーズアウトのデフォルト、コンテキスト別のイージング、カスタムイージングカーブを参照してください。 イージングではなく主に継続時間が問題となる場合は、300ms未満のUI、押下と解放の非対称なタイミング、ドロワーの500msタイミング、体感速度の向上、ツールチップの遅延段階設定を参照してください。 モーションパターンにより具体的なガイダンスが必要な場合は、画面上の移動のイージング、シートとドロワーのイージング、スプリングモーションを参照してください。 ジェスチャーを多用するサーフェスを実装する場合は、減衰するドラッグ境界、上方向ドラッグの摩擦、中断可能なアニメーション、勢いを利用した閉じる操作、ポインターキャプチャ、スクロールとドラッグの競合、速度を考慮したスナップポイントを参照してください。 仕上げとアクセシビリティの調整については、ぼかしを介した状態間トランジション、clip-pathによるタブ切り替え、動きを減らす設定を尊重する、不透明度によるフォールバック、動きを減らす設定の代替案、MotionのuseReducedMotion、ホバー領域の隙間を埋める、スクロール時の表示しきい値、子要素のオーケストレーション、トーストスタックの奥行きを参照してください。 パフォーマンスに影響するプロパティを選ぶ場合は、transformとopacityのみを使う、ドラッグループで継承トークンを変更しない、レイアウトを変えないclip-path表示、メインスレッドが混雑した状況でのハードウェアアクセラレーションモーション、必要な箇所だけで使うwill-changeを参照してください。 モーションに関する方針が重要な判断では、アクションへの即時フィードバック、インタラクション頻度、キーボード操作にはアニメーションを使わない、マーケティングにおける例外、アニメーションの目的を参照してください。 問題の本質がtransformの手法や空間的な印象にある場合は、preserve-3d効果、ゼロから拡大しない、原点を考慮したアニメーション、パーセント指定のtranslateYを参照してください。 transformの細かな仕上げについては、ボタン押下時のスケール0.97、子要素へのスケールの影響、SVGパスのモーフィングによる開閉アイコンを参照してください。 インターフェースを頻繁に使うとすでにもたつく場合は、optimize も読み込んでください。 視差効果の低減、エラー、オーバーフロー、エッジケース、複数の入力モードへの対応を強化する必要がある場合は、harden も読み込んでください。


クレジットとインスピレーション

このスキルのモーションに関するガイダンスは、Emil Kowalski の animations.dev コースから一部影響を受けています。特に、本番環境の UI におけるイージングの選択、タイミング、節度ある表現、スプリング、そして「しっくりくる」モーションの重視が参考になっています。

また、Emil のアニメーションを多用したオープンソースプロジェクトである Sonner と Vaul からも影響を受けています。これらは、React のトーストとドロワーに関するガイダンスとして、このライブラリ内の別の箇所でもすでに関連しています。

このリポジトリでは、コースの教材を直接再現するのではなく、それらの教訓をリポジトリ固有の独自のガイダンスとして書き直しています。


モーションの基本方針

アニメーションを追加する前に、次の順序で判断してください。

  1. まず構造を整える — モーションは階層や状態を補強するものであり、分かりにくいレイアウトを救済するものではありません。
  2. 目的がある場合にのみアニメーションを使う — すべてのアニメーションは、フィードバック、方向の把握、関係性、または楽しさの向上に役立つべきです。
  3. 速度を優先する — プロダクト UI では、印象的であることよりも、まず応答性の高さが求められます。
  4. モーションを中断可能にする — 古いアニメーションの完了より、新たなユーザーの意図を優先してください。
  5. 入力方法に合わせる — 精密ポインター、粗いポインター、キーボードの操作すべてに、同じモーションを適用する必要はありません。
  6. 最初から視差効果の低減を考慮する — アクセシビリティはシステムの一部であり、最後に行う後処理ではありません。
  7. 要件を満たす最も軽量な実装を選ぶ — まず Tailwind ユーティリティと Tailwind 互換のキーフレームを使い、命令的なタイミング制御が必要な場合は WAAPI を、操作に本当に必要な場合は Motion を使ってください。

次のいずれかの目的でモーションを使ってください。

  • フィードバック — 操作が行われたことを伝える
  • 方向の把握 — 要素がどこから来たのか、どこへ移動したのかをユーザーが理解できるようにする
  • 関係性 — 表面、レイヤー、コントロールの空間的な関係を示す
  • 楽しさ — 基本的な機能がすでに適切に動作している状態で、温かみや個性を加える
  • 階層:何が最も大きく変化し、その理由が何かを明確にする
  • フォーカスの誘導:ユーザーの操作権を奪わずに、適切な対象へ注意を向ける

これらの目的のどれにも当てはまらないアニメーションは、削除してください。

モーションの機会を評価する

モーションによって体験が向上する箇所を分析してください。

  1. 静的な箇所を特定する:

    • フィードバックの不足:ボタンのクリックやフォームの送信など、視覚的な応答がない操作
    • ぎこちない遷移:表示/非表示、ページの読み込み、ルートの切り替えなど、唐突に感じる即時の状態変化
    • 分かりにくい関係性:空間的または階層的な関係が明確でない箇所
    • 楽しさの欠如:機能的ではあるものの、楽しさに欠ける操作
    • 案内の不足:注意を誘導したり、動作を説明したりする機会
  2. コンテキストを把握する:

    • どのような雰囲気ですか?(遊び心があるか、真面目か。活気があるか、落ち着いているか)
  • パフォーマンスの予算はどの程度ですか?(コンパクトなレイアウトを優先するか、複雑なページか)
  • 対象ユーザーは誰ですか?(モーションに敏感なユーザーか、速度を求めるパワーユーザーか)
  • 最も重要なのは何ですか?(ひとつのヒーローアニメーションか、多数のマイクロインタラクションか)
  • どの入力方法が重要ですか?(精密ポインター、粗いポインター、キーボード、スタイラス)
    • 頻繁に使われ、特に応答性を高く保つべき操作はどれですか?

コードベースから判断できない点があれば、推測できない内容についてユーザーに直接確認してください。

重要:prefers-reduced-motion を尊重してください。必要とするユーザーのために、アニメーションを使わない代替手段を必ず用意してください。

モーションは階層を補強するものであり、弱い階層を補うものではありません。動かして初めてレイアウトが理解できるのであれば、まずレイアウトを改善してください。

アニメーション戦略の計画

意図のあるアニメーション計画を作成します。

  • ヒーローモーメント:代表となるアニメーションは何ですか?(ページ読み込み時?ヒーローセクション?主要なインタラクション?)
  • フィードバックレイヤー:どのインタラクションに応答が必要ですか?
  • トランジションレイヤー:どの状態変化を滑らかにする必要がありますか?
  • ジェスチャーレイヤー:どのドラッグ、スワイプ、スナップ、または閉じるインタラクションに物理的なロジックが必要ですか?
  • 喜びのレイヤー:どこで驚きや喜びを届けられますか?
  • 奥行きのロジック:どの要素を浮き上がった、押し込まれた、ドラッグ中、くぼんだ、または重なり合ったように感じさせるべきですか?
  • 動きを減らす場合の計画:何をフェード、ぼかし、または即座の状態変化に簡略化しますか?
  • パフォーマンス予算:頻繁に発生するため、軽量に保つべき動きはどれですか?

重要:あちこちにアニメーションを散りばめるより、緻密に調整された体験を一つ作るほうが効果的です。影響の大きい場面に集中してください。

デフォルトのモーションルール

製品のコンテキストに、これと異なる強い理由がない限り、アニメーション作業では以下をデフォルトのガイドラインとして使用してください。

1. 戦略と目的
  • すべてのアニメーションは、フィードバック、方向づけ、関係性、または喜びをもたらすことで、その存在意義を示す必要があります。
  • 製品インターフェースは通常、速く、落ち着きがあり、正確に感じられるべきです。オンボーディング、ヒーローモーメント、ストーリーテリング、マーケティング向けの画面では、よりゆっくりした、またはドラマチックな動きを使います。
  • あらゆる場所に動きを追加するより、印象的な瞬間を一つと、規律あるマイクロインタラクションを組み合わせます。
  • ポインター操作にアニメーションがあるからという理由だけで、キーボード操作によるアクションをアニメーション化しないでください。キーボードユーザーは通常、遅延を最小限に抑えた、予測可能な状態変化を求めています。
  • インタラクションが頻繁に発生するほど、通常は必要な動きが少なくなります。高頻度のコントロールは、ほぼ瞬時に反応するように感じられるべきです。
  • ユーザーの入力にはすぐに応答します。可能な限り、マイクロインタラクションでは約80ms以内に視覚的なフィードバックを返すことを目指します。
  • 実際の処理に約400ms以上かかる可能性がある場合は、何も起きない時間を残すのではなく、楽観的 UI、スケルトン、進捗表示、または明確な読み込みフィードバックですぐに応答します。
  • 読み込みの遅さ、弱い階層構造、または不足した状態設計をごまかすために、モーションを使ってはいけません。
2. イージングのデフォルト
  • 入場、表示、そして大半のフィードバックトランジションでは、デフォルトとしてイーズアウトを使用します。
  • 汎用の ease デフォルトではなく、Tailwind の任意イージング値またはテーマトークンを使ってカスタム cubic-bezier カーブを使用します。
  • 画面上で往復する可逆的な状態変化には、イーズインアウトを使用します。
  • 動きとジェスチャー入力、またはオブジェクトの挙動を物理的に連動させたい場合は、スプリングモーションを使用します。
  • ドロワー、シート、および類似のサーフェスには、シートスタイルのカーブ cubic-bezier(0.32, 0.72, 0, 1) を出発点として使うとよいでしょう。
  • 洗練された UI モーションには、ease-out-quart、ease-out-quint、または ease-out-expo のような指数関数的な減速を優先します。
  • 製品が意図的におもちゃのような、または遊び心のある物理的な比喩を取り入れている場合を除き、バウンスや弾性のあるカーブは避けます。こうした動きは古くさく、騒がしく、わざとらしく感じられることがよくあります。
  • コンテキストに合わせてイージングを選びます。
    • 入場するサーフェス → イーズアウト
    • 退場するサーフェス → より短い時間。多くの場合、イーズインまたはよりシャープな退場カーブ
    • 状態の切り替え/可逆的な動き → イーズインアウト
    • ジェスチャーに連動する動き → スプリングまたは速度を考慮した補間
    • 自律的に一定の動きを続ける場合 → リニア。ただし、ループに意図的な機械的な感触が必要な場合を除く
3. タイミングと継続時間
  • 繰り返し発生する UI の動きは、ほとんどの場合 300ms 未満にします。
  • 押下状態、切り替え、色の変化、即時の応答などのマイクロインタラクションには 100-150ms を使います。
  • ツールチップ、ドロップダウン、メニュー、ホバー状態、小さな表示など、標準的な UI には 150-250ms を使います。
  • シートのような重みが不要な場合、モーダル、ドロワー、中程度のサーフェス遷移には 200-300ms を使います。
  • アコーディオン、シート、ドロワー、大きなサーフェスの変化など、より大きなレイアウト遷移には 300-500ms を使います。
  • 500ms は、シートや段階的な表示など、より大きなサーフェスの動きに対する特別な上限として扱います。通常のコントロールの標準値にはしないでください。
  • 退場アニメーションは、登場アニメーションより速くします。目安として、登場時間の約 75% を標準値にします。
  • 押下時は、離すときより速くします。押し込むフィードバックは即時に感じられるようにし、元に戻る動きは少し柔らかくしてもかまいません。
  • 必要に応じて、最初のツールチップやホバーで表示される補助情報には遅延を設けます。ただし、関連する次の表示は大幅に速くするか、即時にして、インターフェースがもたついて感じられないようにします。
  • 小さな要素をまとめて表示する場合は、まず 30-80ms の段階的な遅延から始めます。長い段階的表示の連鎖は避けてください。最後の要素が気まずいほど遅れて表示されないよう、遅延時間の合計に上限を設けます。
  • 継続時間は、移動距離と視覚的な重さに合わせます。通常、大きな要素や長い移動には、小さな局所的変化より少し長い時間が必要です。
4. プロパティの選択とパフォーマンス
  • transform と opacity のアニメーションを優先します。
  • 本番環境の UI では transition-all を避けます。transition-[transform,opacity]、transition-transform、transition-opacity、transition-colors のように、動かすプロパティを指定します。
  • 強い理由があり、対象となるサーフェスが小さい場合を除き、width, height, top, left, padding, margin, border-width などのレイアウト負荷が大きいプロパティのアニメーションは避けます。
  • アコーディオンのような高さの遷移では、可能であれば生の height アニメーションよりも grid-template-rows や、同等のレイアウトに優しいパターンを優先します。
  • レイアウトを変えずに表示効果を作る必要がある場合は、clip-path、マスク、またはコンポジットによる表示を使います。
  • メインスレッドが混雑している場合や、コンポーネントが頻繁にアニメーションする場合は、translateX(...)、translateY(...)、translate3d(...) など、ハードウェアに適した完全な変換を使います。実際の変換で実現できる処理に、負荷がかかったときにレイアウト位置の値を変更するフレームワークのプロパティを使うのは避けます。
  • will-change は控えめに使い、アニメーションが間近に迫っている場合、または必要性が実証されている場合に限ります。
  • ドラッグ処理中は、遅延が発生するのであれば、フレームごとに高コストな継承トークンやレイアウトの再計算を通すアニメーション設定を避けます。
  • スクロールに連動する動きには Intersection Observer を優先し、一度だけ実行すればよい場合は、動きが完了したら監視を停止します。
5. 変換とスケールのテクニック
  • ボタンやチップの押下フィードバックには、scale(0.97) を有力な初期値として使います。
  • 登場時のアニメーションを scale(0) から始めてはいけません。要素の質量感を保つため、scale(0.95) 以上に近い値から始めます。
  • 要素やビューポートのサイズに合わせて移動量を変化させたい場合は、パーセンテージ指定の translate 値を使います。
  • 動きの原点を考慮します。
    • メニューやツールチップは、トリガーの端から現れるようにします。
    • ドロワーやシートは、固定されている側から動くようにします。
    • 浮き上がるカードは、現在の面から浮き上がるように感じられる必要があります。
  • スケールは子要素にも影響することを忘れないでください。スケールの範囲が大きすぎると、テキストやアイコンがぼやけたり、歪んだりすることがあります。
  • 3D 変換は、空間の理解を助ける場合や、明確に楽しさを加える場合にのみ使います。単に見た目が派手というだけで preserve-3d を使わないでください。
6. ジェスチャーとインタラクションのパターン
  • インタラクティブなアニメーションは中断可能にします。ユーザーが新しい意図を示す前に、動きが終わるまで待たせてはいけません。
  • ホバー、押下、メニュー、ポップオーバーなど、頻繁にトリガーされる状態には、キーフレームより CSS トランジションを優先します。ユーザーの意図が変わったときに、トランジションなら自然に反転できます。
  • ネイティブのダイアログやポップオーバーでは、表示/トップレイヤーへの出入りに @starting-style と transition-behavior: allow-discrete の組み合わせを検討します。ただし、段階的な対応にとどめ、アニメーションの工夫でフォーカス管理やライフサイクルの正確さを損なわないでください。
  • スワイプで閉じる操作、シートのスナップなどのジェスチャーには、距離だけでなく距離と速度を用います。
  • 境界付近では摩擦や減衰を加え、ドラッグに抵抗を感じさせ、急停止させないようにします。
  • スクロールとドラッグの競合には意図的に対処します。ネストされた領域が入力を奪い合っているように感じさせないでください。
  • ドラッグ操作の実装では、ポインターキャプチャや同等のジェスチャー制御など、堅牢なポインター処理を使います。
  • ドラッグ中のアイテムは、影、わずかな拡大、レイヤーの浮き上がりなど、奥行きを示す表現で視覚的に持ち上げます。
  • サーフェスを静止位置より先までドラッグできる場合は、ジェスチャーが突然遮られたように感じないよう、適度な抵抗を加えます。
  • スナップポイントは速度を考慮し、意図を持って設定します。任意の見えない壁のように感じさせないでください。
7. アクセシビリティと仕上げ
  • 常に prefers-reduced-motion を尊重します。
  • モーションの低減は通常、フィードバックをなくすのではなく、動きを簡略化することを意味します。可能な場合は、大きな空間移動を不透明度、ぼかし、ハイライト、短いトランジションなどに置き換えます。
  • フォーカス状態、進行状況、読み込み時のフィードバック、成功またはエラーの通知など、機能上の手がかりを維持します。
  • 状態の切り替えが唐突に感じられる場合は、ぼかしを慎重に使って視覚状態をつなぎます。
  • スタガーは装飾ではなく、表示の演出として意図的に使います。少数のリストには効果がありますが、巨大なリストには通常向きません。
  • ホバー時だけの動きは、ホバーとポインター機能が使える場合に限定します。Tailwind では、タッチ操作でホバー時の動きが誤作動する可能性がある場合、motion-safe: とカスタムの @media (hover: hover) and (pointer: fine) バリアント、または CSS を優先します。
  • スクロールに応じて要素を表示する場合は、ユーザーが要素を通り過ぎる前にトリガーします。ただし、スクロールの流れから切り離されていると感じるほど早くしてはいけません。
  • トリガー要素とフローティングサーフェスの間のホバー領域をつなぎ、ポインターの移動中にツールチップ、メニュー、ポップオーバーがちらついて閉じないようにします。
  • トーストのスタックには、オフセット、スケール、不透明度を使うことで、混乱を招かずに奥行きを表現できます。
  • 広いレイアウトだけでなく、コンパクトな表示や粗いポインター環境でも、モーションへの過敏さを尊重します。ジェスチャーに伴う動きは、過剰にすると特に不快に感じられることがあります。

アニメーションの実装

以下のカテゴリに沿って、体系的に動きを追加します。

登場アニメーション
  • ページ読み込み時の演出:理解を助ける場合に限ってスタッガーを使い、演出全体を短く保ちます
  • ヒーローセクション:製品のトーンに合う場合は、主要なストーリー要素に独自の登場演出を加えます
  • コンテンツの表示:Intersection Observer を使ったスクロールトリガーアニメーション
  • モーダル/ドロワーの表示:滑らかなスライドとフェード、背景のフェード、フォーカス管理
マイクロインタラクション
  • ボタンのフィードバック:
    • ホバー:操作しやすさの向上につながる場合に限り、控えめな拡大、色の変化、または影の変化を加えます
    • クリック/押下:素早く縮小して戻す動き、押し込まれる感覚、または奥行きの変化を加えます
    • 読み込み中:スピナーまたはパルス状態を表示します
  • フォームの操作:
    • 入力フォーカス:気を散らさず、フォーカスを明確にするボーダー、背景、または高さの変化を加えます
    • 検証:装飾的な動きよりも、明確な色、アイコン、またはテキスト状態の変化を優先します
  • トグルスイッチ:滑らかなスライドと色の変化
  • チェックボックス/ラジオボタン:短いタイミングで明確に状態を変化させます
  • いいね/お気に入り:製品のトーンに合う場合に限り、小さな拡大やアイコンの動きを加えます
状態遷移
  • 表示/非表示:フェード+スライド(瞬時に切り替えない)を適切なタイミング(200~300ms)で行います
  • 展開/折りたたみ:オーバーフローを処理した、レイアウトに配慮した開閉トランジションを使用します。必要に応じてアイコンを回転させます
  • 読み込み状態:スケルトンスクリーンのフェード、スピナーのアニメーション、プログレスバーを使用します
  • 成功/エラー:色のトランジション、アイコンのアニメーション、穏やかな拡大縮小のパルスを使用します
  • 有効/無効:不透明度のトランジションやカーソルの変化を使用します
ナビゲーションとフロー
  • ページ遷移:ルート間をクロスフェードし、連続性を明確にする場合は共有要素のトランジションを使用します
  • タブ切り替え:インジケーターのスライド、コンテンツのフェード、clip-path、またはその他の素早い方向性を示す演出を使用します
  • カルーセル/スライダー:滑らかな変形、スナップポイント、慣性、割り込み可能な入力を実現します
  • スクロール効果:視差レイヤー、状態変化を伴うスティッキーヘッダー、スクロール進捗インジケーターを使用します
フィードバックとガイダンス
  • ホバー時のヒント:ツールチップのフェードイン、カーソルの変化、要素のハイライトを使用します
  • ドラッグ&ドロップ:持ち上がる効果(影+拡大)、ドロップゾーンのハイライト、滑らかな位置変更を実現します。ドラッグ中は、アイテムがZ軸方向に手前へ浮き上がるように感じられるようにします
  • コピー/貼り付け:貼り付け時に短くハイライトを点滅させ、「コピーしました」という確認を表示します
  • フォーカスフロー:フォームやワークフロー内の経路をハイライトします
奥行きと浮き上がりの動き
  • 浮き上がった要素は、ユーザーに向かって移動するように感じられる必要があります
  • 押された要素は、内側または下方へ移動するように感じられる必要があります
  • 状態を伝えるため、装飾だけでなく影と動きを組み合わせます
  • 動きの強調度は、色やタイポグラフィに使われている階層の考え方に合わせます
楽しい演出
  • 空の状態:イラストに控えめな浮遊アニメーションを加えます
  • アクションの完了:紙吹雪、チェックマークの演出、成功を祝うアニメーションを使用します
  • イースターエッグ:発見を促す隠しインタラクションを用意します
  • 状況に応じたアニメーション:天候の効果、時間帯のテーマ、季節の演出を取り入れます

技術的な実装

各アニメーションに適した手法を使用します。

手法の選択

インタラクションの要件を満たす、最も軽量な手法を選びます。

  • ホバー、選択、押下、開閉など、単一要素の可逆的な状態変化には、Tailwind のトランジションユーティリティを使用します
  • ローダー、注意喚起のパルス、段階的な表示、振り付けなど、繰り返しや複数段階のタイムラインには、Tailwind 互換のキーフレームを使用します
  • 命令的なシーケンス、再生制御、キャンセル/逆再生、ロジックとのアニメーション同期には、WAAPIを使用します
  • DOM の入れ替え、ルート遷移、リスト/詳細の遷移、レイアウトモードの変更における連続性には、View Transitions APIを使用します

ユーティリティクラス、Tailwind キーフレーム、WAAPI、View Transitions で実現できる場合は、無理にフレームワークのアニメーションライブラリに切り替えないでください。

タイミングとイージング

目的別の時間:

  • 100~150ms:即時のフィードバック(ボタンの押下、トグル)
  • 200~300ms:状態の変化(ホバー、メニューを開く)
  • 300~500ms:レイアウトの変化(アコーディオン、モーダル、ドロワー)
  • デフォルトで最大500ms:本当に必要な、大きな領域のトランジション

イージングカーブ(Tailwind の任意値またはテーマトークンで使用):

/* Recommended - natural deceleration */
--ease-out-quart: cubic-bezier(0.25, 1, 0.5, 1);    /* Smooth, refined */
--ease-out-quint: cubic-bezier(0.22, 1, 0.36, 1);   /* Slightly snappier */
--ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);     /* Confident, decisive */
--ease-in-out-standard: cubic-bezier(0.65, 0, 0.35, 1); /* Reversible movement */
--ease-sheet-standard: cubic-bezier(0.32, 0.72, 0, 1);   /* Sheets / drawers */

/* AVOID - feel dated and tacky */
/* bounce: cubic-bezier(0.34, 1.56, 0.64, 1); */
/* elastic: cubic-bezier(0.68, -0.6, 0.32, 1.6); */

終了アニメーションは開始アニメーションより速くします。 開始時の時間の約75%を使用します。

Tailwind 互換のアニメーション
/* Prefer for simple, declarative animations through Tailwind utilities or keyframes */
- transitions for state changes
- @keyframes for complex sequences
- transform + opacity first (GPU-friendly)
- Tailwind utilities when the project already uses Tailwind

Tailwind の例:

<button className="transition-transform duration-150 ease-[cubic-bezier(0.16,1,0.3,1)] active:scale-[0.97] motion-reduce:transition-none motion-reduce:transform-none">
  Save
</button>

<div className="transition-[transform,opacity] duration-200 ease-[cubic-bezier(0.16,1,0.3,1)] data-[state=open]:scale-100 data-[state=open]:opacity-100 data-[state=closed]:scale-95 data-[state=closed]:opacity-0 origin-[var(--radix-popover-content-transform-origin)]">
  ...
</div>

別々の状態がそれぞれ異なる transform チャネルを持つ場合は、個別の Tailwind transform ユーティリティを使用します。

<div className="translate-y-2 scale-95 opacity-0 transition-[translate,scale,opacity] duration-200 ease-[cubic-bezier(0.16,1,0.3,1)] data-[state=open]:translate-y-0 data-[state=open]:scale-100 data-[state=open]:opacity-100 motion-reduce:translate-y-0 motion-reduce:scale-100">
  ...
</div>

任意の transform 省略記法は、順序を意図的に連動させる場合にのみ使用します。包括的なパフォーマンス対策として translate3d() を使わないでください。まずプロファイリングを行うか、実際に3D/遠近法の処理が必要な場合に限って使用します。

Tailwind 互換の linear() イージングトークンは、区分的な速度制御、滑らかな開始、きびきびした終了、制御された収束に役立ちます。単発の任意値より、名前付きのテーマトークンを優先してください。

@theme {
  --ease-enter-soft: linear(0, 0.08 12%, 0.34 36%, 0.74 66%, 0.93 84%, 1);
  --ease-exit-crisp: linear(0, 0.3 18%, 0.72 58%, 0.9 78%, 1);
  --ease-settle-gentle: linear(0, 0.06 10%, 0.31 32%, 0.72 62%, 0.92 82%, 1);
  --ease-emphasis-pop: linear(0, 0.38 20%, 0.88 62%, 1);
}
JavaScript アニメーション
/* Use for complex, interactive animations */
- Web Animations API for programmatic control
- Framer Motion / Motion for React
- GSAP for complex sequences

デフォルトのルール:ホバー、押下、表示、または動きを抑えた表示へのフォールバックを Tailwind ユーティリティや Tailwind 互換のキーフレームで簡潔に表現できる場合は、Motion に切り替える前にその方法を優先してください。

パフォーマンス
  • GPU アクセラレーション:transform と opacity を使用し、レイアウトプロパティは避けます
  • will-change:負荷の高いアニメーションがわかっている場合にのみ、控えめに追加します
  • 描画を減らす:再描画を最小限に抑え、適切な場合は contain を使用します
  • FPS を監視する:対象デバイスで 60fps を確保します
  • インタラクションを優先する:頻繁に行われる製品の操作は、性能の低いデバイスでも応答性よく感じられるようにします
アクセシビリティ
@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

あらゆる形式のフィードバックをなくすのではなく、大きな動きを短いフェード、ハイライト、ぼかしのトランジション、または即時の状態変化に置き換えることをおすすめします。

推奨されるデフォルト値

まずは以下の値を使用し、状況に合わせて調整してください。

値適した用途
scale(0.97)ボタンやチップを押したときのフィードバック
scale(0.95)自然に見える最小限の表示時スケール
200ms標準的な UI トランジション
300ms一般的な UI の動きの上限の目安
500ms大きなシート/ドロワーのトランジションの上限
cubic-bezier(0.32, 0.72, 0, 1)ドロワー/ボトムシートのイージング
10-16pxトーストスタックのオフセットの開始範囲
~100px from viewport edgeスクロール表示のトリガー位置の開始目安

絶対に避けること:

  • デフォルトでバウンスや弾性のあるイージング曲線を使うこと。アニメーションそのものに注意を引いてしまいます
  • transform や opacity で実現できる場合に、width、height、top、left などのレイアウトプロパティをアニメーションさせること
  • 日常的なフィードバックに長い時間をかけること。すぐに動作が遅く感じられます
  • 目的なくアニメーションさせること。すべてのアニメーションには理由が必要です
  • prefers-reduced-motion を無視すること。これはアクセシビリティ違反です
  • あらゆるものをアニメーションさせること。アニメーション疲れによって、インターフェースが使いづらく感じられます
  • 動きが終わるまでユーザーを待たせること
  • 構造の弱さ、階層の不明瞭さ、データ取得の遅さを動きでごまかすこと
  • 慣性、減衰、スクロールとの競合を考慮しないジェスチャーロジックを提供すること

品質を確認する

アニメーションを十分にテストしてください。

  • 60fps で滑らかに動く:対象デバイスでカクつかない
  • 自然に感じられる:イージング曲線がロボットのようではなく、自然に感じられる
  • タイミングが適切:速すぎず(唐突にならず)、遅すぎない(もたつかない)
  • すぐに反応がある:入力に対して、すばやく目に見える応答がある
  • 必要に応じて中断できる:新しい意図によって、以前の動きを上書きできる
  • ジェスチャーの品質:ドラッグ、スワイプ、スナップ、閉じる操作が物理的に一貫して感じられる
  • モーション軽減が機能する:アニメーションが適切に無効化または簡略化される
  • 操作を妨げない:アニメーション中や終了後にユーザーが操作できる
  • 価値を加える:インターフェースをよりわかりやすく、またはより楽しくする

レビュー時には、次の問題をすぐに指摘してください。

  • 正確なプロパティがわかっているのに transition-all を使用している
  • scale(0) から表示するアニメーション。代わりに、およそ scale(0.95) と opacity を使用します
  • 日常的な UI の動きが 300ms を超えている
  • ホバー機能の有無を判定せずにホバーアニメーションを使用している
  • キーボードで実行するアクションに、ポインター操作向けのアニメーションを使用している
  • ポップオーバー、ツールチップ、メニューの拡大の起点が適切でない
  • 可逆的なトランジションのほうが適している、頻繁に操作されるコントロールでキーフレームを使用している
  • 子要素のレイヤーでアニメーションさせるほうが適切なのに、親要素のホバーアニメーションによって子要素がちらついたり歪んだりしている
  • 負荷がかかっているときに Motion の x または y スタイルの更新を使用している。合成される transform 文字列を使うほうが安全です
  • 閉じる動きを速くすべきなのに、表示時と閉じる時のタイミングが同じになっている
  • 順序をわかりやすくするための小さく上限のあるスタガー表示が適切なのに、リストの子要素がすべて同時に表示される
  • 即時に React のアンマウントを行い、項目、ダイアログ、トースト、ポップオーバーの閉じるアニメーションを妨げている
  • ダイアログ、ポップオーバー、削除可能なリスト項目に transition: all を使用している

最良の UI アニメーションは、たいてい目立とうとするのではなく、自然に感じられるものです。目的を持ってアニメーションを使い、応答性を調整し、アクセシビリティを尊重して、動きが製品の主役ではなく、その価値を支えるようにしてください。

出力仕様

ユーザーからモーションプラン、モーションシステム、または大規模なアニメーションの実装を求められた場合は、次の内容を回答します。

  1. 意図:モーションによって促すユーザーの知覚や行動
  2. モーション仕様:再生時間、イージングトークン、距離、トリガー、影響を受ける要素
  3. 実装:具体的な Tailwind、Tailwind のキーフレーム、WAAPI、または View Transition のコード
  4. アクセシビリティ対応:モーションの軽減設定と、未対応 API に対する動作
  5. QA チェックリスト:パフォーマンス、使いやすさ、フォーカス、キーボード、デバイス間の確認項目

振り付けが複雑な場合は、モーションの振り付けにある、より厳格なストーリーボード形式(ストーリーボード、タイムライン仕様、実装計画、アクセシビリティ対応/フォールバック、検証計画)を使用します。

コメント