デフォルトの説明用動画
落ち着いたプレミアムなプロダクトデモ。資金調達の行き届いたスタートアップがホームページに掲載するような種類のものです。その秘訣は抑制です。明るく風通しの良いキャンバスに、一度に一行ずつ短いテキストを表示し、製品の実際のインターフェースをきれいに再構築して、使用中の様子をクローズアップで撮影します。カメラがストーリーテリングを行います。テキスト行に押し込み、タイピングに沿って移動し、引きで結果を表示し、次の機能へと滑らかに移行します。
これは、時間値から任意のフレームをレンダリングする単一のHTMLページとして記述し、モーションブラーとサウンドトラックを付けてMP4にレンダリングします。
ステップ1: 概要を把握する(1メッセージで、その後は実行)
すべてを1つのメッセージで質問し、その後は自分で作業を進めてください。必須なのは製品情報のみです。空白のままの項目については、自分で決定し、何を選んだかを伝えてください。
- 製品: 名前と、それが何をするかを数文で。ウェブサイトのURLがあればなお良いです。
- 視聴者が覚えるべき最重要ポイント(例:「アイデアを入力すると、ライブアプリができる」)。
- ブランド: 色、フォント、ロゴファイル、または「ウェブサイトを使用」。指定がない場合は、以下のデフォルトパレットを使用します。
- フォーマット: 16:9(1920×1080)または9:16(1080×1920)。デフォルトは16:9です。
- 長さ: このスタイルのデフォルト長さは以下に示されています。
- 音楽: ユーザー自身のトラック(ファイルパス)、または合成させることができます。デフォルトは合成です。
- ディレクション(任意): 欲しいシーン、タグライン、コールトゥアクション、避けたいことなど。
URLが与えられた場合は、何かを書く前に、製品の実際の文言、機能、色、フォント名を(web fetchで)読み取ってください。UIラベルやタグラインには、製品の実際の言葉を使用してください。
事実を捏造しないでください。 顧客数、収益、評価、推薦の言葉、引用などはすべて捏造禁止です。数字は、ユーザーまたはウェブサイトが明記している場合のみ使用します。それ以外の場合は、相対的なバー、進行状況、プレースホルダーのスケルトン行を使用します。UI内部のコンテンツ例(プロンプト、ファイル名、プロジェクト名、レシートの価格など)は問題なく、信頼できるものであるべきですが、製品自体に関する主張(統計、ユーザー数、評価、「無料」などのオファー)は禁止です。コールトゥアクションは、ユーザーまたはウェブサイトから提供されたURLのみを使用するか、何もない場合は、名前とタグラインで終了します。
ロゴ。 ユーザーがファイルを提供した場合、またはそれがユーザー自身の製品でありユーザーがロゴを要求した場合にのみロゴを使用します。それ以外の場合は、ブランドフォントで名前をテキストとして記述します。サードパーティのロゴ(統合機能)は提供された場合のみ使用します。それ以外の場合は、名前にニュートラルな角丸タイルを使用します。
また(任意で)以下を尋ねてください: 表示する3~5つの機能またはワークフローステップ、および製品が接続するもの(統合機能)。URLが与えられた場合は、これらをサイトから取得します。
このスタイルのデフォルト長さ: 60秒。範囲は45~90秒。長さに応じて予算を立てます(最初にオプションセクションを削除):
| 長さ | 機能 | オプションセクション |
|---|---|---|
| 45秒 | 2~3、各約9秒 | 証拠または統合機能のいずれか、両方は不可 |
| 60秒 | 3~4、各約10秒 | 証拠/統合機能のいずれか1つ |
| 90秒 | 4~5、各約12秒 | 両方 |
ステップ2: スクリプトを書き、構築する
構造
最初にスクリプトとビートシートを書きます。画面上のテキストの各行、それに続くUIモーメント、およびその時間を記述し、合計時間が上記の予算内に収まるようにします。画面上のテキストが唯一の「声」なので、それだけでストーリーを伝える必要があります。
シーンとカメラの連携方法: 各シーン(タイトル行、UIモーメント)は、独自のカメラを持つ独立したレイヤーです。シーン内ではカメラが押し込み、移動し、引き戻します。シーン間では、出力レイヤーが短いぼかし(0.3~0.4秒)を伴って次のレイヤーにディゾルブします。次のレイヤーはすでに動き出しています。
- オープニング(0~5秒)。無地の明るいキャンバス。中央に小さな
Introducingという単語がフェードインします。それはブランドモーメントにディゾルブします。柔らかなブランドグラデーションがスイープイン(シルクのような斜めの光の帯がゆっくりと漂う)し、ロゴまたは名前が中央に小さく配置されます。 - 問題または問いかけ(約5秒)。視聴者が認識できる短い行(
まだ手作業で見込み客リストを作っていますか?)、または製品の入力フィールドに直接進みます。大きな角丸の入力ボックスが、空でプレースホルダーテキストと、その下にサジェストチップと共に表示されます。 - 機能チャプター(3~5、各約8~15秒)。それぞれは:
- タイトル行: 短い一文(1080pで約28px)、無地のキャンバスに中央揃え。文字ごと、または単語ごとにタイプまたはフェードインします。次に、カメラがその行に押し込み、行がフレーム幅の約75%になるまで進み、1つのキーワードまたは短いフレーズがハイライトされます。柔らかなブランドカラーのボックスが左から右にスイープしてその背後に表示されます(
意思決定者に直接電話してください。)。 - UIモーメント: 製品の実際のインターフェースを、クリーンなベクターUI(スクリーンショットではない)として再構築し、重要な部分だけにトリミングして大きく表示します。カメラは十分に近づいて要素がフレームの大部分を占め、アクションに沿って移動します。入力へのテキストタイピング(カメラはキャレットを追跡します。
measureTextでテキストを測定して位置を把握します)、エージェントのステップが一つずつチェックされる様子(スピナー→チェック、247件の一致が見つかりました)、結果カードが積み重なり遠くのものはぼやける(被写界深度)、テーブルが行ごとに埋まる、カーソルがセルボタンをクリックして値が現れる、新しい列が追加され各セルが「思考」してから値が現れる、推論とソースを含むポップオーバーが開く、など。 - 引き: アクションの後、カメラが ease アウトして画面全体を一瞬表示し、視聴者がどこにいるかを理解させ、その後グライドして次へ進みます。
- タイトル行: 短い一文(1080pで約28px)、無地のキャンバスに中央揃え。文字ごと、または単語ごとにタイプまたはフェードインします。次に、カメラがその行に押し込み、行がフレーム幅の約75%になるまで進み、1つのキーワードまたは短いフレーズがハイライトされます。柔らかなブランドカラーのボックスが左から右にスイープしてその背後に表示されます(
- 証拠(任意、実際の数字のみ)。数字がカウントアップする文。数字がハイライトされます(
3億以上のプロファイルを誇るデータベースを搭載)。微妙な点線の地球またはグリッドの上に表示されます。 - 統合機能(任意)。中央に
お使いの既存のワークフロー向けに構築されました。と表示され、8~12個のアプリアイコン(角丸四角形、指定された場合のみ実ロゴ、数が少ない場合は統合機能を繰り返す)が、異なる奥行きで端からフロートインします。近くのものは大きくややぼやけ、遠くのものは小さくシャープで、すべてがパララックス効果で漂います。ここでは、カメラの押し込みではなくテキスト自体がスケールアップするため、アイコンはフレーム内に留まります。 - クロージング。ブランドグラデーション上に、回転するハイライト単語がユースケースを循環する一文(
Productで[見込み客開拓/調査/アウトリーチ]をすべて行いましょう)。次に、製品に実際にある場合のみ、別の使用方法(Claudeコネクタを持つ製品の場合はまたはClaudeに依頼するだけ)。最後に、キーフレーズがハイライトされたタグライン。 - エンドカード(3秒)。ブランドグラデーション上のロゴまたは名前。その下にURLまたはコールトゥアクションを小さく表示。
プレミアム感を生み出すルール
- 一度に一つのこと。 画面上に、テキスト一行とUI要素一つ以上を同時に表示しないこと。テキストとUIがフレームを共有することはほとんどありません。テキストシーン、次にUIシーン。
- カメラが編集者。 ハードカットなし。すべてのシーンチェンジはカメラの動き(押し込み、引き、グライド)または無地キャンバス上のソフトなブラーディゾルブです。カメラの動きはスムーズなイーズ(
easeで0.6~1.2秒)または強く減衰されたスプリング(z≥ 0.95)です。バウンドはありません。 - 本物のUI、クリーンに。 製品のインターフェースを、知っていること(またはそのウェブサイト)から再構築します。実際のレイアウト、ラベル、色、フォント、角丸を、シーンに必要なものに簡略化します。内部のコンテンツは、製品に合った信頼できるサンプルデータです。ソフトシャドウ、1pxの境界線、十分な余白。
- カーソル: 通常のmacOSスタイルの矢印で、優しい曲線で移動し、クリックの一拍前に到着し、小さな押し込みと、クリックされたコントロールにソフトなリップルを伴います。ホバー状態は変化します。
- タイポグラフィ: ブランドフォントが既知の場合はそれを使用。そうでなければInterまたはGeist。タイトル行には小さな標準ウェイト(フォントサイズではなくカメラで大きく表示されます)。大きなテキストにはタイトな文字間隔。
- デフォルトパレット: キャンバス
#F7F7F8、テキスト#111114、セカンダリ#8A8A94、UI表面は白、境界線#E7E7EC、ブランドアクセント#2E6BFF、ハイライトボックス = アクセントの15~20%の不透明度。ブランドグラデーション: 白 → 淡いアクセント → アクセント、ゆっくりとした斜めのシルクの帯(CSSブラーではなくキャンバスに描画)。ブランドカラーがアクセントを置き換えます。 - ペーシング: 各タイトル行は表示後約2秒保持。UIモーメントは実際の速度で実行(タイピングは約毎秒25文字)。各結果の後には0.5秒のポーズを入れ、視聴者が読めるようにします。
- 禁止事項: UIの背後に込み入った背景、複数のアクセントカラー、バウンドするイージング、絵文字、大きなドロップシャドウ、ガラスモーフィズム全般、捏造された指標や推薦の言葉。
サウンド
元気づける、優しいベース音を100~110BPMで(ソフトなピアノまたはアルペジオコード、オープニング後に軽いパーカッションが入り、クロージングで盛り上がる)、静かで暖かく。効果音は小規模に: タイピング時のキークリック、ソフトなクリック、完了したステップごとに軽い「チック」、大きなカメラムーブにソフトな「ウーッ」、エンドカードに優しいチャイム。音楽は、よくできたプロダクト動画のバックグラウンドのように、主役にならずにいるべきです。
ページの構築方法
1つの自己完結型HTMLファイル(インラインCSSとJS。画像はユーザーが提供した場合のみ使用)。DOM + CSS transform、SVG、または1つのフルスクリーンキャンバスを使用して描画します。
ページの契約
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)); // 0..1 progress of t through [a, b]
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); })(); // スクラバーはoffsetを設定(一時停止、設定、再生)
- ビートシートをスクリプトの先頭にコメントとして配置します。各モーメントの行に、その時間、何が起こるか、およびどのサウンドかを記述します。
ステップ3: チェック、レンダリング、納品
ワーキングフォルダに一度セットアップ
…
[翻訳のため省略]