Communitygithub.com

Niltra/web-scrollytelling

映画のようなスクロール体験(ピン留めヒーロー、キャンバスフレームシーケンス、ビデオスクラブ、ナレーション付きチャプター)を、GSAP ScrollTrigger を使って実装します。スクロールジャッキングは行わず、パフォーマンスも測定します。アニメーションヒーロー、ピン留めセクション、水平ギャラリー、または「Web を動画のように操作する」効果を作成する際に使用します。

web-scrollytelling とは?

このスキルは、Apple 製品のランディングページで見られるような、映画のようなスクロール体験(スクローリーテリング)を実装するための技術設計を提供します。GSAP の ScrollTrigger とピン留めを中核とし、単一のスクロール進行度(0→1)によって、キャンバス上のフレームシーケンス、ビデオのスクラブ、テキストオーバーレイのフェードなど、すべてのアニメーションを制御します。 主な特徴として、スクロールジャッキングを禁止しユーザーのスクロール速度を尊重すること、Lenis と GSAP の統合による単一アニメーションループの維持、そしてテキストは DOM に保持しキャンバスに描画しないことが挙げられます。フレームシーケンスには、ffmpeg で生成した WebP 画像を使用し、モバイルではフレーム数を制限、ウィンドウスライディング方式でメモリを節約します。パフォーマンス計測は `requestAnimationFrame` で 60fps を目標とし、実際のモバイル端末でのテストを含みます。 このスキルは、Claude Code、Cursor、Codex などの AI エージェントが、開発者向けに高パフォーマンスでアクセシブルなスクローリーテリング体験を生成するための明確なガイドラインとコード構造を提供します。対応プラットフォームは Web ブラウザ全般(特に iOS Safari を考慮)です。

対応~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Niltra/agent-skills-web/tree/HEAD/skills/web-scrollytelling

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

映画的なスクローリーテリング

基本アーキテクチャ(譲れない条件)

  • 単一ピン、単一タイムライン。 ヒーロー(またはメインチャプター)は、N ビューポート高の間ピン留めされるコンテナを持ち、進行度 0→1 ですべてを制御します。複数のスクロールアニメーションが競合する場合、それは単なるエフェクト付きの Web ページであり、これではありません。
  • 絶対にスクロールジャッキングをしない。 ユーザーはネイティブスクロールで速度を制御し、アニメーションはそれに応じて「スクラブ」されます(scrub: true)。ホイールを乗っ取ったり、ユーザーに代わってスクロールを移動させることは禁止です。
  • 単一のアニメーションループ。 Lenis を GSAP のティッカーに統合する(autoRaf: false)か、ネイティブスクロールとスクラブを使用します。2 つのループが競合することはジャンクの最大の原因であり、アセットを最適化しても解決しません。
  • テキストは DOM 内に配置し、キャンバスにオーバーレイし、進行度に応じてレイヤーを制御します。キャンバス内にコピーをレンダリングしてはいけません。

フレームシーケンス(Apple タイプの手法)

  • 推奨ソース:実際のビデオ → ffmpeg でフレームに変換(fps=12..24、画面解像度に合わせて拡大縮小)。WebP(q≈68-75)でエクスポートし、結果を見ながら微調整します(直感ではなく)。
  • 最大約 90~120 フレーム。モバイルでは半分または 720p バージョンを配信します。
  • スライディングウィンドウ方式で読み込む:現在のフレームの周囲 ±6~10 フレームを維持し、シーケンス全体をデコードしてはいけません(フル 1080p シーケンスは iOS Safari を強制終了させます)。
  • プリロードには IntersectionObserver(rootMargin 約 800px)、requestIdleCallback によるデコード、fetchPriority="low"(ヒーローを除く)を使用します。
  • キャンバスは devicePixelRatio を 1.5 に制限し、cover/contain を計算して設定。デコード済みのフレームのみを描画します。該当するフレームがない場合は、最も近い既に読み込まれているフレームを使用します(決して黒を描画しない)。
  • キャッシュは不変(Cache-Control: public, max-age=31536000, immutable)とし、ファイル名はバージョン管理します。
  • prefers-reduced-motion や低速接続時のフォールバック:静的ポスター+ピン留めなしの通常チャプター。
  • 後処理が不要な場合のよりシンプルな代替手段:フレームごとに <img> の src を交換する(キャンバスなしで、すべてのブラウザで信頼性が高い)。

ビデオスクラブ(<video> を使用する場合)

  • currentTime は、単一の requestAnimationFrame 内で進行度によって制御し、スムージングを適用。シークを統合します(Safari はキューを蓄積します)。
  • 100% シーク可能にするために blob として読み込む。GOP を短く(数フレームごとにキーフレーム)エンコードするか、スクラブがカクつきます。
  • 絶対に autoplay は使用しない。スクロールによって動きます。

チャプターとオーバーレイ

  • ビートは進行度の範囲(10%、35%、60%、85%...)で定義し、フェードイン/アウトと、リズムのために左右交互に入力を行います。
  • 各チャプターのテキストは、正しいセマンティックな順序で DOM に保持し、SEO に対応します。
  • 水平ギャラリー:セクションをピン留めし、x を進行度にリンク。カードは中央に向かってスケールします。

パフォーマンスと検証

  • アニメーションは transform、opacity、filter のみに制限。will-change は必要な場面でのみ使用し、終了後に削除します。
  • フレームレートは requestAnimationFrame でローカルと実際のモバイル端末(可能であれば)で測定。目標は中級ノート PC で 60fps。
  • ヘッドレスキャプチャはキャンバスを黒く読み取る可能性があります(バッファが保存されていない)。DOM で検証する(計算済みスタイル、要素、window.debug に公開された状態)、および減速モードを有効にして検証します。
  • 375/768/1280/1440 でテスト。デスクトップブラウザのリサイズは iOS のメモリクラッシュを再現しません。QA レポートにその旨を記載します。

推奨データ構造

「プレーン」の順序付けられた配列。各プレーンは { tipo: 'frames' | 'overlay' | 'galeria', ... } です。ムービーの順序を変更するには、リストを並べ替えます。フレームはパターンで参照します(/seq/plano-01/0001.webp)。

Individual skills in this repo

This repo contains 3 individual skills — each has its own dedicated page.

関連スキル