mcpField
S
synthetic-ui-demo

synthetic-ui-demo

github.com/digitalsambaクリエイティブ・メディア2.4k62 回インストール今日更新
リポジトリ

synthetic-ui-demo について

Synthetic UI Demos は、製品デモ動画を再現可能な形で作るスキルです。製品のソースコードを読める場合に向いており、画面録画や製品の実行をせず、静的な React 画面と Remotion でカーソル、カメラ、クリックをフレーム単位で制御します。

主な機能

  1. 01製品ソースから静的画面を再構築
  2. 02Remotion でフレーム単位のデモを構成
  3. 03カーソル、クリック、カメラ移動を制御
  4. 04シーンごとに音声とタイムラインを整理
  5. 05静止画のコンタクトシートでクリック位置を確認

活用シーン

  1. 01リリースごとに更新する機能紹介の作成
  2. 02実際のアプリで使えないデータや画面の提示
  3. 03デモのクリックとカメラ移動を正確に調整
  4. 04複数アプリにまたがるリリース動画の制作

インストール

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

$npx skills add https://github.com/digitalsamba/claude-code-video-toolkit --skill synthetic-ui-demo

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

詳細

合成 UI デモ

画面録画は行いません。Claude Code が製品のリポジトリを読み取り、シーンに登場する画面だけを静的な React として再構築し、Remotion 上でスクリプト制御のカーソルとカメラを使って一連の動きを実行します。クリックはすべてフレーム番号で指定するため、シーンは毎回同じように再レンダリングされ、シード済みのアカウントや実行中の環境は必要ありません。製品が変更された場合は、コードを編集して更新します。

参考ビルド(このスキルと併せて参照してください。どちらも製品のリポジトリなしでビルドできます):

  • examples/ds-free-schedule-demo:ナレーターのタイル付きで、電話を予約する26秒のフローを1つ収録しています。最もシンプルな完全版です。 src/Demo.tsx は、カーソルのすべてのキーフレーム、クリック、カメラ移動を含む単一のタイムラインです。
  • examples/ds-release-649:3つのアプリにまたがる8つのシーンで構成された、80秒のリリースノート動画です。src/Release.tsx がシーンを順番に並べ、src/scenes/ に各リリース項目のファイルが1つずつあり、src/room/ と src/ac/ が画面キットです。

これと Playwright のどちらを使うか

合成(このスキル)Playwright 録画(/record-demo)
アプリのソースを読める実行中のアプリしか使えない
リリースごとに作り直すリリースノートや機能紹介ツアー実際の動作や実データを一度だけ収録する場合
手元にないデータが必要なフロー(通話全体、他のユーザー、管理者画面)実際の画面に簡単にアクセスでき、そのままでも見栄えがよい
カメラ移動、正確なクリックのタイミング、音声変更後の再レンダリング再構築にコストがかかる、長く複雑な操作

構成要素(lib/components)

import { Stage, typed, cursorAt, near } from '../../../../lib/components';

<Stage
  url="app.example.com/settings"             // address bar; host darker than path
  camera={CAMERA}                             // [{ f, z, x, y }] in canvas px, eased, clamped to the window
  path={PATH}                                 // [{ f, x, y }] cursor keyframes in canvas px
  clicks={CLICKS}                             // frames that squash the cursor and throw a ripple
  aiNote                                      // "People shown are AI-generated" (or pass your own text)
  canvasWidth={1440} canvasHeight={810}       // the defaults
>
  <SettingsScreen field={typed(frame, 'Q4 Product Review', 128)} />
</Stage>
  • Stage は固定サイズのアプリ用キャンバスの周囲にブラウザーの枠を描画し、カメラを適用して、カーソルを最前面(zIndex 100)に配置します。ズーム1では、ウィンドウはフレーム幅に対して fit(0.8625)です。キーフレームで値を繰り返すと、その値を維持できます。
  • Cursor と cursorAt は、ブラウザー以外のシーンでも単独で使用できます。near(cursor, target) はホバー状態を制御します。
  • 製品固有の画面キット(テーマ、アイコン、レイアウト)はプロジェクト内に置きます。ライブラリには含めません。

手順

1. サブエージェントを使って、アプリのリポジトリからビジュアル仕様を抽出する

