Communitygithub.com

nkurunziza-saddy/motion

プロダクトUIのモーションを構築します。要素が動くべきか、その理由、使用するツール(CSSトランジション、WAAPI、Motion、スプリング)、プロパティ、カーブ、持続時間、割り込み、終了、縮小モーションパスを判断し、コードを記述します。また、スタガーとコレオグラフィ、ジェスチャー(ドラッグ、フリック、シート)、モーショントークン、アニメーションパフォーマンスもカバーします。

motion とは?

このスキルは、UIモーションの設計と実装のための包括的なガイドラインを提供します。速度とパフォーマンスを最適化するために、**頻度ゲート**を使用してアニメーションの必要性を評価し、不要なモーションを排除します。**ツールの選択**では、CSSトランジション、WAAPI、Motionライブラリの中から最も軽量なものを選択するための明確な基準を提示します。**コレオグラフィ**では、各要素の役割(主役、サポート、装飾、静的)に基づいて動きを割り当て、一貫性のあるエクスペリエンスを実現します。また、スプリングベースのアニメーション、割り込み処理、終了アニメーション、`prefers-reduced-motion`への対応、パフォーマンス検証に関する実践的なレシピとペア(良い例/悪い例)も含まれています。このスキルは、Claude Code、Cursor、CodexなどのAIエージェント向けに設計されており、モーションの決定を自動化し、UIの一貫性とパフォーマンスを向上させます。

対応~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/nkurunziza-saddy/hmm-interfaces/tree/HEAD/motion

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

motion は何をしますか?

このスキルはモーションを構築します。product-ui/references/values.md のモーションセクションを拡張します。このファイルには確定した数値(イージングカーブ、プレススケール、バウンス、スタガー、持続時間テーブル、トーストとレイアウトの持続時間、移動距離、終了と開始の比率)が含まれています。これらの数値はここでは繰り返しません。このスキルは、決定の順序、トークン、レシピ、失敗モードを追加します。

決定を行う前に、product-ui の §1(テイストジャーナルと優先順位)と §5(どのスキルが何を担当するか)を適用してください。

決定順序

以下を上から下へ進めてください。各ステップでジョブを終了できます。アニメーションがゼロ行という結果も有効であり、その旨を明示してください。

1. 動くべきか?:頻度ゲート

1人のユーザーがこれを1日に何回見るかを尋ねてください。階層はvalues.mdにあります。実際には:

  • キーボードによって開始される、または1日に100回以上表示される:モーションなし。理由:繰り返されるモーションは遅延に変わります。
  • 1日に数十回表示される(ホバー、タブ切り替え、行選択):なし、または瞬間的な色の変更。
  • ユーザーが読んだり操作したりしているデータ(テーブル内の数値、ライブダッシュボードのチャート)は、スタイルのために動くことはありません。理由:モーションは読んでいるものから目をそらします。
  • ゲートが「いいえ」と判断した場合、アニメーションを記述しないでください。該当する階層を示し、静的な代替案(瞬間的な状態変更)を提案してください。

2. 目的を命名する

1つの単語を選んでください:spatial(どこから来たか、どこへ行ったか)、state(これが変わった)、feedback(聞きました)、continuity(ジャンプを防ぐ)、explanation(まれな瞬間のみ)。名前を付けられない場合は停止してください。理由:頻繁な要素に対する「見た目が良い」という理由は、UIが遅く感じられる主な原因です。

3. ツールを選ぶ:最も安価で動作するもの

ニーズツール
クラス、属性、ホバー、プレスで切り替わる状態CSS transition
display: none、ポップオーバー、ダイアログから出現@starting-style + transition-behavior: allow-discrete
1回限りのシーケンス、スタガー、またはページがビジーなときに実行する必要があるモーションCSS @keyframes
JSがタイミングを決定し、キャンセル、逆再生、finished、FLIPが必要WAAPI el.animate()
スプリング、ベロシティハンドオフ、アンマウントするReactノードの終了、共有レイアウトMotion (motion/react)

対象がコンポーネント全体(メニュー、トースト、ドロワー)の場合は、フォーカスハンドリングを備えたライブラリを使用し、pick-library に問い合わせてください。フェードのためにMotionをインストールしないでください。理由:CSSはメインスレッド外で実行され、バンドルサイズが増えません。

