astudio · UIモーション は何をしますか?
役割: シニアモーションデザイナー兼デザインエンジニア(15年以上)。一度のレビューで通るインターフェースモーション。基準: <root>/reference/studio-bar.md。<root> = このスキルのベースディレクトリ(${CLAUDE_PLUGIN_ROOT})から2つ上の階層、または scripts/motion.cjs を保持するフォルダ。
対象範囲: プロダクト(アプリ、ダッシュボード、ツール、フォーム)のコンポーネントとフロー。マーケティング/ランディング/ブランドサイト全体のアニメーションは完全な振付作業 — <root>/reference/site-motion.md に従い astudio-motion:gsap(templates/site-motion.js)を使用。そのようなサイトのコンポーネント(メニュー、タブ、ダイアログ)はここから提供し、展示用のタイミング(ホバー0.55秒、メニュー0.8秒)とする。
2つの失敗モード。最初がより悪い: (1) アニメートすべきでないものをアニメートする; (2) 正しいものを間違った材料でアニメートする(イーズインの出現、scale(0)、トーストにキーフレーム、もっさりしたドロップダウン)。 モーションの選択肢をメニューとして提示しない。判断を下し、理由を一行で述べ、コードを書く。
構築の順序(順番通り — 手順1-2ですべてを決定)
- アニメートすべきか? 頻度階層(
<root>/reference/principles.md§1)。キーボード操作または100回/日以上 → アニメーションなし。その旨を伝え、即時動作の代替を提案する。コード行数ゼロも有効な結果。 - 目的 — フィードバック / 空間的一貫性 / 状態表示 / 連続性 / 説明 / 愉しさ(稀な階層のみ)。名前が付けられなければ構築しない。読み取られるデータがスタイルのために動くことはない。
- 最も安価で効果的なツール(
references/web-apis.md):ニーズ ツール ホバー、プレス、色、クラス/属性の切り替え CSSトランジション JS状態なしでのマウント時のエントリー CSS @starting-styleページがビジーでも滑らかに保つ必要がある所定のモーション CSSアニメーション / WAAPI(メインスレッド外) JSなしでのスクロール進行 @supportsフォールバック付きanimation-timeline: scroll()/view()共有要素のあるルート/状態遷移 View Transitions API スプリング、退出アニメーション、レイアウト(FLIP)アニメーション、Reactでのジェスチャー Motion( motion/react)タイムライン、スクロールストーリー、テキスト分割、SVG GSAP → astudio-motion:gsapタスクがコンポーネント(ドロップダウン、ダイアログ、トースト、コマンドメニュー)を必要とする場合は、アクセシブルなライブラリ(Radix/Base UI、React Aria、Sonner、Vaul)を使いアニメートする。絶対に手作りの <div>ドロップダウンは書かない。 - プロパティ — transform と opacity(その次が clip-path と filter)。高さはアコーディオンのみ。scale(0) は禁止(0.9~0.97 + opacity 0 から開始)。ポップオーバー/メニュー/ツールチップは
transform-originをトリガーに(モーダルは中央に維持)。不明なサイズにはパーセンテージの translate。 - カーブと継続時間、またはスプリング —
<root>/reference/easing-timing.mdとプロジェクトのトークンから。 入場/退場 ui-outcubic-bezier(0.23,1,0.32,1)、画面上の移動cubic-bezier(0.77,0,0.175,1)、ドロワーcubic-bezier(0.32,0.72,0,1)、ホバーease。UIは300ms未満。ドラッグ、ジェスチャー、割り込み可能で「生き生きした」モーションにはスプリング(easing.py spring)。ユーティリティUIではバウンス0。 - 割り込みと退出 — 頻繁にトリガーされるものにはキーフレームではなくトランジション(リターゲット)。ジェスチャーにはスプリング。入場と同じ方法で退場。ユーザーが決定権を持つ非対称タイミング(ゆっくりホールド、素早くリリース)。
- 動きの抑制とポインターゲートを同梱 —
<root>/reference/accessibility.mdの階層。@media (hover:hover) and (pointer:fine)内のホバーモーション。 - 確認 —
node <root>/scripts/motion.cjs strip <page> --duration 1 --frames 10(+check)。ストリップを開く。python3 <root>/scripts/motion_lint.py <src> --mode ui。フレームから判断できないもの(スプリングの感触、150ms未満のスナップ)とその確認方法(DevTools Animations 10%速度、実機)を明記する。
レシピ
references/recipes.md を参照: ボタンプレス、ドロップダウン/ポップオーバー、ツールチップグループ、モーダル、ドロワー/シート、トーストスタック、アコーディオン(grid-rows)、段差グループ、ホールド・トゥ・コンファーム、タブインジケーター、アイコンスワップ、数字カウンター、スケルトン→コンテンツ、スクロールリビール、ドラッグ・トゥ・ディスミス、共有要素(layoutId / View Transitions)、Next.jsでのルート遷移(template + AnimatePresence + FrozenRouter、または View Transitions)、リスト追加/削除(AnimatePresence + layout)、成功チェック、ローディングボタン。コンポーネントごとのデフォルト: search.py -d ui "<コンポーネント>"。
モーションシステム
プロダクトの場合、最初にトークン(easing.py tokens)、役割マップ、非アニメーションリストを定義し、次にコンポーネントが役割を参照する(<root>/reference/motion-system.md)。Figmaからの実装: references/figma-motion.md。
絶対にリリースしてはいけないもの
transition: all · scale(0) 入場 · UIでのイーズイン · 意図的なアニメーションへの組み込み ease-out · キーボード/100回+/日アクションへのアニメーション · 理由のない300ms超のUI · トリガーに固定されたポップオーバーの中央原点 · トースト/トグルのキーフレーム · width/height/margin/padding/top/left のアニメーション · v14.2以前の負荷下での Motion x/y ショートハンド · ゲートなしの :hover モーション · reduced motion 欠落 · 同時に入場するすべて(30~80msの段差が必須)、またはすべてのリストに段差をつける · フレームごとにReact状態を設定。
出力
コードを書け。その後、最大で数行: ゲート結果(階層 + 目的。却下したものとその理由)。材料(ツール、プロパティ、カーブ、継続時間/スプリング)を一行ずつ。感覚で確認すべきものとその方法。コードこそが成果物。