mcpField
A
animate

animate

github.com/emilkowalskiデザイン・UI51.1k179.1k 回インストール今日更新
リポジトリ

animate について

animateは、定められた手順とルールに基づいてUIの動きを実装するデザインエンジニアリングスキルです。動きの必要性と手法を判断し、実装では視差効果を減らす設定にも対応します。

主な機能

  1. 01動きの必要性の評価
  2. 02アニメーション手法の選択
  3. 03イージングと時間のルール適用
  4. 04視差軽減設定とホバー入力への対応
  5. 05一般的なUIモーションのレシピ

活用シーン

  1. 01モーダルやトーストへの動きの追加
  2. 02ドロップダウンの表示アニメーション実装
  3. 03頻繁な操作に動きが必要かの判断

インストール

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

$npx skills add https://github.com/emilkowalski/skills --skill animate

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

同梱ファイルRECIPES.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 が強制するのと同じ基準です。そのレビューを一発で通過するように書いてください。

失敗モードは二つあり、一つ目のほうが悪いです。

  1. アニメーション化すべきでないものをアニメーション化すること。 以下のゲートは、ときにゼロ行のコードを生み出すために存在します。それは回避ではなく成功です。
  2. 正しいものを間違った材料でアニメーション化すること — 入場時の ease-in、scale(0)、トーストへのキーフレーム、ドロップダウンを鈍重に感じさせる duration。

モーションの選択肢をメニューとして提示しないでください。判断を下し、理由を一行で述べ、コードを書いてください。

厳守事項

  1. シーケンスを順番に実行する。 ステップ 1 と 2 がすべてのゲートになります。そもそもアニメーションするかどうかを知る前に、カーブに手を伸ばさないでください。
  2. 近似値を使わない。 すべてのカーブ、duration、スプリング設定は以下の表から取ります。見慣れているからといって cubic-bezier(0.4, 0, 0.2, 1) をでっち上げないでください。
  3. コードベースのトークンを拡張し、分岐させない。 --ease-out や duration スケールがすでに存在するなら、それを使います。並行するシステムを追加することは欠陥です。
  4. ** reduced motion と hover のゲーティングはアニメーションと一緒にリリースする**、後追いではなく。
  5. 機能する中で最も安価なツール。 フェードのためにモーションライブラリをインストールしないでください。

構築シーケンス

1. そもそもこれをアニメーション化すべきか?
頻度判断
1 日 100 回以上(キーボードショートカット、コマンドパレットのトグル)アニメーションなし。絶対に。 ここで停止。
1 日数十回(ホバー効果、リストのナビゲーション)ほぼ知覚できないもののみ — 高速で控えめ、さもなくばなし
ときどき(モーダル、ドロワー、トースト)標準的なアニメーション
まれ / 初回(オンボーディング、成功、祝賀)喜びの予算はここにあります

キーボードで開始される操作は失格であり、判断の余地はありません。 Raycast には開閉アニメーションがありません。1 日に何百回も開くものにとって、それは正しいのです。

要求がこのゲートを通過しない場合は、はっきりとそう述べ、アニメーションを書かないでください。代わりにモーションを使わない代替案(即時の状態変化、静的なアフォーダンス)を提供してください。

2. 目的は何か?

続ける前に、次のいずれかの言葉でそれを名付けてください。

  • フィードバック — インターフェースがユーザーを聞き取ったことを確認する
  • 空間的一貫性 — 何かがどこから来てどこへ行ったかを示す
  • 状態の表示 — 状態の変化を読み取れるようにする
  • 唐突な変化の防止 — そうでなければ瞬間移動してしまうコンテンツをつなぐ
  • 説明 — 何かがどのように機能するかを示す(マーケティング / オンボーディングのみ)
  • 喜び — まれ / 初回の階層でのみ許可される

名付けられない?ならば構築しないでください。頻繁に見られる要素に対しての「かっこよく見える」は、やめる理由です。

機能も確認してください。ユーザーが読んだり操作したりしているデータは、スタイルのために動くべきではありません。装飾的なマウストラッキング効果はマーケティングページに属し、銀行アプリのグラフには属しません。

3. ツールを選ぶ — 機能する中で最も安価なもの

順にたどり、最初に当てはまったものを使います。

要件ツール
ホバー、押下、色、クラスまたは属性で制御する状態の切り替えCSS transition
マウント時の登場アニメーション、JS の状態なしCSS @starting-style
ページが読み込みで忙しい間もスムーズに保つ必要があるあらかじめ決まったモーションCSS アニメーション(メインスレッド外で実行されます)
ライブラリなしで、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 は 3 つすべてを発生させます。(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 では、完全な transform 文字列を使う。 x/y/scale の省略記法はハードウェアアクセラレーションされず、負荷がかかるとフレームを落とします:
<motion.div animate={{ x: 100 }} />                          // drops frames under load
<motion.div animate={{ transform: "translateX(100px)" }} />  // hardware accelerated
  • 親の 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 回発火させられるものすべて。トランジションは現在の値から再ターゲットされますが、キーフレームはゼロから再開します。
  • ジェスチャーにはスプリングを使う。中断をまたいで速度を引き継げるからです。
  • 入ってきた方法と同じ方法で退出させる。 下からスライドインしたトーストは下へ抜けていきます。対称的なパスが、スワイプで閉じる操作を直感的に感じさせます。
  • ユーザーが判断している局面では非対称なタイミングを使う。 意図的なフェーズはゆっくり(長押しで確定する押下:2 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 要素に対する easeease-out または強いカスタムカーブ
意図的なアニメーションに対する組み込みの ease-outcubic-bezier(0.23, 1, 0.32, 1)
キーボードショートカットや 1 日 100 回以上の操作に対するアニメーションアニメーションなし
理由のない 300ms 超の UI duration150〜250ms
トリガーに紐づくポップオーバーに対する transform-origin: centervar(--transform-origin)(モーダルは例外)
トースト、トグル、すばやく連続してトリガーされる要素に対するキーフレームCSS トランジション
width/height/margin/padding/top/left のアニメーションtransform / opacity
負荷がかかった状態でのモーションの x/y/scale プロパティ完全な transform 文字列
ゲーティングされていない :hover のモーション@media (hover: hover) and (pointer: fine)
prefers-reduced-motion の欠如ゼロではなく、より穏やかなバリアント
すべてが同時に登場する30〜80ms のスタッガー

出力

コードを書きます。その後、数行以内で次を記します。

  • ゲートの結果 — 頻度のティアと、名前を付けた目的。リクエストの中で却下したものがあれば、どれを、なぜ却下したかを述べてください。
  • 構成要素 — ツール、プロパティ、カーブ、duration またはスプリングの設定を、それぞれ 1 行ずつ。
  • 体感で確認すべきこと — 結果がコードからは判断できない体感に依存する場合(クロスフェード、スプリングの跳ね返り、登場するリストにおける opacity と height のバランスなど)、そう述べて確認方法を指し示してください。duration の 2〜5 倍で再生するか DevTools のアニメーションインスペクターでフレームごとに進め、ジェスチャーは実機でテストし、翌日あらためてフレッシュな目で見直してください。

これを引き延ばしてレポートにしないでください。コードが成果物です。

トーン

断定的かつ簡潔に。「これはアニメーションさせるべきではない」が正直な答えであるときは、そう答えてください — その答えこそがこのスキルが存在する理由です。体感がコードからは本当に決められないときは、値を推測するのではなく、そう述べてください。

コメント