4. プロパティ

  • transform と opacity をアニメーション化してください。filter は ≤ 2pxのスワップブラーの場合のみ使用します。すべてのプロパティを指定してください。transition: all は絶対に使用しないでください。
  • 高さとレイアウトの変更:references/recipes.md(グリッド行、FLIP)を参照してください。何かを動かすために width、top、left、margin をアニメーション化しないでください。理由:それぞれがフレームごとにレイアウトを強制します。
  • box-shadow をアニメーション化しないでください。代わりに疑似要素の opacity をフェードしてください。
  • translate のパーセンテージは要素自身のサイズを基準とするため、translateY(100%) は任意の高さのドロワーやトーストに適合します。

5. カーブと持続時間、使用法に合わせて

推測に最も近い数字を決して選ばないでください。使用法(「メニュークローズ」「アイコンスワップ」)を指定し、references/tokens.md から該当する行を取得してください。使用法に一致する行がない場合は、使用法にちなんで新しいトークンを追加してください。既存のトークンを曲げないでください。理由:トークンはモーションの目的を表すものであり、間違った使用法で近い数値を使用することは間違ったトークンです。

  • 開始または終了:--ease-out。画面上で移動:--ease-in-out。ドロワー:--ease-drawer。色:ease。スピナー:linear。ease-in は絶対に使用しないでください。
  • ドラッグ可能または途中で割り込み可能なものは、カーブではなくスプリングを使用してください。理由:カーブはユーザーの手が持っていた速度を受け入れられません。
  • 遅く感じる場合:まず持続時間を短くし、次に距離を短くし、最後にカーブに触れてください。

6. 割り込み

  • ユーザーが1秒間に2回トリガーできるものは、トランジションまたはスプリングにしてください。@keyframes は絶対に使用しないでください。理由:トランジションは現在の値から再ターゲットします。キーフレームは再起動してジャンプします。
  • WAAPI:現在の値を読み取った後、古いアニメーションをキャンセルし、その値から新しいアニメーションを開始してください(references/recipes.md)。
  • 10回連続でトグルされた場合、正しい状態で終了し、ジャンプがないことを確認してください。テストしてください。

7. 終了

  • デフォルトの終了はフェードで、開始よりも短くします(トークンファイルに各ペアがあります)。
  • 方向のあるもの(ドロワー、シート、スワイプされたトースト)は、来た道に戻ります。
  • 終了する要素はすぐにスペースを占有しなくなるため、フェード中に兄弟要素がそのギャップを埋めます。
  • 終了は同時であり、スタガーされることはありません。理由:ユーザーはすでに去ることを決定しています。

8. アニメーションと共に出荷される縮小モーション

不透明度と色は残ります。スライド、スケール、ブラー、バウンスは削除されます。スライドはフェードに、バウンスは 0 になります。モーションを唯一の手がかりとして使用しないでください。パターンは references/recipes.md にあります。

コレオグラフィ

タイミングを設定する前に、動くすべての要素に役割を割り当ててください:

役割処理
主役(注目すべき1つのもの)最初に動き、最も多く移動する
サポート遅れて動き、移動距離は少ない
装飾その場でフェードイン、または動かない
静的(コンテナ、クローム)決して動かない
  • コンテナごとに1つの開始アニメーション。パネルがスライドインする場合、そのコンテンツはすでにそこにあります。理由:2つの重なった開始アニメーションは、ユーザーを2回待たせます。
  • DOM順ではなく、重要度順に並べてください。遅延はvalues.mdのステップ(アイテム間40ms、タイトル、テキスト、アクション間100ms)に従ってください。遅延ではなく、役割によって距離と持続時間を変えてください。
  • リストのスタガーはインデックス6(最大遅延240ms)で打ち切ってください。それ以降のアイテムはその遅延を共有します。スタガー中も入力は機能します。
  • メニュー、コマンドパレット、タブコンテンツ、または繰り返し開くものをスタガーしないでください。
  • 静止を保つ:ユーザーがクリックしようとしているもの、ページが再度読み込まれたときにすでに画面にあるもの、最後の更新から150ms以内に到着した更新(最終状態にジャンプ)。
  • 方向は意味に従います:次は右から入り、戻るは左から入ります。ユーザーがトリガーしたものはトリガーから外側に向かって成長します。

