scroll-scrubbed-visual-sequence について
Web ページでスクロール操作に連動するビジュアルシーケンスを作るデザインスキルです。レンダラーの選択、スクロール位置との同期、アクセシビリティやメディア処理を支援します。
主な機能
- 01動画、画像、Canvas、SVG、DOM、WebGL からレンダラーを選択
- 02スクロール位置を再現可能なビジュアル状態に対応付け
- 03レスポンシブなスティッキーステージ構成
- 04動きを減らす設定とセマンティックコンテンツの指針
- 05メディア読み込み、性能、クリーンアップの確認
活用シーン
- 01スクロール連動の商品ストーリーを作成
- 02画像フレームや動画をページスクロールに同期
- 03動きを減らす設定向けの静止画表示を用意
- 04異なるビューポート幅でシーケンスを検証
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ mengto/ skills --skill scroll-scrubbed-visual-sequenceインストール後、Claude Code で/scroll-scrubbed-visual-sequenceを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
REFERENCES.mdagents/openai.yamldemo/index.htmlPROMPT.md詳細
スクロール連動のビジュアルシーケンス
1つのビジュアル変化を、スクロールに応じて反応する仕組みにします。モーションがなくてもページを使える状態に保ち、レンダラーを差し替え可能にします。
シーケンスを定義する
コーディングの前に、ビジュアルの状態を記述します。
const sequence = {
scrollVh: 280,
frameCount: 96,
fit: "contain",
posterFrame: 0,
reducedMotionFrame: 95,
copyStops: [0, 0.42, 0.78]
};
すべてのレンダラーで、正規化された値を1つ使います。
const progress = Math.min(1, Math.max(0,
(viewportTop - sectionTop) / (sectionHeight - viewportHeight)
));
ホイールのデルタ、経過時間、自動再生を真の状態の基準にしないでください。スクロール位置によって、双方向で正確なビジュアル状態が決まるようにします。
レンダラーを選ぶ
- シーケンスが連続的、写真のような表現、またはリアルタイムでの描画コストが高い場合は、動画を使います。キーフレームを細かく設定し、メタデータを先読みし、アスペクト比の領域を確保して、
requestAnimationFrame内でcurrentTimeへの書き込みをまとめます。 - アートディレクションに忠実なフレームが重要な場合は、画像シーケンスを使います。まず現在のフレームを先読みし、次に近くのフレームを読み込みます。すべての画像の読み込みが完了するまで初回描画を妨げないでください。
- 手続き型の描画や合成には、canvasを使います。デバイスピクセル比は2を上限とし、進行状況が変化したときだけ再描画します。
- 図、製品カード、インターフェースの状態、アクセシブルなテキストには、SVGまたはDOMを使います。レイアウトへの負荷が大きいプロパティではなく、transform、opacity、clip path、CSS変数を使って制御します。
- 深度、ライティング、実際の3Dカメラによってアイデアが大きく強化される場合に限り、WebGLを使います。静的なポスターを用意し、リソースを破棄します。
スクロールステージを構築する
- セクションを通常のドキュメントフローに保ち、高さを
scrollVhから設定します。 - ビジュアルを、ビューポートサイズの
position: stickyステージに配置します。 - コピーとコントロールは別のレイヤーに配置します。重要なテキストをフレームに埋め込まないでください。
- 暗黙のイージングを使わずに、進行状況をレンダラーに反映します。正しく動作することを確認した後で、必要に応じてスムージングを追加します。
- フォントやメディア固有のサイズが確定した後に、計測値を更新します。
- 次のセクションの前でスティッキーステージを適切に終了し、フッターにアクセスできる状態を保ちます。
プロジェクトでGSAPをすでに使っている場合や、ピン留め、更新、タイムラインの正確な連携が必要な場合は、GSAP ScrollTriggerを使います。
ScrollTrigger.create({
trigger: section,
start: "top top",
end: () => `+=${innerHeight * 2.8}`,
pin: stage,
scrub: true,
invalidateOnRefresh: true,
onUpdate: ({ progress }) => render(progress)
});
依存関係なしで実装する場合は、スクロール時とリサイズ時にセクションを計測し、アニメーションフレームごとに1回だけ描画をスケジュールします。
メディアを安全に扱う
- 最初の実際のフレームが描画されるまでは、ポスターを表示しておきます。
- フレームインデックスを
0...frameCount - 1の範囲に制限します。 - 古くなった画像リクエストをキャンセルし、高速スクロール中にシークをすべてキューに入れないでください。
- モバイルで切り抜かれても被写体が残るように、
object-fitと明示的な焦点位置を設定します。 - セクションが画面外にあるとき、またはドキュメントが非表示のときは、デコード、描画、監視を一時停止します。
- ルート変更またはアンマウント時に、ScrollTrigger、オブザーバー、リスナー、アニメーションフレーム、Blob URL、レンダラーのリソースをクリーンアップします。
アクセシビリティと操作性を確保する
- 見出し、コピー、キャプション、CTAはセマンティックHTMLに保ちます。
- スクロールを妨げたり、キーボード操作をブロックしたり、正確なポインター操作を必須にしたりしないでください。
prefers-reduced-motion: reduceの場合は、ピン留めとスクラブを解除し、選択した静止フレームを描画して、通常のドキュメントフローに戻します。- シーケンスが順序のある情報を伝える場合は、同じ状態をテキストまたはリストでも提示します。
意図を持って調整する
スクロール距離、レンダラー、フレーム数、ポスターフレーム、メディアのフィット方法、焦点位置、コピーの停止位置、オーバーレイの強さ、スムージング、動きを減らす設定の状態を、設定として公開します。イベントハンドラー全体にマジックナンバーを散在させないでください。
検証する
順方向と逆方向のスクロール、高速なフリック、動作中のリサイズ、幅390/768/1024/1440、未読み込みのフレーム、動画再生のブロック、動きを減らす設定、キーボード操作の順序、ルートのクリーンアップ、コンソールエラーを確認します。同じスクロール位置では、常に同じ状態が再現される必要があります。
動作するリファレンスとしてdemo/index.htmlを使い、再現またはリミックスするにはdemo/PROMPT.mdを使います。REFERENCES.mdはリンクのみの実装ソース一覧として維持します。