スライドショー作成契約
HyperFramesスライドショーは、通常のHyperFrames構成(シーン、クリップ、GSAPタイムライン)に、スライドとしてのシーンとその接続を宣言するJSONアイランドを追加したものです。プレーヤーのSlideshowControllerがJSONアイランドを読み取り、連続的なGSAPタイムラインを個別のナビゲーション可能なデッキに変換します。
最初に/hyperframes-coreを読んで、基本構成契約(クリップ、トラック、data-*属性、決定性ルール)を確認してください。このスキルは、新しい部分(JSONアイランドスキーマ、スライド作成ルール、フラグメント、ブランチング、検証、ラッピングコンポーネント)のみを扱います。
出力 — 線形MP4ではなく、ナビゲーション可能なデッキ
スライドショーの出力は実行中のデッキです。hyperframes present <project-dir>(またはStudioのプレゼントモード)で提供します。プレーヤーのSlideshowControllerがJSONアイランドを読み取り、ナビゲーション、フラグメント、ブランチング、発表者モードを駆動します。**「プレゼンテーションと引き継ぎ」**セクションを参照してください。
スライドショーをhyperframes renderで単一のMP4にレンダリングしないでください。 デッキは複数のトップレベルシーン構成(スライドごとに1つのdata-composition-id)で作成され、それらをラップするマスタールート構成がないため、renderは最初の構成のみを解決し、黙って切り詰められたMP4(例:40秒のデッキのうち6秒)を出力します。線形のメインラインエクスポート(ブランチシーケンスを除いたメインスライドのみ)は延期されています。それがリリースされるまで、サポートされる出力はライブのpresentデッキとスライドごとのsnapshot静止画です。ユーザーが今日線形MP4を必要とする場合は、この制限を伝え、renderをデッキに向けないでください。
意図確認
ユーザーが明示的にスライドショー、スライド表示、またはHyperFramesスライドショーを要求した場合は、このスキルに従って進めてください。
このスキルが「プレゼンテーション」、「ピッチデッキ」、「デッキ」、「インタラクティブデッキ」、または「このページを変換」などの隣接するリクエストからトリガーされた場合は、作成前に一時停止し、選択肢を提示してから確認を求めてください。HyperFramesスライドショーが、個別のスライド、組み込みナビゲーションと発表者モード、編集可能な発表者ノート、共有メディア処理、引き継ぎ前の検証を備えた実行可能なデッキであることを簡単に説明してください。ソースページの変換の場合は、目標が元のページのビジュアルデザイン、インタラクション、モーション、メディア動作を維持しながら、ページの移動をスライド間のトランジションに変換することであることも述べてください。
その後、短い確認質問をしてください:
これをHyperFramesスライドショーとして作成しますか?
環境で提供されている場合は、はい/いいえの選択UIを使用してください。それ以外の場合は、プレーンテキストで質問してください。
ユーザーが「はい」と答えるまで、スライドショーを実装しないでください。ユーザーが「いいえ」と答えた場合は、このスキルの使用を停止し、適切な非スライドショーワークフローに切り替えてください。
2つの構成要素
1. シーン — 通常の方法で宣言
すべてのスライドはシーンによってサポートされています。data-composition-id、data-start、data-duration、data-labelを使用してシーンを宣言します:
<div
data-composition-id="problem"
data-start="0"
data-duration="8"
data-label="問題"
data-width="1920"
data-height="1080"
>
<!-- クリップをここに配置 -->
</div>
ブランチスライド(ホットスポットからのみ到達可能で、メインラインから除外される)もまったく同じ方法で宣言されます。JSONアイランドのslideSequencesエントリにのみ表示され、メインのslides配列には表示されません。
2. JSONアイランド — 構成ごとに1つのスクリプトブロック
構成HTMLに、<script type="application/hyperframes-slideshow+json">ブロックを1つだけ追加します。これにより、すべてのスライドショーメタデータが保持されます:
<script type="application/hyperframes-slideshow+json">
{
"slides": [...],
"slideSequences": [...]
}
</script>
JSONアイランドは、スライドの順序、ノート、フラグメントの保持ポイント、ホットスポット、ブランチシーケンスの単一の情報源です。<body>の先頭近く、シーンのdivの前に配置して、見つけやすくしてください。
スライドショーマニフェストを、別の<script type="application/json">ブロックとJSONアイランドを作成するランタイムコードの背後に隠さないでください。presentコマンドは構成HTMLを静的に読み取り、実際のapplication/hyperframes-slideshow+json JSONアイランドがすでに存在することを期待します。
スキーマ
SlideshowManifest(トップレベルのJSONアイランドオブジェクト)
{
"slides": [
/* SlideRef[] — メインライン、順序通り */
],
"slideSequences": [
/* SlideSequence[] — オフラインブランチシーケンス */
]
}
SlideRef
{
"sceneId": "problem",
"notes": "痛みから始め、会社から始めない。",
"fragments": [3.5, 5.2, 7.0],
"hotspots": [
/* SlideHotspot[] */
],
"ttsScript": null,
"ttsAudioUrl": null,
"ttsDurationMs": null
}
| フィールド | 必須 | メモ |
|---|---|---|
sceneId | はい | シーンのdata-composition-idと正確に一致する必要があります(または明示的なstartTime/endTimeを提供)。リントルールはdata-composition-idでシーンを解決します。 |
notes | いいえ | 発表者のみのテキスト。観客には決して表示されません。 |
fragments | いいえ | スライドの[start, end]範囲内の時間(秒)の配列 — 以下の「フラグメント」セクションを参照。 |
hotspots | いいえ | ブランチをトリガーするインタラクティブオーバーレイ — 以下の「ブランチング」セクションを参照。 |
startTime | いいえ | オプション。一致するシーンの時間範囲をオーバーライドします。デフォルトはシーンの開始/終了。 |
endTime | いいえ | オプション。一致するシーンの時間範囲をオーバーライドします。デフォルトはシーンの開始/終了。 |
ttsScript, ttsAudioUrl, ttsDurationMs | いいえ | 予約済み。 スキーマフィールドは存在しますが、TTS再生はまだ配線されていません。将来のビルドのために事前入力しない限り、省略してください。 |
SlideHotspot
{
"id": "h1",
"label": "これはどのように計算しましたか?",
"target": "market-deep-dive",
"region": { "x": 60, "y": 10, "w": 35, "h": 20 }
}
| フィールド | 必須 | メモ |
|---|---|---|
id | はい | スライド内で一意。 |
label | はい | 観客に表示されるツールチップ/ボタンテキスト。 |
target | はい | slideSequences内のSlideSequence.idと一致する必要があります。 |
region | いいえ | スライドのパーセンテージベースの境界ボックス:{x, y, w, h}(0–100)。省略すると、ホットスポットは代わりにフルスライドのラベル付きボタンとしてレンダリングされます。 |
SlideSequence
{
"id": "market-deep-dive",
"label": "市場規模算出手法",
"slides": [{ "sceneId": "mkt-1" }, { "sceneId": "mkt-2" }]
}
シーケンス内のslidesは、メインラインと同じSlideRef形状を使用します。フラグメントとネストされたホットスポットが許可されます。
スライド作成ルール
これらは提案ではなく厳格な制約です。これらに違反するスライドは、レビュー担当者が見たときにそのまま置き換えられます。
- 見出しはラベルではなく、完全な文による主張である。 「スケジューリングの問題」ではなく、「SMBは手動スケジューリングに週14時間を費やしている」と書きます。ビジュアルが無視されても、その文は単独で成り立つ必要があります。
- 1スライドに1つのアイデアと1つのビジュアル。 2つ目の箇条書きのクラスターや2つ目のチャートを追加したくなったら、スライドを分割してください。
- 結論を先に述べる。 最も強いポイントを最初に — スライド上とデッキの順序の両方で。投資家は左から右、上から下に読み、そして止まります。
- ボトムアップの市場規模算定のみ。 計算を示さずに「$500億TAM」と書かないでください。ユニットエコノミクスから構築します:アカウント×ACV、またはトランザクション×テイクレート。
- フォントは最低30pt相当。 1920×1080で、見出しは72~96px、本文は48pxです。観客が読む必要のあるテキストで40pxを下回らないでください。
ソースページの移植
既存のページをスライドショーに変換する場合、ソースの忠実性は契約の一部です。ユーザーが明示的に再設計を要求しない限り、ソース固有のウィジェットを簡略化された近似値に置き換えないでください。
- 元のページのビジュアルデザイン、モーション言語、インタラクティブな動作、メディア動作、プレゼンテーション機能を可能な限り忠実に保持してください。スライドショーシステムが発表者モードをサポートしている場合は、デッキ固有の実装ではなく、共有の編集可能なノート動作を使用して発表者ノートを含めてください。
- ソースのDOM/CSS/JSから機械的なビジュアルを可能な限り正確に移植します。カスタムプレーヤー、キャンバスビジュアライザー、タイムライン、プレイヘッド、ステム、拡大する円、ホバー状態、その他のインタラクティブな詳細は変換後も維持されるべきです。
- ネイティブの
<video>/<audio>要素を、カスタムメディアクローム、キャンバスビジュアライザー、波形、ビートグリッド、プレイヘッドの情報源として扱ってください。ソースのメディアイベント(play、pause、timeupdate、seeking、seeked、ended、ratechange、volumechange)を配線し、media.currentTimeからビジュアル状態を派生させてください。実際の再生からずれる可能性のある別個のタイマーを実行しないでください。 srcを持つコピーされたすべての<video>または<audio>は、リントする前にHyperFramesタイミング属性(data-startとdata-duration、さらにネイティブオーディオを保持する場合はdata-has-audio="true")を持つ必要があります。スライド固有のメディアにはシーンの時間範囲を使用し、複数のフォーカスされたスライドから再生される可能性のあるユーザー制御の証拠ビデオにはデッキ全体の範囲を使用してください。メディアにpreload="none"を残さないでください。metadataまたはautoを使用してください。- 検証前にソースフォントトークンを解決してください。カスタムソースフォントを保持する場合は、ローカル/キャプチャされたフォントファイルの
@font-faceルールを追加してください。システムフォールバックを使用する場合は、font-family: var(--f-body)などのトークン化された宣言を、system-ui, sans-serifやui-monospace, monospaceなどの具体的なレンダリングセーフなスタックに置き換えてください。フォントファミリーの値としてvar(...)を残さないでください。 - ソースの異常なページ移動、特にスクロール、ホイール、タッチ、ハッシュ状態、リサイズ、またはrequestAnimationFrameループによって駆動される動作を監査してください。固定ビューポートと変換/スケーリングされた「ワールド」レイヤー、パララックス、固定パネル、水平スクローラー、スクロールスクラブされたタイムライン、セクションスナップ、拡大要素カメラをソースの動作として扱ってください。スクロールは多くの場合、ソースの遷移トリガーであるため、その進行停止、イージング、カメラ/フォーカス状態を抽出し、そのモーションをタイムライン位置、フラグメント、または再利用可能なプレーヤー/ハーネスフックを通じてスライドショーナビゲーションに再ホストすることで、遷移を保持してください。スライドの保持ポイントにジャンプするスタンドアロンラッパーでも、明示的なナビゲーション-カメラ遷移フックが必要です。スライドごとのカメラ変換を計算するだけでは不十分です。スライド内でリテラルなページスクロールダウン遷移をシミュレートしないでください。ビューアーは、ウェブページがスクロールされているのを見るのではなく、ある焦点から別の焦点へのカメラの移動/ズームを感じるべきです。各スライド間のカメラ移動を連続的に保ってください。ソースが同じ境界で明らかにそうしない限り、x/y方向を逆転させたりズームを変更する中間ルート停止を避けてください。着地前にあちこち動く遷移は、よりシンプルな直接焦点移動よりも悪いです。
- ソースのメディアクロップセマンティクスを保持してください。スクリーンショット、ツイート/ソーシャル投稿、製品UIキャプチャ、チャート、ドキュメント、コード、リーダーボード、および読み取り可能なテキストを含む画像は、装飾メディアではなくコンテンツ証拠として扱ってください。安定したフレーム内でソースのアスペクト比(
height: auto)またはobject-fit: containを使用してください。object-fit: coverは、ソースがそうした場合、または意図的に装飾/背景/シネマティックなサムネイルにのみ使用してください。これらのキャプチャをスライドに収めた後、4つのエッジすべてで切り詰められたテキスト、ロゴ、コントロール、キャプションがないか検査してください。意味のあるコンテンツに表示されるクロップは、ソース自体がクロップした場合を除き、バグです。 - 動作がスライドショーに一般的なものである場合は、プレーヤー/コントローラーまたは再利用可能なスキルスニペットに配置してください。1回限りのデッキスクリプトで解決しないでください。
- スタックされたシーンフレームは、アクティブなスライドでのインタラクションを決してブロックしてはなりません。非表示のフレームは、視覚的な非表示とイベントゲーティングの両方が必要です:
.scene-frame {
opacity: 0;
visibility: hidden;
pointer-events: none;
}
.scene-frame.is-active {
opacity: 1;
visibility: visible;
pointer-events: auto;
}
可視性が命令的に駆動される場合は、可視性コントローラーで3つのプロパティ(opacity、visibility、pointerEvents)すべてを設定してください。opacity: 0だけでは、クリックを飲み込むことができる目に見えないレイヤーが残ります。
フラグメント:スライド内の表示保持ポイント
フラグメントは、スライドの[start, end]範囲内の絶対構成タイムライン時間(秒)であり、コントローラーが表示状態を保持するポイントです。
仕組み:
- プレーヤーがフラグメント化されたスライドに入る — 直接
fragments[0]にシークしてそこに保持。 - ユーザーが次へ(または→)を押す — コントローラーが
fragments[1]にシークして保持。 - 最後のフラグメントの後、次へは次のスライドに進む。
- フラグメントのないスライドは、スライド内の休息フレームに入る。通常は中間点で、
slide.endの正確な位置ではない。
フラグメント時間は[start, end]内にある必要があります。
…
[翻訳用に切り詰められました]