パララックスランディングページ
短い動画を、ユーザーのスクロール操作でフレームを進めながら、5つのドラマチックなテキストシーンがクロスフェードする、1画面のシネマティックランディングページに変換します。ドキュメント自体は実際にはスクロールせず、ホイール/タッチ/キーボード入力をJSでインターセプトし、仮想的なフレーム進行に変換します。
このスキルは、../../examples/parasites/ にバンドルされたリファレンス(github / lion / hope ランディング — このスキルで構築された3つの実動ページ)で実証されたパターンをエンコードしています。不明な点があれば、そのフォルダを信頼できる情報源として扱ってください。
YUV.AIピラミッドにおけるこのスキルの位置づけ
parallax-landing-page は、yuv-design-system、yuv-decks、yuv-viral-video、video-to-landing-page と並んで、YUV.AIスキルピラミッドの中間層にあります。トップ層のオーケストレーター yuv-pilot は、5〜15秒の動画クリップを単一ヒーローのスクロールスクラブランディングにする必要がある場合に、ここにルーティングします。
このスキルは独自のビジュアル言語(Anton + Caveat + Inter、金/琥珀/アクセント/クリームのアクセントパレット)を持ち、yuv-design-system を呼び出しません。2つのシステムは共存します。yuv-design-system はウェブ/アプリ/デッキ全体のブランドパレットを担当し、parallax-landing-page は特にシネマティックなスクロールスクラブの美学を担当します。YUV.AIパララックスランディングでは、オプションでフッターエリアにフェニックスの透かしと標準のLinktree URLをブランドスレッドとして追加できます — 透かしファイルについては yuv-design-system/assets/ を参照してください。デザインシステムのNeonパレットにAnton/Caveatタイプスタックを置き換えないでください — そうすると特徴的な外観が失われます。
構築するもの
各ランディングは、ロックされた単一のビューポートで構成されます。
- 画面いっぱいに表示されるキャンバス(カバーフィット、DPR ≤ 2)で、一度に1フレームを描画
- 5つの絶対配置されたテキストシーン(キッカー + 大文字Anton見出し + Caveat手書き行)。それぞれに独自のスクロール進行度ウィンドウがあります
PARALLAX // showcaseロゴと兄弟ランディングへのリンクを持つ固定ナビゲーション- ユーザーが操作する前にすべてのフレームをプリロードするローダー
- ビネット + フィルムグレインのオーバーレイ
- ユーザーがスクロールを開始するとフェードアウトする、下部のスクロールヒント
- 右下のフレームカウンター(例:
073 / 145) - 最終シーンがそのままCTAセクション — 下部に別の
.endセクションはありません
q:v 2での総重量:約120〜220 KB/フレーム × フレーム数。6秒・24fpsのクリップ = 145フレーム ≈ 25 MB。10秒のクリップ = 241フレーム ≈ 53 MB。
保存場所
デフォルト: ~/Documents/yuv-projects/landings/<slug>/ — 後で見つけられるように、スタンドアロンランディングは常にここに保存します。ユーザーが明示的に別の場所を指定した場合、またはモードB(既存の examples/parasites/ ショーケースに統合)が選択された場合のみ上書きします。
mkdir -p ~/Documents/yuv-projects/landings
cd ~/Documents/yuv-projects/landings
# フレームを抽出しHTMLを構築する際、スキルはここに<slug>/を作成します。
最終パス(モードA — スタンドアロン):~/Documents/yuv-projects/landings/<slug>/
最終パス(モードB — 統合):ユーザーが選択した既存のショーケースディレクトリ
ビルドの最後に、ユーザーに最終パスを伝えてください。
ワークフロー
4つのフェーズがあります。フェーズをスキップしないでください — 各フェーズが次のフェーズにフィードします。
フェーズ1 — 発見
ユーザーに以下の確認を行います。
- 動画パス — ソースMP4の場所。
- スラッグ — 短いフォルダ/ファイル名(例:
hope、marcus、desk)。1単語、小文字、スペースなし。これがフレームフォルダ名(<slug>/)とHTMLファイル名(<slug>.html)の両方になります。 - テーマ/トピック — このランディングは何についてのものですか? 製品ローンチ? 個人的な瞬間? 野生動物との遭遇? コピーを書くためにこれが必要です。
- プロジェクトモード — スタンドアロン(新しいフォルダ)または、このリポジトリのトップにある既存の
examples/parasites/ショーケースに統合。ユーザーが「ショーケースに追加して」と言った場合、それは以下のモードBを意味します。 - アクセントカラー — スクリプト/CTAハイライト用:
gold(#f5b042)、amber(#ff8a3d)、accent(ピンク #ff4d6d)、cream(#f5e9d4)、または新しい色(style.cssの:rootに追加し、新しい.script.<name>ルールを記述)。
ユーザーがこれらの一部を指定していない場合は、デフォルトを提案して次に進んでください — 結果を見れば答えられる質問で立ち止まらないでください。
フェーズ2 — フレーム抽出
バンドルされた抽出スクリプトを実行します。ffprobeで動画をプローブし、ネイティブ解像度で -q:v 2(ほぼロスレスJPEG)ですべてのフレームを抽出し、frame-001.jpg から frame-NNN.jpg(3桁ゼロ埋め)の名前で保存します。
python <skill>/scripts/extract_frames.py <video_path> <output_folder>
例:
python C:/Users/User/.claude/skills/parallax-landing-page/scripts/extract_frames.py \
C:/Users/User/Documents/parasites/hope/hope.mp4 \
C:/Users/User/Documents/parasites/hope
スクリプトはJSONメタデータブロックを標準出力に出力します。それをキャプチャしてください — HTMLに frame_count と suggested_scroll_budget が必要です。
なぜ -q:v 2 なのか:ezgifや類似のツールは積極的に再圧縮します(約55 KB/フレーム)。ネイティブのffmpeg q:v 2では、同じ寸法で約120〜220 KB/フレーム — 明らかにシャープです。ダウンスケールしないでください。アップスケールも絶対にしないでください(詳細を追加せずにファイルサイズが増加します)。
なぜスクロールバジェットの計算式(フレームあたり約26ピクセル)なのか:クリップの長さに関係なく、「進行したフレームあたりのスクロールピクセル数」という触感を一定に保ちます。145フレーム → 約4200、241フレーム → 約6300、90フレーム → 約2500(フロア)。スクリプトが自動で計算し、[2500, 8000] の範囲にクランプします。
フェーズ3 — ページの作成
<skill>/assets/landing-page-template.html にあるテンプレートを読み取ります。これは {{PLACEHOLDER}} マーカーと、クリエイティブ部分の隣に <!-- TODO: --> コメントがある完全な動作ファイルです。<target>/<slug>.html に新しいファイルを書き込み、すべてを置き換えます。
置き換えチェックリスト(すべてのプレースホルダーを置き換える必要があります):
| プレースホルダー | 何を入れるか | 例 |
|---|---|---|
{{PAGE_TITLE}} | HTML <title> | Hope — The Fastest Heart in the Negev |
{{PAGE_DESCRIPTION}} | メタディスクリプション、1文 | A moment with Hope, the cheetah of Midbarium. |
{{SLUG}} | フォルダ名(パスなし、スラッシュなし) | hope |
{{FRAME_COUNT}} | 整数のフレーム数 | 241 |
{{FRAME_COUNTER_TEXT}} | 幅が一致する 001 / NNN | 001 / 241 |
{{SCROLL_BUDGET}} | 抽出JSONからの整数 | 6300 |
{{PREVIEW_FRAME_MID}} | ゼロ埋めされた中間フレーム | 121 |
{{PREVIEW_FRAME_END}} | ゼロ埋めされた最終フレーム | 241 |
{{LOADER_TITLE}} | 1語、大文字 | HOPE |
{{LOADER_SCRIPT}} | 手書き行で … で終わる | summoning the runner… |
{{NAV_LINKS_HTML}} | ナビゲーション用の完全な <a> タグブロック | 以下を参照 |
{{SCENE_N_*}} | 各5シーンのキッカー、見出し、手書き行 | コピーガイドを参照 |
{{SCROLL_HINT_TEXT}} | 2〜4語の大文字プロンプト | SCROLL TO RUN |
{{CTA_BUTTONS_HTML}} | 2〜4個の <a class="cta"> タグ | 以下を参照 |
{{ACCENT_CLASS}} | .script.X と .cta.X のアクセントカラーサフィックス | amber |
references/copy-guide.md を読んで、シネマティックなコピーパターン(キッカーの言い回し、見出しの長さ、手書き行のトーン)を確認してください。このスキルの真価はコピーにあります — 一般的なコピーは、美しいアニメーションを台無しにします。
フェーズ4 — アセットの配線
ターゲットフォルダにすでに style.css と parallax.js がある場合(ショーケース統合)、何もしないでください — それらは共有されています。それ以外の場合は、両方を <skill>/assets/ からターゲットフォルダにコピーします。
cp <skill>/assets/style.css <target>/style.css
cp <skill>/assets/parallax.js <target>/parallax.js
既存のショーケースに統合する場合は、references/showcase-integration.md の手順も実行します — index.html にカードを追加し、既存の各ランディングのナビゲーションバーにリンクを追加し、前のランディングの最終シーンにチェーンCTAを追加します。
ユーザーに表示方法を伝えます:
親フォルダから
python -m http.server 8000経由で<target>/<slug>.htmlを開きます(file://ではない — Chromiumはローカル画像オリジンでキャンバスを汚染する可能性があります)。
ファイル契約
<target>/
├── <slug>/ # フレームフォルダ
│ ├── <slug>.mp4 # ソース(保存)
│ ├── frame-001.jpg
│ ├── frame-002.jpg
│ └── … frame-NNN.jpg
├── <slug>.html # ランディングページ
├── style.css # 共有(スタンドアロンの場合はコピー)
├── parallax.js # 共有(スタンドアロンの場合はコピー)
└── index.html # ハブ(スタンドアロンまたは統合の場合のみ)
フレームフォルダ名とHTMLファイル名は同じスラッグを共有する必要があります — ページの new ParallaxPage({folder: '<slug>', ...}) 呼び出しの folder オプションは、リテラルのフォルダパスです。
ParallaxPage API(すでにparallax.jsにあり、再定義しないでください)
new ParallaxPage({
folder: '<slug>', // frame-001.jpgなどを含むフォルダ
frameCount: 145, // 整数
prefix: 'frame-', // このスキルでは常に 'frame-'
scrollBudget: 4200, // 完全なパスのための累積入力ピクセル数
// オプション:padWidth(デフォルト3)、ext(デフォルト 'jpg')
})
このクラスは自動的に body.scrub-page をアタッチし(CSSでスクロールをロック)、すべてのフレームをプリロードし、スクロールから導出されたターゲットフレームに向けてRAF駆動のlerp(係数0.22)を実行し、data-start/data-end 範囲に現在の進行度が含まれるシーンをクロスフェードします。
ハード制約(譲れない条件)
これらはリファレンスに組み込まれており、違反するとエクスペリエンスが損なわれます。
- 5シーン、固定の進行度ウィンドウ:
0.00–0.20、0.22–0.40、0.42–0.60、0.62–0.80、0.82–1.00。シーン間の0.02のギャップは意図的なものです — ビートとビートの間の「画像だけでテキストがない」瞬間です。ヒーロー(シーン1)と最終(シーン5)は、それぞれdata-fade="0.30"とdata-fade="0.18"を使用して、端でより長くホールドします。中間シーンはデフォルトの0.25を使用します。 - スクラブの下に
.endセクションはありません。最終シーンにCTAが含まれます。ページ全体が1つのロックされたビューポートです。 - Anton + Caveat + Inter — 太字はすべて大文字のAnton、手書きアクセント(金/琥珀/クリーム)にはCaveat、本文のリードテキストにはInter。決して置き換えず、4番目のフォントを追加しないでください。
- オフホワイト
#f5f1ea、決して#fffではない — すでにCSSにvar(--text)としてあります。 - フレーム名は
frame-NNN.jpgで、総数の幅にゼロ埋め(クリップは1000フレーム未満なので3桁が標準。JSは総数からカウンター幅を自動計算します)。 - スラッグはフォルダ名であり、かつHTMLファイル名のベース名 —
hope/、hope.html。例外はありません。統合手順はこれを前提としています。
行き詰まったときに見る場所
- このリポジトリにバンドルされているリファレンスショーケース:
examples/parasites/— github.html、lion.html、hope.html、style.css、parallax.js、index.html。出力がそれらと明らかに異なる場合、逸脱しています。読み直してください。 references/copy-guide.md— 5つのシーンを実際にシネマティックに感じさせる書き方。references/showcase-integration.md— 既存のハブに追加するときに必要な正確な編集。assets/landing-page-template.html— プレースホルダー付きの標準構造。assets/hub-template.html— 新しいショーケースをゼロから作成する場合のみ使用(3つのカードをゼロから作成)。
2つの実際の呼び出し例
スタンドアロン: ユーザーが単一のクリップ desk.mp4 を持っており、ランディングページを希望している。
- スラッグとテーマを尋ねる。
desk.mp4で抽出ツールを実行 →./desk/frame-NNN.jpg。 style.css+parallax.jsをプロジェクトルートにコピー。- テンプレートから
desk.htmlを作成。ナビゲーションには自身へのリンクが1つだけ。 - 完了。
python -m http.serverで提供するようにユーザーに伝える。
ショーケース追加: ユーザーが既存のparasitesフォルダに hope.mp4 を追加する。
- スラッグ =
hope。抽出 →hope/frame-NNN.jpg。(既存のstyle.css + parallax.jsを再利用。) - テンプレートから
hope.htmlを作成。 - ショーケース統合を実行:
index.htmlに3番目のカードを追加、github.htmlとlion.htmlのナビゲーションバーにHopeリンクを追加、前のランディングの最終シーンにNext: Hope →CTAでチェーンする。 - 新しいアクセントカラーを導入する場合は、
:rootに追加し、style.cssに.script.X+.cta.Xルールを追加する。