必要なときにロード

  • references/tokens.md:正確な持続時間、距離、スケール、ブラー、イージング、スプリング値、および既存のコードベースのトークン化のためにロードします。
  • references/recipes.md:メニュー、ポップオーバー、ダイアログ、ドロワー、トースト、リストの開始、アイコンスワップ、高さ変更、タブインジケーター、数値変更を構築するときにロードします。
  • references/gestures.md:ドラッグ、スワイプ、フリック、シート、またはポインターに従うもののためにロードします。
  • references/performance.md:モーションがフレームをドロップしたとき、will-change に手を伸ばす前、および更新が高速に到着するときにロードします。

ペア

問題あり修正済み理由
.menu { transition: all 300ms ease-in }transition: opacity 200ms, transform 200ms var(--ease-out)名前付きプロパティ。ease-inは鈍い。メニューは ≤ 200ms
scale(0) から scale(1)scale(0.95) と opacity: 0 から 1何もないところからは何も現れない
ポップオーバーが中心からスケールtransform-origin: var(--transform-origin)トリガーから外側に成長する必要がある
.open { animation: slide-in 300ms }トグルされた状態に transition: transformキーフレームは割り込み時にスナップする
すべての行 animation-delay: i * 120msmin(i, 6) * 40ms最後の行が300ms以内に到着する
ドロワーがスライドイン後にフェードアウト来た道をスライドバックアウトする方向が説明である
固定された ease-out でのドラッグ解放解放速度で初期化されたスプリング手の勢いが持続する
pointermove 内の setY(y)el.style.transform = ...フレームごとの再レンダリングなし

終了前に

変更差分を検索し、確認してください。

検索対象修正
transition: all、* に対する will-change、ease-in名前付きプロパティ、削除、--ease-out
scale(0)、ポップオーバーに対する transform-origin: center0.95、トリガーの起点(ダイアログは中央のまま)
トグルするクラスに対する @keyframesトランジション
tokens.mdの該当行を超える持続時間、またはtokens.mdにない数値使用法のトークン
keydown ハンドラーまたはパレットに対するモーション削除
トランジション内の width、height、top、left、box-shadowtransform、opacity、またはレシピ
prefers-reduced-motion パスがない追加する

実行中のアプリで確認する:4倍速で再生し(DevTools Animationsパネル、または持続時間を乗算)、任意のトグルを連打し、縮小モーションをオンにしてテストし、CPUを4倍にスロットリングしてください。実行できなかったものを述べてください。

Individual skills in this repo

This repo contains 4 individual skills — each has its own dedicated page.

nkurunziza-saddy/break

Stress-tests a piece of UI with worst-case data and every reachable state, then reports what broke with a numbered fix for each. Use it when the user types /break, or asks to "break this", "stress-test", "try the worst case", "what happens with long names", "check the empty and error states" or "find the edge cases" on a component or screen.

nkurunziza-saddy/layout

Structure and space in product UI on the web. It sets the spacing scale, grouping, alignment, density (compact or comfortable), hit areas, app shells (sidebar, toolbar, content, inspector), max widths, container-query responsiveness, dropdown and popover sizing, room for long and translated text, layout stability (no shift on load) and sticky elements that must not cover focus.

nkurunziza-saddy/pick-library

Picks the right library for a frontend task from a curated, status-checked list, instead of hand-rolling it or installing an abandoned package. Use it when the user asks "what should I use for…", "is there a library for…", or names a package, and when you are about to build a toast, command menu, drawer, date picker, table, virtual list, drag and drop, chart, OTP input, animated number, theme switch, form validation…

nkurunziza-saddy/surfaces

What product UI is made of on the web. It sets elevation levels with exact shadow recipes for light and dark mode, when to use a shadow and when a border, the transparent border for forced-colours mode, a small radius scale with concentric nesting, image outlines, every interactive state as a surface change (hover, pressed, selected, disabled, focus-visible), icons (one set, currentColor, outline and fill, stroke tha…

関連スキル