アプリまたは領域ごとにサブエージェントを1つ割り当て、並行して作業させます。ファイル全体ではなく、簡潔な仕様を返すように指示してください。

  • テーマ: 配色、フォントスタック、角丸、間隔、影(テーマファイルまたは CSS 変数を参照)。
  • 文字列: シーンに表示されるすべてのラベル、メニュー項目、ダイアログ、トーストについて、英語ロケールの正確な文字列を取得します (public/locales/en/*.json、src/i18n/locales/en/*)。UI テキストを言い換えないでください。
  • アイコン: アプリがアイコンフォントを使用している場合は、icomoon または fontello の selection.json に各グリフの SVG パスが含まれています。必要なものを小さな JSON に抽出し、<svg><path d=...> として描画します。それ以外の場合は、SVG コンポーネントをコピーします。
  • レイアウトと動作: 表示する画面のコンポーネントツリー、ツールバーの順序、デフォルト値、各コントロールの動作。

リモートのデフォルトブランチを読み取ります(git show origin/main:path、または git fetch を実行してから origin/<default> を読み取ります)。 ローカルのチェックアウトは古くなっていることが多く、前四半期の UI が含まれている場合があります。

リリースノートの場合は、まず各項目を、それが最初に出荷されたコミットとコンポーネントまでたどります。そうすることで、表示する正確な文字列とデフォルト値がわかります。

2. シーンに表示する部分だけを、固定キャンバス上に再構築する
  • 固定キャンバス(1440x810 が適切なデフォルト)上に、すべての要素を絶対位置で配置します。重要な領域は矩形を定数としてエクスポートします(SAVE_BTN = { x, y, w, h })。これにより、クリック対象の位置を推測ではなく計算で求められます。
  • カメラに映るものだけを構築します。映らないパネルは単色にしてかまいません。
  • 静的な React を維持します。state も effects も使いません。視覚的な変化はすべて frame によって決まります。
  • キットは専用のフォルダー(src/ui/、src/room/)に置き、定数を記述した theme.ts を含めます。
3. まず音声を作成し、その後タイムラインをフレームで設定する
  • シーンごとに1行ずつ書き、最初にシーンごとの音声を生成します(voiceover.py --scene-dir ... --json。--max-wpm 165 を追加します)。計測された長さを確認します。
  • 各シーンの長さは、その行の音声に間を加えた長さにします。また、各行の開始位置と長さを記したヘッダーコメントを残します。このコメントが正式な基準です(CLAUDE.md の「音声に合わせたタイムライン」を参照)。
  • シーンファイルの先頭にあるフレーム定数ですべてを設定します。カーソルのキーフレーム、CLICKS、カメラのキーフレーム、UI の状態切り替え(frame >= C.save でダイアログを表示)などです。クリックのフレームをエクスポートして、親シーンからクリック効果音を配置できるようにします。
  • 各クリックは、その名前を表す語に合うタイミングにします。
4. 項目が多い行は、間で分割する

複数の項目を並べた行(「スケジュール、連絡先、録音、文字起こし」など)は、1つのショットには速すぎます。音声を間の位置でフレーズファイル(07a、07b、...)に分割し、各フレーズに個別のショットを割り当て、それぞれのフレーズを別の拍に配置します。ds-release-649 の moreVo フィールドはこの処理を行います。

5. 本番レンダリングの前に、コンタクトシートでクリック対象を計測する

推測した座標は、カメラをズームすると通常20~50pxずれます。各クリックフレームと、その少し前の数フレームの静止画をレンダリングして並べ、カーソルの先端が対象に合っていることを確認します。

i=1; for f in 46 78 122 212; do npx remotion still MyComp out/stills/s$i.png --frame=$f; i=$((i+1)); done
ffmpeg -start_number 1 -i out/stills/s%d.png -vf "scale=640:-1,tile=2x2" -frames:v 1 out/contact.png

定数を修正し、静止画を再レンダリングしてから、動画をレンダリングします。

6. AI 生成の人物には画面上でラベルを付ける

実在しない人物(タイル内の FLUX.2 のポートレート、アバター、ナレーター)には、必ず画面上にラベルを付けます。Stage の aiNote を使うか、ナレーターのタイルに「AI」バッジを付けます。名前、連絡先、通話データもすべて創作なので、明らかに架空だと分かるようにします。

7. レンダリング後に音量を正規化する

レンダリング前に tools/qc.py --project ... を実行し、その後 qc.py --render out/video.mp4 --fix を実行して -14 LUFS にします。

注意点

  • モノクロ SVG ロゴは黒くレンダリングされます。 通常、logo_mono.svg の塗りは黒です。暗い背景では filter: brightness(0) invert(1) を使います。
  • ローカルブランチが古い場合があります。 ローカルのチェックアウトがどのブランチにあるかにかかわらず、origin/<default> を読みます。
  • rsync --exclude src は node_modules/*/src も除外します。 プロジェクトやキットをコピーするときは、除外パターンを先頭のスラッシュで転送元ルートに固定します:--exclude /src。
  • カメラの移動範囲には制限があります。 キャンバスの端に近いカメラ中心は、ウィンドウの端がフレーム外に出ないよう内側に引き戻されます。ズーム位置が予想外になる場合は、これが原因です。さらに内側の点を狙います。
  • メニューとダイアログはキャンバス内に配置する必要があります。 キャンバスによって子要素がクリップされます。実際のアプリと同様に、内側に開くようメニューを配置します。
  • ホバー状態はカーソルの軌跡から決まります。 フレーム定数を別に設定するのではなく、near(cursorAt(frame, PATH), target) を使います。これにより、キーフレームを移動するとホバーも連動します。
  • 音声のセリフを変更すると、その後のすべての位置がずれます。 長さを再計測し、ヘッダーコメントとシーンの長さを更新してから、クリック時の静止画をもう一度確認します。リップシンクするナレーターが編集済みの音声トラックに基づいている場合は、ナレーターも再生成します。

コメント