css-animation について
アプリ機能を再現する自己完結型 HTML/CSS アニメーションを作るスキルです。製品紹介やオンボーディング向けに、調査から生成・レビューまでを案内し、機能デモとカルーセルに対応します。
主な機能
- 01Chrome でアプリの見た目を調査
- 02機能デモとカルーセル形式
- 03デスクトップとモバイルの出力
- 04ブリーフと HTML アニメーションの生成
- 05反復レビューと調整
活用シーン
- 01アプリ機能の状態変化の紹介
- 02複数画面の製品ウォークスルー作成
- 03デスクトップまたはモバイル向け導入デモの準備
MCP 対応
調査段階で Claude-in-Chrome MCP ツールを使い、対象アプリを確認して視覚情報を抽出します。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ neonwatty/ css-animation-skill --skill css-animationインストール後、Claude Code で/css-animationを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
LICENSECNAMEREADME.mdindex.htmldocs/plans/2026-02-26-css-animation-skill-design.md2026-02-26-css-animation-skill-implementation.mdexamples/seatify-optimize-brief.mdseatify-rsvp-brief.mdseatify-rsvp.htmlseatify-optimize.htmlseatify-walkthrough.html詳細
CSS アニメーションの手順
実際のアプリの機能を再現する、洗練された自己完結型の HTML/CSS アニメーションを作成します。これらは、ウォークスルー、オンボーディングのデモ、マーケティングに使用されます。GIF ではありません。解像度に依存せず、ファイルサイズが小さく、簡単に反復できます。
2 つのアニメーションスタイル
- 機能デモ — Before → Action → After。単一の機能の変化を示します(例:「Optimize」をクリックして、座席が再配置される様子を表示)。
- カルーセル — 複数のビュー。クロスフェード遷移で、複数のアプリ画面を切り替えます(例:ダッシュボード → ゲストリスト → キャンバス → RSVP)。
インタビューの段階で、ユーザーが必要とするスタイルを判断します。
フェーズ
Phase 1: Research → Phase 2: Interview → Phase 3: Generate → Phase 4: Review Loop
フェーズ 1:調査
何かを生成する前に、Chrome でアプリを操作し、対象アプリのビジュアルシステムを詳しく把握します。
前提条件
- Claude-in-Chrome MCP ツールを利用できること
- 対象アプリにブラウザーからアクセスできること(ローカルで実行中、またはデプロイ済み)
ステップ 1:Chrome をセットアップする
tabs_context_mcpを呼び出して既存のタブを確認します- 新しい専用タブを作成します:
tabs_create_mcp - このタブ ID を保存し、以降のブラウザー操作にはこのタブのみを使用します
ステップ 2:移動して調べる
- 対象アプリの URL に移動します
- 認証が必要な場合は、ユーザーに手動でログインしてもらい、その後再開します
- モバイル、または両方を対象にする場合: 機能に移動する前に、
resize_windowを使ってブラウザーをモバイルのビューポート(390×844px)にリサイズします。これにより、デスクトップ版を縮小したものではなく、アプリの実際のモバイルレイアウトを調査できます。両方を対象にする場合は、まずデスクトップをフルサイズで調査してから、モバイルにリサイズし、モバイルレイアウトを再抽出します。 - アニメーション化する特定の機能/ページに移動します
- レイアウトを把握するため、調査用のスクリーンショットを撮影します
ステップ 3:デザイン言語を抽出する
read_page、find、javascript_tool を使って、以下を抽出します。
- 色:背景、サーフェス、境界線、アクセント/プライマリー、テキスト、薄いテキスト
// Example: extract computed styles const body = getComputedStyle(document.body); JSON.stringify({ bg: body.backgroundColor, color: body.color, fontFamily: body.fontFamily }) - フォント:見出しの font-family、本文の font-family、使用されているフォントウェイト
- 間隔:パディング、マージン、border-radius の値
- コンポーネントのスタイル:ボタン、カード、バッジ、アバター、サイドバーパネル
これらを CSS カスタムプロパティとして記録します(例:--bg: #0f0f0f)。
ステップ 4:レイアウトの形状を把握する
アニメーション化する特定の機能について、以下を調べます。
- コンテナーの寸法:主要なコンテナーの幅、高さ、位置
- 要素の位置:主要な要素の絶対座標
- 関係性:どの要素がどの要素に含まれるか、z-index の重なり順
- 円形の要素:中心点と半径
- 長方形の要素:原点(左上)、幅、高さ
javascript_tool を使って正確な位置を抽出します。
const el = document.querySelector('.selector');
const rect = el.getBoundingClientRect();
`${rect.left}, ${rect.top}, ${rect.width}, ${rect.height}`
ステップ 5:主要な状態のスクリーンショットを撮影する
以下のスクリーンショットを撮影します。
- 機能のデフォルト/初期状態
- 中間状態(ホバー、読み込み中、処理中など)
- 機能の動作が完了した後の最終/結果状態
これらのスクリーンショットは、生成時の視覚的な参照として使用します。
フェーズ 2:インタビュー
アニメーション化する内容を定義するため、ユーザーに要点を絞った質問をします。それぞれに AskUserQuestion を使い、一度に 1 つずつ複数選択肢を提示します。
質問 1:アニメーションスタイル
"What style of animation should this be?"
- Feature Demo (Recommended): Before → Action → After. Shows one feature transformation.
- Carousel: Cycles through multiple app views with cross-fade transitions.
質問 2:対象サイズ
"What size should the animation target?"
- Desktop only (960×620px) — for landing pages, marketing, desktop walkthroughs
- Mobile only (360×640px) — for in-app tour tooltips, mobile onboarding
- Both — generates two files from the same brief, one per viewport
モバイルまたは両方が選択された場合:
- モバイル版では 360×640px のステージを使用します(縦向きで、一般的なスマートフォンのビューポートに合わせます)
- レイアウトを簡略化します:要素を減らし(最大 8~12 個)、相対的なサイズを大きくし、サイドバーは使いません
- 小さな画面に適さない要素(幅の広いツールバー、複数列のレイアウトなど)を省きます
- 横並びより縦並びを優先します
- ステージに対するフォントサイズを大きくします(本文は最低 11px、見出しは 14px)
- ファイル名:
<app>-<feature>.html(デスクトップ)、<app>-<feature>-mobile.html(モバイル)
質問 3:機能の特定
"What specific feature or flow should the animation show?"
- [Options based on research phase findings]
- Other (user describes)
質問 4:見せ場となる瞬間
"What's the key moment — the visual 'wow' of this animation?"
- [Options relevant to the chosen feature]
- Other
質問 5:強調点
"Is there anything specific to emphasize or avoid showing?"
- Show everything as-is
- Emphasize specific elements (user specifies)
- Hide certain elements (user specifies)
質問 6:出力先
"Where should I save the animation files?"
- Current directory: [show cwd path]
- Desktop
- Other (user specifies path)
生成に必要な情報が揃ったら、3~6 個の質問で終了します。質問しすぎないでください。
フェーズ 3:生成
このフェーズでは、2つの成果物を作成します。ブリーフ(Markdown)とHTML アニメーションファイルです。
3a:ブリーフの生成
アニメーションを生成または再生成するために必要なすべての情報をまとめた、構造化された Markdown ドキュメントを作成します。ユーザーが選択したディレクトリに <app>-<feature>-brief.md として保存します。
ブリーフの形式:
---
app: <App Name>
feature: <Feature Name>
style: feature-demo | carousel
target: desktop | mobile | both
output_file: <app>-<feature>.html
output_file_mobile: <app>-<feature>-mobile.html # only when target is mobile or both
---
# Design Language
- Background: <hex>
- Surface: <hex>
- Border: <hex>
- Accent: <hex> (<name>)
- Text: <hex>
- Text dim: <hex>
- Heading font: <font> (serif/sans-serif)
- Body font: <font> (sans-serif)
- Border radius: <N>px
- Additional colors: <name>: <hex> (for groups, statuses, categories, etc.)
# Layout (Desktop)
- Stage: 960x620px
- [Container hierarchy description]
- [Element positions with exact pixel coordinates]
- [Circular elements: center point (x,y), radius R]
- [Rectangular containers: origin (x,y), width, height]
- [Item sizing: WxH px]
# Layout (Mobile)
- Stage: 360x640px
- [Simplified container hierarchy — no sidebars, single-column]
- [Reduced element count: 8–12 elements max]
- [Element positions recalculated for smaller stage]
- [Larger relative element sizing: e.g., 36x36px avatars instead of 30x30px]
- [Elements or sections omitted from desktop version and why]
# Animation Plan
## Style: Before → Action → After
(or: ## Style: Carousel with N scenes)
### Before State
- [Element positions, visual state, text content]
- [For circular layouts: N items, angular spacing, starting angle]
### Action (feature-demo only)
- [User action: cursor movement, button click]
- [Intermediate states: loading, processing]
### After State
- [New positions, trigonometrically calculated for circles]
- [Visual changes: colors, borders, labels, badges]
- [Text content changes]
### Scene N (carousel only)
- [What's visible in this scene]
- [Entry animations for elements]
- [Duration and transition to next scene]
### Timing
- Total loop: <N>s
- [Phase-by-phase durations]
- Easing: cubic-bezier(0.34, 1.56, 0.64, 1) for spring motion
- Easing: ease-in-out for fades
HTML を生成する前に、ブリーフをユーザーに提示します。
"Does this brief capture the animation correctly?"
- Yes, generate the animation
- Needs adjustments (user specifies)
ユーザーの承認を得るまでブリーフを修正してから、3b に進みます。
3b:HTML/CSS アニメーションの生成
ブリーフを仕様として、自己完結型の HTML ファイルを生成します。ユーザーが選択したディレクトリに <app>-<feature>.html として保存します。
ファイル構成
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><App> – <Feature> Animation</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=...');
/* ALL CSS here — no external stylesheets */
</style>
</head>
<body>
<div class="stage" id="stage">
</div>
<script>
// Minimal JS: setTimeout loop controller + class toggling ONLY
</script>
</body>
</html>
技術ルール(必須)
1. 円形レイアウトの配置には三角関数を使用します。
円周上の位置を目分量で決めてはいけません。必ず計算します。
left = centerX + R * cos(angle_radians) - (elementWidth / 2)
top = centerY + R * sin(angle_radians) - (elementHeight / 2)
以下のとおりです。
R= コンテナの表示半径 +(要素サイズ / 2)。これにより、要素の内側の端がコンテナの周囲に接します。- N 個の項目を均等に配置する場合:
angle_i = startAngle + i * (2 * PI / N)。開始位置は中央上部の-PI/2とします。 - 度数をラジアンに変換する場合:
radians = degrees * PI / 180
中心が (140, 160)、R=95 の円周上に、30x30px の項目を 7 個配置する例:
Item 0: angle = -90° → left = 140 + 95*cos(-90°) - 15 = 125, top = 160 + 95*sin(-90°) - 15 = 50
Item 1: angle = -38.6° → left = 140 + 95*cos(-38.6°) - 15 = 199, top = 160 + 95*sin(-38.6°) - 15 = 86
...etc for all N items
2. 長方形の辺に沿った配置。
長方形の辺に沿って項目を均等に配置します。
- 上辺/下辺:X を等間隔で変化させ、Y は辺の位置 ±(要素の高さ / 2)にします。
- X 間隔:
containerLeft + containerWidth * (i + 1) / (numItemsOnEdge + 1) - 左辺/右辺:同じ方法で、Y を変化させます。
3. 自己完結型 HTML。 Google Fonts の @import 以外に外部依存関係を使用しません。すべての CSS を <style> に、すべての JS を <script> に記述します。ビルド工程は不要です。
4. 要素の移動には CSS トランジションを使用します。
.element {
position: absolute;
transition: left 1.2s cubic-bezier(0.34, 1.56, 0.64, 1),
top 1.2s cubic-bezier(0.34, 1.56, 0.64, 1);
}
5. JS はループ制御とクラスの切り替えにのみ使用します。
重要:インラインスタイルは絶対に使用しないでください(JS のリセット/更新関数内で element.style.opacity = '1' のように記述しないでください)。インラインスタイルは CSS クラスのルールを上書きし、状態の不具合(例:「非表示」の要素が、インラインスタイルが CSS クラスに優先するため表示されたままになる)が発生します。クラスの切り替えのみを使用してください。
const stage = document.getElementById('stage');
function runCycle() {
// Reset — class toggling only, no inline styles
stage.classList.remove('clicking', 'processing', 'optimized', 'complete');
// Reset text content to before-state values
setTimeout(() => stage.classList.add('clicking'), 500);
setTimeout(() => {
stage.classList.remove('clicking');
stage.classList.add('processing');
}, 900);
setTimeout(() => {
stage.classList.remove('processing');
stage.classList.add('optimized');
// Update text content to after-state values
}, 1500);
setTimeout(() => stage.classList.add('complete'), 3000);
setTimeout(runCycle, 6000); // Loop
}
setTimeout(runCycle, 300);
初期設定は短い時間にします。 ユーザーがアニメーションを最初に想定した速度より速くしたい場合がほとんどです。まずはテンポのよい設定にします。
- 変化前の状態を保つ時間:0.3~0.5s(状態を認識できる最低限の長さ)
- 要素間のずらし時間:0.3~0.5s
- 変化後の状態を保つ時間:2~3s
- ループ全体の時間:5~8s
- タイミングはフェーズ 4 で反復的に調整します。まずは短く設定し、求められた場合にのみ遅くします。
6. インタラクティブではないアニメーションには CSS の @keyframes を使用します — カーソルの移動、バッジの表示、スピナーの回転などです。該当する要素に animation プロパティを使用します。
7. トランジションを段階的にずらします。 各要素に transition-delay を設定し(0.04~0.08s ずつ間隔をあけます)、自然に感じられる順番のある動きを実現します。
8. 対象に応じたステージの寸法。
- デスクトップ: 960×620px、
border-radius: 12px - モバイル: 360×640px、
border-radius: 16px(縦向き) - アプリのデザイン言語(ダーク/ライトテーマ、色)に必ず合わせます。対象のビューポートにおけるアプリの実際のレイアウトに応じて、比率を調整します。
9. 非表示の要素には、opacity: 0 と併せて visibility: hidden を使用します。 暗い背景では、JPEG のスクリーンショット圧縮によって不透明度 0 の要素にアーティファクトが生じ、薄く残像のように見えることがあります。必ず併用してください。
.element-hidden {
opacity: 0;
visibility: hidden;
transition: opacity 0.5s ease-out, visibility 0s 0.5s; /* visibility delays on hide */
}
.element-hidden.visible {
opacity: 1;
visibility: visible;
transition: opacity 0.5s ease-out, visibility 0s 0s; /* visibility instant on show */
}
プレースホルダーテキストのように、非表示にしたときにフローから完全に取り除く必要がある要素には、親クラスの切り替えを使って display: none を適用します。
.stage.active .placeholder { display: none; }
10. コンテンツがステージ内に収まることを確認します。 生成後、レビューループに入る前に JS を挿入し、すべてのコンテンツがステージの境界内に収まっているか確認します。
var content = document.querySelector('.content');
var stage = document.getElementById('stage');
JSON.stringify({ stageH: stage.offsetHeight, contentH: content.scrollHeight, fits: content.scrollHeight <= stage.offsetHeight - content.offsetTop })
コンテンツがはみ出している場合は、余白(パディング、マージン、フォントサイズ)を小さくするか、ステージの高さを増やしてから続行します。はみ出しの不具合にレビューの時間を費やさないようにします。
カルーセル固有のルール
- 各シーンでは、
opacityのキーフレームを使って表示/非表示を切り替えます(フェードイン → 表示 → フェードアウト)。 - 各シーン内の子要素には、
animation-delayを使って段階的に表示します。 - ループ全体の長さ = すべてのシーンの長さの合計 + トランジションの間隔。
- シーンの表示には、パーセンテージベースのタイミングを指定した
@keyframesを使います。 - 各シーンは、
position: absolute; inset: 0;を指定したコンテナーdivにします。
機能デモ固有のルール
- デフォルトの CSS で、すべての要素の「変換前」の位置を定義します。
- 変換後の位置は
.stage.optimized .element { left: ...; top: ...; }の下に記述します。 - JS のクラス切り替え(
stage.classList.add('optimized'))で CSS トランジションを開始します。 - 次の要素を含めます:アニメーションするカーソル(CSS キーフレーム)、クリック時のフラッシュ効果、処理中のスピナーオーバーレイ。
- 次の要素を含めます:変換後にアニメーション表示する完了バッジ。
- JS の setTimeout チェーンで、テキストコンテンツ(カウンター、ラベル)を更新します。
モバイル固有のルール
モバイルアニメーション(360×640px のステージ)を生成する際は、次の点に従います。
- 大胆に簡略化します。 すべての UI 要素ではなく、機能の要点を見せます。デスクトップ版のアニメーションでツールバー、サイドバー、キャンバス全体を表示する場合、モバイル版では主要な操作だけを表示します。
- 要素は最大 8~12 個にします。 小さなステージはすぐにごちゃつきます。まず装飾要素を削り、次に補助的な UI を減らします。
- アニメーションするカーソルは使用しません。 モバイルはタッチ操作のため、タップ位置で短く円が脈打つインジケーターに置き換えます。
- 相対的に大きくします。 要素はステージに対して比例的に大きくします。デスクトップ版が 960px のステージで 30×30px のアバター(3.1%)を使う場合、モバイル版では 360px のステージで 36×36px(10%)にします。
- 1 列のレイアウトにします。 サイドバーは使わず、コンテンツを縦に並べます。
- アクションは下部に配置します。 モバイルアプリの一般的なレイアウトに合わせ、ボタンや CTA をステージの下部に配置します。
- スペースが足りない場合はナビゲーションバーを省略します。 アニメーションでアプリの全体的な枠組みを再現する必要はありません。機能部分に焦点を当てます。
1 つのブリーフから両方のバリアントを生成する場合:
- まずデスクトップ版(
<app>-<feature>.html)を生成します。 - 次に、モバイル版(
<app>-<feature>-mobile.html)を別ファイルとして生成します。 - モバイル版は小さなステージ向けに意図的に再設計したものであり、縮小コピーではありません。
- 両方のファイルで同じデザイン言語(色、フォント)を使いますが、レイアウトはそれぞれ独立させます。
- フェーズ 4 では、各バリアントを個別にレビューします。
フェーズ 4:レビューループ
これが品質を確保するための中核的な仕組みです。アニメーション HTML を生成した後、ユーザーが承認するまで反復的なレビューループを行います。
ステップ 1:アニメーションをローカルで配信する
- Python HTTP サーバーがすでに起動しているか確認します。
lsof -i :8765 - 起動していない場合は、出力ディレクトリで起動します。
python3 -m http.server 8765 --directory <output-directory> & - フェーズ 1 で使用した Chrome のタブを使うか、新しいタブを作成します。
- モバイルアニメーションをレビューする場合: 移動前に
resize_windowを使ってブラウザーをモバイルのビューポート(390×844px)にリサイズします。これにより、デスクトップのウィンドウ全体に引き伸ばされず、意図したスケールでアニメーションを確認できます。 - 次の場所に移動します:
http://localhost:8765/<filename>.html?v=<timestamp>
編集するたびにキャッシュを無効にするため、必ず ?v=<Date.now()> を追加します。
両方のバリアントをレビューする場合: まずブラウザーを最大サイズにしてデスクトップ版のアニメーションをレビューし、次にモバイル向けにリサイズしてモバイル版をレビューします。レビューは分けて行い、バリアント間でフィードバックを混在させないでください。
ステップ 2:各重要状態を固定して確認する
JavaScript を実行してアニメーションを停止し、特定の状態を設定します。
// Stop ALL pending timers
var id = window.setTimeout(function(){}, 0);
while (id--) { window.clearTimeout(id); }
// Reset stage
var stage = document.getElementById('stage');
stage.classList.remove('clicking', 'processing', 'optimized', 'complete');
// Hide cursor
var cursor = document.querySelector('.cursor');
if (cursor) { cursor.style.animation = 'none'; cursor.style.opacity = '0'; }
// Hide badges/overlays
var badge = document.querySelector('.optimized-badge');
if (badge) { badge.style.display = 'none'; }
次に、対象の状態を設定します。
- 変換前の状態:すべてのクラスを削除したままにします(デフォルトの CSS 位置が適用されます)。
- 変換後の状態:
stage.classList.add('optimized');を実行し、テキストコンテンツを更新します。 - 完了状態:
stage.classList.add('optimized', 'complete');を実行し、バッジを表示します。
各状態を設定した後にスクリーンショットを撮り、ユーザーに提示します。
確認する主な状態
機能デモ:
- 変更前の状態 — すべての要素が表示されていますか? コンテナーの周縁に正しく配置されていますか? 色はアプリと一致していますか?
- 変更後の状態 — 要素は周縁に配置されていますか? グループ分けは正しいですか? ラベルとバッジは正しく配置されていますか?
- バッジ/オーバーレイ — 完了バッジが重要な要素を隠していませんか?
カルーセル:
- 各シーン — レイアウトはアプリと一致していますか? 要素のスタイルは適切ですか? テキストの内容は正しいですか?
ステップ 3:フィードバックを集める
確認した状態ごとに、AskUserQuestion を使用します。
"How does the [BEFORE / AFTER / Scene N] state look?"
Options:
- Looks good
- Element positions are off (not on perimeters, wrong placement)
- Colors or styling need adjustment
- Layout or spacing needs changes
- Text content is wrong
- [Other]
複数の問題がありそうな場合は、multiSelect: true を有効にします。
ステップ 4:修正して再確認する
ユーザーから問題の報告があった場合:
- 現在の HTML を読み取り、CSS の構造を把握します
- 根本原因を特定します:
- 周縁から位置がずれている → 三角関数の公式を使って再計算します
- 色が違う → CSS カスタムプロパティを更新します
- レイアウトがずれている → コンテナーの位置と絶対座標を確認します
- テキストが違う → HTML の内容を更新します
- バッジが要素を隠している → バッジの位置または z-index を調整します
- Edit ツールを使って修正を適用します
- 修正によって仕様の誤りが判明した場合は、ブリーフを更新します
- 新しいキャッシュバスター
?v=<new-timestamp>を付けて再配信します - 同じ JS インジェクションを使い、該当する状態で再度フリーズします
- スクリーンショットを撮り直し、もう一度ユーザーに確認します
すべての状態についてユーザーが「Looks good」と言うまで、ステップ 3~4 を繰り返します。
ステップ 5:全体の再生とタイミング調整
すべてのフリーズした状態が個別に承認されたら:
- ページを再読み込みし(キャッシュバスターを付けて)、アニメーションループを再開します
- アニメーション全体をユーザーに見てもらいます。フリーズはしないでください
- 質問します:
"How does the full animation look in motion?" Options: - Approved — looks great! - Timing needs adjustment - Transitions need work (easing feels wrong, stagger off) - Something else needs fixing - 承認済みの場合 → 完了です。ファイルの保存場所(ブリーフと HTML)をユーザーに伝えます。
- タイミングの調整が必要な場合 → (以下の)タイミング調整ループに進みます。
- それ以外のフィードバックがある場合 → 反映して再配信し、もう一度質問します。
タイミング調整ループ
タイミング調整は常に反復して行います。 タイミング調整を 2~4 回繰り返すのは普通のことであり、最初の試みが悪かったという意味ではありません。具体的な質問をして、すばやく目標に近づけることが目的です。
タイミングの調整が必要だとユーザーが言ったら、どのフェーズかを具体的に質問します:
"What about the timing needs adjustment?"
Options (multiSelect: true):
- Initial state too long (before the action starts)
- Initial state too short (need more time to see the 'before')
- Action/stagger too slow (elements appear too slowly)
- Action/stagger too fast (can't follow what's happening)
- Final hold too long (loop feels sluggish)
- Final hold too short (not enough time to absorb the result)
変更を適用し、キャッシュバスターを付けて再読み込みしてから、もう一度質問します:
"How does the updated timing feel?"
Options:
- Approved — looks great!
- Still needs adjustment
「まだ調整が必要」の場合 → 該当するフェーズについて、もう一度具体的に質問します。承認されるまで繰り返します。
タイミング調整のヒント:
- 意味のある幅で調整します(50ms 単位で細かく調整せず、半分または倍にします)
- 詳細を指定せずに「速く」と言われた場合は、まず変更前の状態と最後の状態の表示時間を短くします。通常、アクション間のずらしは適切です
- ループ全体が 6 秒未満なら軽快に感じられ、12 秒を超えると遅く感じられます
- 変更前の状態は 0.5 秒を超える時間が必要になることはほとんどありません。閲覧者は「空」の状態をすぐに理解します
レビューループの原則
まず静止状態を確認し、それから動きを評価します。
位置やレイアウトの不具合は、フリーズしたフレームのほうがはるかに見つけやすくなります。タイミングやイージングの不具合は、再生中にのみ現れます。まず視覚的な不具合を修正し、それから動きを調整してください。
エラー処理
- アプリへのログインが必要な場合: 停止し、Chrome タブで手動ログインするようユーザーに依頼します。ログインを確認してから調査を再開します。
- Chrome ツールが利用できない場合: フェーズ 1(調査)には Claude-in-Chrome が必要であることをユーザーに伝えます。アプリについて口頭で説明できる場合は、インタビューに進むことを提案します。
- HTTP サーバーのポートが使用中の場合: 8766、8767 などのポートを試します。
lsof -i :<port>で確認します。 - ブラウザーのキャッシュに古いバージョンが表示される場合: 常に
?v=<timestamp>を付けてキャッシュを無効化します。それでも古いバージョンが表示される場合は、新しい Chrome タブを試します。 - ユーザーが報告した問題を再現できない場合: 詳細を説明するようユーザーに依頼します。
read_pageまたはjavascript_toolを使って、実際の DOM と計算済みスタイルを調べます。 - 円形の配置が正しく見えない場合: 数式を再確認します。よくある間違い:
- 度をラジアンに変換し忘れる
- 中心点を間違える(中心 = 原点 + 寸法の半分です)
- 半径を間違える(コンテナーの見える半径 + 要素サイズの半分です)
- 計算した位置から要素サイズの半分を引き忘れる
高品質なアニメーションのヒント
- アプリの個性に合わせます。 ダークテーマのアプリには暗いアニメーションを使います。遊び心のあるアプリには弾むようなイージングを使います。ビジネス向けのアプリには控えめなトランジションを使います。
- シンプルにするのが効果的です。 動かす要素は14~20個で十分です。実際のアプリのピクセルをすべて再現しようとしないでください。
- スプリングイージングで生き生きとした印象になります。
cubic-bezier(0.34, 1.56, 0.64, 1)を使うと、要素に物理的な動きが加わり、生き生きと感じられます。 - すべての動きに時間差をつけます。 要素ごとに
transition-delayを順番に(0.04~0.08sずつ)設定すると、同時に動かすよりはるかに見栄えがよくなります。 - 見せ場の後は少し止めます。ただし、長すぎないようにします。 変化が終わったら、最終状態を2~3秒間表示します。それ以上長くなると、ループがもたついて感じられます。視聴者が結果を把握するのは、思っているより早いものです。
- ラベルやバッジは最後に表示します。 これらは結果を伝えるものなので、まず視覚的な変化を見せましょう。
- デザイン言語が最も重要です。 色、フォント、角丸を適切に設定すれば、大まかなレイアウトでも「そのアプリらしく」感じられます。レイアウトが完璧でも色が合っていないと、違和感が生まれます。