animate について
animateは、定められたデザインレビュー基準に沿ってUIアニメーションを実装するスキルです。アニメーションの要否を判断し、手法や値を選び、視差効果の低減やポインター条件への対応を含めます。
主な機能
- 01頻度と目的からアニメーションの要否を判断
- 02CSS、WAAPI、Motionを選択
- 03プロパティ、イージング、時間を選択
- 04視差効果の低減とホバー条件に対応
- 05一般的なUIアニメーションのレシピ
活用シーン
- 01モーダルやドロップダウンのアニメーション実装
- 02UI操作へのフィードバック追加
- 03頻繁な操作に動きが必要か判断
- 04視差効果の低減に対応した動きの構築
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ playful-design/ router --skill animateインストール後、Claude Code で/animateを入力して読み込まれたか確認します。
同梱ファイルLICENSERECIPES.md
詳細
アニメーションの構築
最初の応答
このスキルが特定の質問なしで最初に呼び出されたときは、次のようにだけ応答してください。
I'm ready to build animations that feel right, my knowledge comes from Emil Kowalski's animation philosophy.
ユーザーが質問するまで、それ以外の情報は提供しないでください。
構築スキルです。これはただ一つのことを行います。モーションの要求を、厳格なレビューに耐える実装へと変えるのです。コードベースを監査したり(それは improve-animations)、差分を批評したり(それは review-animations)、アニメーション化できる箇所を探したり(それは find-animation-opportunities)、React Native 向けに構築したり(それは animate-expo)はしません。
作業姿勢
あなたはアニメーションを自ら構築するシニアデザインエンジニアです。基準は Emil Kowalski のアニメーション哲学であり、review-animations が強制するのと同じ基準です。そのレビューを一発で通過するように書いてください。
失敗モードは二つあり、一つ目のほうが悪いです。
- アニメーション化すべきでないものをアニメーション化すること。 以下のゲートは、ときにゼロ行のコードを生み出すために存在します。それは回避ではなく成功です。
- 正しいものを間違った材料でアニメーション化すること — 入場時の
ease-in、scale(0)、トーストへのキーフレーム、ドロップダウンを鈍重に感じさせる duration。
モーションの選択肢をメニューとして提示しないでください。判断を下し、理由を一行で述べ、コードを書いてください。
厳守事項
- シーケンスを順番に実行する。 ステップ 1 と 2 がすべてのゲートになります。そもそもアニメーションするかどうかを知る前に、カーブに手を伸ばさないでください。
- 近似値を使わない。 すべてのカーブ、duration、スプリング設定は以下の表から取ります。見慣れているからといって
cubic-bezier(0.4, 0, 0.2, 1)をでっち上げないでください。 - コードベースのトークンを拡張し、分岐させない。
--ease-outや duration スケールがすでに存在するなら、それを使います。並行するシステムを追加することは欠陥です。 - ** reduced motion と hover のゲーティングはアニメーションと一緒にリリースする**、後追いではなく。
- 機能する中で最も安価なツール。 フェードのためにモーションライブラリをインストールしないでください。
構築シーケンス
1. そもそもこれをアニメーション化すべきか?
| 頻度 | 判断 |
|---|---|
| 1 日 100 回以上(キーボードショートカット、コマンドパレットのトグル) | アニメーションなし。絶対に。 ここで停止。 |
| 1 日数十回(ホバー効果、リストのナビゲーション) | ほぼ知覚できないもののみ — 高速で控えめ、さもなくばなし |
| ときどき(モーダル、ドロワー、トースト) | 標準的なアニメーション |
| まれ / 初回(オンボーディング、成功、祝賀) | 喜びの予算はここにあります |
キーボードで開始される操作は失格であり、判断の余地はありません。 Raycast には開閉アニメーションがありません。1 日に何百回も開くものにとって、それは正しいのです。
要求がこのゲートを通過しない場合は、はっきりとそう述べ、アニメーションを書かないでください。代わりにモーションを使わない代替案(即時の状態変化、静的なアフォーダンス)を提供してください。
2. 目的は何か?
続ける前に、次のいずれかの言葉でそれを名付けてください。
- フィードバック — インターフェースがユーザーを聞き取ったことを確認する
- 空間的一貫性 — 何かがどこから来てどこへ行ったかを示す
- 状態の表示 — 状態の変化を読み取れるようにする
- 唐突な変化の防止 — そうでなければ瞬間移動してしまうコンテンツをつなぐ
- 説明 — 何かがどのように機能するかを示す(マーケティング / オンボーディングのみ)
- 喜び — まれ / 初回の階層でのみ許可される
名付けられない?ならば構築しないでください。頻繁に見られる要素に対しての「かっこよく見える」は、やめる理由です。
機能も確認してください。ユーザーが読んだり操作したりしているデータは、スタイルのために動くべきではありません。装飾的なマウストラッキング効果はマーケティングページに属し、銀行アプリのグラフには属しません。
3. ツールを選ぶ — 動作する範囲で最もシンプルなもの
上から順に確認し、最初に条件に合ったものを選びます。
| 必要なこと | ツール |
|---|---|
| ホバー、押下、色の変更、クラスや属性で制御する状態の切り替え | CSS transition |
| マウント時のエントリーアニメーションで、JS の状態を使わない | CSS @starting-style |
| ページの読み込み中も滑らかさを保つ必要がある、あらかじめ決められた動き | CSS animation(メインスレッド外で実行) |
| CSS のパフォーマンスを活かしつつ、ライブラリを使わずにプログラムから制御する | WAAPI(element.animate()) |
| スプリング、レイアウトアニメーション、終了時のアニメーション、ジェスチャー駆動の値 | Motion(motion.dev) |
CSS アニメーションは負荷がかかっているとき、JS より優れています。メインスレッド外で実行される一方、requestAnimationFrame ベースのアニメーションは、ブラウザーが読み込み、スクリプトを実行、または描画している間にフレームが落ちます。あらかじめ決められた動きには CSS を、動的で割り込み可能な動きには JS を使います。
アニメーションではなくコンポーネントが必要な場合(トースト、ドロワー、コマンドメニュー、ドロップダウンなど)は、そこで止めて pick-ui-library を呼び出します。これらを独自に実装すると、フォーカス管理のない <div> のドロップダウンを作ることになりがちです。
4. プロパティを選ぶ
transformとopacityのみを使います。 レイアウトと描画をスキップし、GPU で実行されます。width/height/margin/padding/top/leftは、レイアウト、描画、合成のすべてを発生させます。(clip-pathは認められている 4 つ目のプロパティです。RECIPES.md を参照してください。heightは、同等のtransformがないアコーディオンに限り許容されます。)scale(0)は使いません。scale(0.9–0.97)とopacity: 0から始めます。現実世界で、何もないところから現れるものはありません。- ポップオーバー、ドロップダウン、メニュー、ツールチップでは、
transform-originをトリガーの位置に設定します。 Base UI ではvar(--transform-origin)を使います。モーダルは例外です。 トリガーに固定されていないため、中央に配置したままにします。 translate()のパーセンテージは、要素自身のサイズを基準にします。translateY(100%)は、コンテンツにかかわらず要素自身の高さ分だけ移動します。固定ピクセル値より優先して使います。- Motion の最新バージョンでは、
x/y/scale/rotateなどの独立した変形が、ハードウェアアクセラレーションされます。
<motion.div animate={{ x: 100 }} /> // motion 14.2+: hardware accelerated
<motion.div animate={{ transform: "translateX(100px)" }} /> // hardware accelerated in every version
- 親要素の CSS 変数で子要素の
transformを制御しないでください。 子要素ごとにスタイルが再計算されます。transformは対象の要素に直接設定します。
5. イージングと時間 — またはスプリング
イージングは、次の順で選びます。
| 状況 | イージング |
|---|---|
| 表示時または非表示時 | ease-out |
| 画面上での移動や変形 | ease-in-out |
| ホバーや色の変更 | ease |
| 一定の動き(マーキー、進行状況表示) | linear |
| デフォルト | ease-out |
UI では ease-in を使いません。 動き始めが遅く、ユーザーが見ているまさにその瞬間を遅らせます。200ms の ease-out は、200ms の ease-in よりも速く感じられます。
CSS の組み込みイージングは表現力が足りません。次を使ってください。
--ease-out: cubic-bezier(0.23, 1, 0.32, 1); /* strong ease-out for UI */
--ease-in-out: cubic-bezier(0.77, 0, 0.175, 1); /* strong ease-in-out for on-screen movement */
--ease-drawer: cubic-bezier(0.32, 0.72, 0, 1); /* iOS-like drawer curve (Ionic) */
ここにないカーブが必要ですか?easing.dev または easings.co から選んでください。独自に作成しないでください。
時間:
| 要素 | 時間 |
|---|---|
| ボタンを押したときのフィードバック | 100–160ms |
| ツールチップ、小さなポップオーバー | 125–200ms |
| ドロップダウン、セレクト | 150–250ms |
| モーダル、ドロワー | 200–500ms |
| マーケティング/説明用 | より長くても可 |
UI アニメーションは 300ms 未満にします。 180ms のドロップダウンは、400ms のものよりも応答性が高く感じられます。
動きに慣性を伴うドラッグ、生き生きとした印象にしたい要素、ユーザーが中断または反転できるジェスチャー、装飾的なマウストラッキングには、スプリングを使います。
{ type: "spring", duration: 0.5, bounce: 0.2 } // Apple-style — easier to reason about
{ type: "spring", mass: 1, stiffness: 100, damping: 10 } // traditional physics — more control
バウンスは 0.1–0.3 に抑え、ほとんどの UI では避けます。ドラッグして閉じる操作や遊び心のあるインタラクションに限って使います。
6. 中断と終了
- すばやく再度トリガーされるものには、キーフレームではなくトランジションを使います — トースト、トグルなど、ユーザーが1秒間に2回操作できるものが対象です。トランジションは現在の値から再ターゲットしますが、キーフレームは最初から再生します。
- ジェスチャーにはスプリングを使います。中断時にも速度を引き継げるためです。
- 入ってきた経路と同じ経路で退出させます。 下からスライドして入るトーストは、下から退出させます。対称的な経路にすると、スワイプで閉じられることが直感的に伝わります。
- ユーザーが判断する場面では、タイミングを非対称にします。 意図的な動作の段階(長押しで確定する操作:2s linear)はゆっくり、システムの応答(指を離す操作:200ms ease-out)は素早くします。
7. 動きを減らす設定とポインターの制御
アニメーションを使う場合は、毎回同梱します。
@media (prefers-reduced-motion: reduce) {
.element { animation: fade 0.2s ease; } /* keep opacity/color, drop transform-based motion */
}
@media (hover: hover) and (pointer: fine) {
.element:hover { transform: scale(1.05); } /* touch fires false hovers on tap */
}
const reduce = useReducedMotion();
const closedX = reduce ? 0 : '-100%';
動きを減らす設定では、アニメーションをゼロにするのではなく、少なく、穏やかにします。理解の助けになるトランジションは維持し、移動や位置の変更は取り除きます。
レシピ
よくあるケース(ボタンの押下、ドロップダウン、ツールチップ、モーダル、ドロワー、トースト、アコーディオン、段階的な表示、長押しで確定する操作、タブインジケーター、スクロール時の表示、スワイプで閉じる操作)のすぐに実装できる例については、RECIPES.md を参照してください。依頼内容がこれらのコンポーネントに当てはまる場合は、これを読み込み、空のファイルからではなくレシピを基に始めてください。
リリース禁止事項
完了する前にセルフチェックしてください。以下はそれぞれ、review-animations による自動ブロックの対象です。
| 禁止事項 | 代わりに使うもの |
|---|---|
transition: all | 対象のプロパティを明示する |
transform: scale(0) による登場 | scale(0.95) + opacity: 0 |
UI 要素に ease-in を使う | ease-out または力強いカスタムカーブ |
意図的なアニメーションに組み込みの ease-out を使う | cubic-bezier(0.23, 1, 0.32, 1) |
| キーボードショートカットや1日100回以上使う操作へのアニメーション | アニメーションなし |
| 理由なく UI の表示時間を300msより長くする | 150〜250ms |
トリガーにアンカーされたポップオーバーに transform-origin: center を使う | var(--transform-origin)(モーダルは対象外) |
| トースト、トグル、頻繁にトリガーされる要素にキーフレームを使う | CSS トランジション |
width/height/margin/padding/top/left のアニメーション | transform/opacity |
14.2より前のバージョンで、負荷時に Motion の x/y/scale プロパティを使う | 14.2以降にアップグレードするか、transform 文字列を使う |
制御されていない :hover の動き | @media (hover: hover) and (pointer: fine) |
prefers-reduced-motion の設定がない | ゼロではなく、穏やかなバリエーションを使う |
| すべてを一度に表示する | 30〜80msの段階表示 |
出力
コードを書いてください。その後、数行以内で次のことを記述してください。
- 制御結果 — 頻度の段階と、明示した目的。依頼内容の一部を却下した場合は、対象と理由を記してください。
- 構成要素 — ツール、プロパティ、カーブ、時間またはスプリング設定を、それぞれ1行で記してください。
- 感覚的に確認すること — クロスフェード、スプリングの弾み、表示中のリストにおける不透明度と高さのバランスなど、コードだけでは判断できない感覚に結果が左右される場合は、その旨を伝え、確認方法を示してください。再生時間を2〜5倍にして再生するか、DevTools のアニメーションインスペクターで確認し、フレームごとに動きを追い、実機でジェスチャーを試し、翌日に新鮮な目で見直してください。
これを報告書のように膨らませないでください。成果物はコードです。
トーン
明確な意見を持ち、簡潔にしてください。正直な答えが「これはアニメーションにすべきではない」であれば、そのように伝えてください。その答えこそが、このスキルの存在理由です。コードだけでは感覚的な判断が本当にできない場合は、値を推測せず、その旨を伝えてください。