Default Explainer (デフォルト説明ツール)
落ち着いたプレミアムな製品デモです。資金調達に成功したスタートアップが自社のホームページに掲載するようなものです。その秘訣は「抑制」です。明るく風通しの良いキャンバスに、一度に1行の短いテキスト、そして製品自身のインターフェースをきれいに再構築し、アップクローズで使用中の様子を撮影します。カメラがストーリーを語ります。テキストに押し込み、タイピングに沿って移動し、結果を引きで見せ、次の機能へとグライドします。
タイム値から任意のフレームをレンダリングする1つのHTMLページとして作成し、モーションブラーとサウンドトラック付きでMP4にレンダリングします。
ステップ 1: ブリーフィングを取得 (1回のメッセージで、その後は独立)
1回のメッセージですべてを質問し、その後は自分で作業を進めてください。製品は必須です。空白のままのものは、自分で決定し、何を選んだかを伝えてください。
- 製品: 名前と、どのようなものかを数文で。WebサイトのURLがあればさらに良い。
- 視聴者が覚えておくべきこと (例: 「アイデアを入力すると、ライブアプリができる」)。
- ブランド: 色、フォント、ロゴファイル、または「Webサイトを参照」。指定がない場合は、後述のデフォルトパレットを使用。
- フォーマット: 16:9 (1920×1080) または 9:16 (1080×1920)。デフォルトは16:9。
- 長さ: このスタイルのデフォルト長さは以下に示されています。
- 音楽: ユーザー自身のトラック (ファイルパス)、またはシンセサイズを委任。デフォルト: シンセサイズ。
- 方向性 (オプション): 希望するシーン、タグライン、コールトゥアクション、避けたいことなど。
URL が提供された場合は、それを読み取って (Webフェッチ)、製品の実際の表現、機能、色、フォント名を取得してから、何かを作成してください。UIラベルやタグラインには、実際の表現を使用してください。
事実を捏造しないでください。 顧客数、収益、評価、推薦文、引用など、でっち上げは禁止。数値は、ユーザーまたはWebサイトが明示している場合のみ使用。それ以外の場合は、相対的なバー、進行状況、プレースホルダーのスケルトン線を使用してください。UI内のサンプルコンテンツ (プロンプト、ファイル名、プロジェクト名、レシートの価格) は許容され、もっともらしくあるべきです。製品自体に関する主張 (統計、ユーザー数、評価、「無料」などのオファー) は許容されません。コールトゥアクションは、ユーザーまたはWebサイトが提供したURLのみを使用するか、提供がない場合は名前とタグラインで終了してください。
ロゴ: ユーザーがファイルを提供した場合、またはそれがユーザー自身の製品でありユーザーが要求した場合にのみロゴを使用してください。それ以外の場合は、ブランドフォントで名前をテキストとして記述してください。サードパーティのロゴ (インテグレーション) は提供された場合のみ。提供がない場合は、名前が入ったニュートラルな角丸タイル。
また、(オプションで) 表示する3〜5の機能またはワークフローステップと、製品が接続するもの (インテグレーション) を尋ねてください。URLが提供された場合は、サイトからこれらを取得してください。
このスタイルのデフォルトの長さ: 60秒。範囲は45〜90秒。長さに応じて予算配分 (オプションセクションを最初に削除):
| 長さ | 機能 | オプションセクション |
|---|---|---|
| 45秒 | 2–3、各約9秒 | プルーフまたはインテグレーションのいずれか (両方は不可) |
| 60秒 | 3–4、各約10秒 | プルーフ/インテグレーションのいずれか |
| 90秒 | 4–5、各約12秒 | 両方 |
ステップ 2: スクリプトを書き、次に構築する
構成
先にスクリプトとビートシートを書いてください。画面上のテキストの各行、それに続くUIの瞬間、その時間をすべて記述します。時間を上記の予算と照らし合わせて合計してください。画面上のテキストが唯一の「声」なので、それだけでストーリーを語る必要があります。
シーンとカメラの連携方法: 各シーン (タイトル行、UIモーメント) はそれぞれ独自のカメラを持つ独立したレイヤーです。シーン内ではカメラが押し込み、移動し、引き戻します。シーン間では、前のレイヤーは0.3〜0.4秒の短いブラーを伴って次のレイヤーにディゾルブし、次のレイヤーはすでに動いています。
- オープン (0〜5秒)。プレーンなライトキャンバス。中央に小さな単語「Introducing」がフェードアップします。それがブランドモーメントにディゾルブします。ソフトなブランドグラデーションがスイープイン (シルクのような斜めのライトバンドがゆっくりと漂う) し、ロゴまたは名前が中央に小さく表示されます。
- 問題または問いかけ (約5秒)。視聴者が認識できる短い行 (「まだ手動で見込み客リストを作っていますか?」)、または製品の入力に直接進みます。大きな角丸の入力ボックスが空で表示され、プレースホルダーテキスト、その下にサジェストチップが配置されます。
- 機能チャプター (3〜5、各約8〜15秒)。それぞれ次の構成:
- タイトル行: 短い1文 (1080pで約28px)、プレーンなキャンバスに中央揃え。単語ごとにタイプまたはフェードインします。次に、カメラがその行に押し込み、行がフレーム幅の約75%になるまで近づきます。そして、1つのキーワードまたは短いフレーズがハイライトされます。ソフトなブランドカラーのボックスが左から右にスイープしてその後ろに表示されます (「決裁者に直接電話しよう。」)。
- UIモーメント: 製品の実際のインターフェースを、クリーンなベクターUI (スクリーンショットではない) として再構築し、重要な部分のみにトリミングして大きく表示します。カメラは要素がフレームのほとんどを占めるように十分に接近し、アクションに沿って移動します。テキストが入力ボックスに入力される (カメラはキャレットを追跡。
measureTextでテキストの位置を測定)、エージェントのステップが1つずつチェックされていく (スピナー→チェック、「247件の一致を発見」)、結果カードが積み重なり遠くのものはブラー (被写界深度)、テーブルが行ごとに埋まっていく、カーソルがセルボタンをクリックして値が表示される、新しい列が追加され各セルが「思考」してから値が表示される、ポップオーバーが推論とソースとともに開く、など。 - 引き: アクションの後、カメラがゆっくりと引き、画面全体を一瞬表示して視聴者に現在地を理解させ、その後グライドして次へ進みます。
- プルーフ (オプション、実際の数字のみ)。数字がカウントアップする文、数字がハイライトされます (「3億以上のプロファイルを搭載」)、控えめな点線の地球またはグリッドの上に表示。
- インテグレーション (オプション)。「既存のワークフローと連携。」が中央に表示され、8〜12のアプリアイコン (角丸の正方形、実際のロゴは提供された場合のみ。インテグレーションが少ない場合は繰り返し) が端から異なる深度でフロートインします。近くのものは大きくて少しブラー、遠くのものは小さくてシャープ、すべてパララックスで漂います。ここでは、カメラの押し込みではなく、テキスト自体が拡大するため、アイコンはフレーム内に留まります。
- クロージャー。ブランドグラデーション上に、1文。ハイライトされた単語がユースケースをローテーションします (「[プロスペクティング / リサーチ / アウトリーチ] のすべてをProductで。」)。その後、製品に実際にある場合に限り、別の使用方法を表示します (例: Claudeコネクタがある製品の場合は「またはClaudeに尋ねる」)。その後、キーフレーズがハイライトされたタグライン。
- エンドカード (3秒)。ブランドグラデーション上にロゴまたは名前、その下にURLまたはコールトゥアクションを小さく表示。
プレミアム感を出すためのルール
- 一度に一つだけ。 画面上に1行のテキストと1つのUI要素を同時に表示しないでください。テキストとUIが同じフレームを共有することはほとんどありません。テキストシーン、次にUIシーン、という順序です。
- カメラが編集者です。 カットはハードカットにしないでください。すべてのシーンチェンジはカメラの移動 (押し込み、引き、グライド) またはプレーンキャンバス上のソフトなブラーディゾルブです。カメラの動きはスムーズなイージング (
ease、0.6〜1.2秒) または強く減衰されたスプリング (z≥ 0.95) で行います。跳ねるような動きは禁止です。 - リアルなUI、クリーンに。 知っている情報 (またはそのWebサイト) から製品のインターフェースを再構築します。実際のレイアウト、ラベル、色、フォント、角の半径を、シーンに必要な部分だけに簡略化して使用します。その中身は製品に合ったもっともらしいサンプルデータです。ソフトなシャドウ、1pxの境界線、たっぷりとした余白。
- カーソル: 通常のmacOSスタイルの矢印。穏やかな曲線で移動し、クリックする少し前に到着し、小さなプレスディップとクリックされたコントロールにソフトな波紋を伴います。ホバー状態は変化します。
- タイポグラフィ: ブランドのフォントが既知の場合はそれを使用。それ以外はInterまたはGeist。タイトル行には小さめの標準ウェイト (フォントサイズではなくカメラで大きく表示されるように)。大きなテキストでは文字間隔を密に。
- デフォルトパレット: キャンバス
#F7F7F8、テキスト#111114、セカンダリ#8A8A94、UI面は白で境界線#E7E7EC、ブランドアクセント#2E6BFF、ハイライトボックス = アクセントの15〜20%透明度。ブランドグラデーション: 白 → 淡いアクセント → アクセント、ゆっくりとした斜めのシルクバンド (CSSブラーではなくキャンバスに描画)。ブランドカラーがあればアクセントを置き換えます。 - ペーシング: 各タイトル行は表示後約2秒間保持。UIモーメントは実際の速度で実行 (1秒あたり約25文字のタイピング)。各結果の後に0.5秒のポーズを入れ、視聴者が読めるようにします。
- 禁止事項: UI背後でのごちゃごちゃした背景、複数のアクセントカラー、跳ねるようなイージング、絵文字、大きなドロップシャドウ、あらゆる場所でのグラスモーフィズム、捏造された指標や推薦文。
サウンド
アップリフティングで優しいBGM (100〜110BPM) (ソフトなピアノまたはプラックコード、オープン後に軽いパーカッションが入り、クロージャーに向けて盛り上がる)、静かで温かみのある。効果音は控えめに: タイピング時の小さなキー音、ソフトなクリック音、ステップ完了ごとの軽い「チク」音、大きなカメラ移動時のソフトな「ウッ」音、エンドカードでの優しいチャイム。音楽は、よく作られた製品動画の背景のように、主役にならずに存在するべきです。
ページの構築方法
単一の自己完結型HTMLファイル (インラインCSSとJS。画像はユーザーが提供した場合のみ)。DOM + CSS transform、SVG、または全画面キャンバス、適切なものを使用してください。
ページコントラクト
window.VIDEO = {w, h, duration}とwindow.seek(t)、これは時間の純粋関数です。時刻t(秒) のすべての要素を設定します。CSSトランジションやアニメーション、setTimeout、前のフレームからの状態引き継ぎは禁止。任意のフレームが、任意の順序で独立して正しくレンダリングされる必要があります。seek内でのレイアウト測定 (offsetLeft、measureTextなど) は問題ありません。これは決定論的です。- ランダム性 (粒状ノイズ、パーティクル、オーディオノイズ) はシード付きジェネレーターから生成され、
Math.randomは決して使用しません。 - 履歴を必要とするもの (移動するオブジェクトに遅れて追従するカメラ、シミュレーション) は、ロード時に一度だけベイクします。0から
durationまで1/240秒刻みでステップ実行し、値を保存し、seekはそれらを補間して読み戻します。ループの場合、ループが開始する状態からシミュレーションを開始します (スタイルのシームルールを参照)。 - ループ:
seek(t)はt % durationを使用します。シームをまたぐエフェクト (着地時のスカッシュ、サウンドテール) は両端で描画またはミックスされます。 - URLに
?renderが含まれる場合: コントロールなし、プレビュースケーリングなし。ステージは正確にw × hで左上に配置されます。含まれない場合: ステージはCSSでウィンドウに合わせてスケーリングされ、プレビューコントロールが表示されます。 - フォント: 埋め込んでください。 woff2ファイルをダウンロード (Google Fontsまたはブランドのもの) し、base64
@font-faceとしてインライン化し、レンダリングが静かにフォールバックしないようにします。ウェイトの変化には、可変フォント (範囲[email protected]) を使用してください。 - レイヤー: シーンレイヤーには透明な背景を与え、1つのステージ背景をその後ろに置いてベースカラーを提供することで、後のレイヤーが誤って前のレイヤーを隠さないようにします。絶対配置のテキストには
white-space: nowrapを設定します。 - 速度: 大きなCSS
filter: blur()と大きなブラーグラデーションはスクリーンショットに非常に時間がかかります。グラデーションとグローはロード時にキャンバスに一度描画するか (または画像として)、それを移動させてください。
ヘルパー: これらを貼り付けて、すべてをその上に構築してください
// 減衰スプリングステップ応答 0 -> 1。w = 速度 (8 遅い、14 通常、22 スナッピー)、z = 減衰 (1 = オーバーシュートなし)
function spring(t, w = 14, z = 0.82) {
if (t <= 0) return 0;
if (z >= 1) return 1 - Math.exp(-w * t) * (1 + w * t);
const wd = w * Math.sqrt(1 - z * z);
return 1 - Math.exp(-z * w * t) * (Math.cos(wd * t) + (z * w / wd) * Math.sin(wd * t));
}
// ターゲットが複数回変化し、それぞれにスプリングで追従: track(start, [[time, value, w?, z?], ...]) -> f(t)
const track = (v0, keys) => t => { let v = v0, p = v0; for (const [tk, val, w, z] of keys) { v += (val - p) * spring(t - tk, w, z); p = val; } return v; };
// 精密なイージングキーフレーム (カメラ移動に最適): kf([[t0, v0], [t1, v1, easeFn?], ...]) -> f(t)
const kf = keys => t => { if (t <= keys[0][0]) return keys[0][1]; for (let i = 1; i < keys.length; i++) { const [a, va] = keys[i - 1], [b, vb, e = ease] = keys[i]; if (t <= b) return lerp(va, vb, e((t - a) / (b - a))); } return keys[keys.length - 1][1]; };
const clamp = (x, a = 0, b = 1) => Math.min(b, Math.max(a, x));
const ease = x => (x = clamp(x), x < .5 ? 4 * x * x * x : 1 - Math.pow(-2 * x + 2, 3) / 2); // easeInOutCubic
const lerp = (a, b, k) => a + (b - a) * k;
const seg = (t, a, b) => clamp((t - a) / (b - a)); // t through [a, b] の進行度 0..1
const rng = s => () => (s = (s + 0x6D2B79F5) | 0, s = Math.imul(s ^ (s >>> 15), 1 | s), s ^= s + Math.imul(s ^ (s >>> 7), 61 | s), ((s ^ (s >>> 14)) >>> 0) / 4294967296);
- タイピング: 表示文字列は
full.slice(0, n(t))で、キャレットがtから点滅。カウントアップ:lerp(a, b, ease(seg(t, …)))でフォーマット。 - カメラ は、
kfまたはtrackによって駆動されるtransform: translate() scale() rotate()を持つラッパー要素です。
サウンド
window.buildAudio(ctx)は、与えられたAudioContextまたはOfflineAudioContextに対して、ビジュアルと同じタイムライン番号を使用して、時間0からサウンドトラック全体 (音楽 + 効果音) をスケジュールします。オシレーター、フィルタリングされたノイズ (シードバッファから)、エンベロープを使用してシンセサイズします。ユーザーが音楽ファイルを提供した場合は、fetch+decodeAudioDataでロードし、ビートグリッドをそのテンポに設定し (測定する)、その上に効果音のみを追加します。- プレビュー再生: 最初の再生時に、サウンドトラックを一度バッファにレンダリングし、その後は任意のスクラブ位置から再生します。クロックが
seekを駆動します:
let buf, ac, src, startAt = 0, offset = 0, playing = false;
async function play() {
ac ??= new AudioContext();
if (!buf) { const off = new OfflineAudioContext(2, Math.ceil(48000 * VIDEO.duration), 48000); await buildAudio(off); buf = await off.startRendering(); }
src = ac.createBufferSource(); src.buffer = buf; src.connect(ac.destination);
src.start(0, offset % VIDEO.duration); startAt = ac.currentTime; playing = true;
}
function pause() { if (!playing) return; offset += ac.currentTime - startAt; src.stop(); playing = false; }
function now() { return playing ? (offset + ac.currentTime - startAt) % VIDEO.duration : offset; }
(function loop() { seek(now()); requestAnimationFrame(loop); })(); // スクラバーはオフセットを設定 (一時停止、設定、再生)
- ビートシートをスクリプトの先頭にコメントとして配置してください。各行には、その時間、何が起こるか、どのようなサウンドが再生されるかを含めます。
ステップ 3: 確認、レンダリング、納品
作業フォルダに一度だけセットアップ
…
[翻訳のため省略]