gsap-scrolltrigger-pin について
縦スクロールに連動して複数スライドのトラックを横移動させる、セクション固定型のデザインスキルです。GSAP ScrollTriggerの設定、動きを抑える場合の処理、ブラウザー検証を扱います。
主な機能
- 01固定型の横スライドトラック
- 02GSAP ScrollTriggerによるスクラブ
- 03動きを抑える場合のCSS切り替え
- 04リサイズと横はみ出しの検証
活用シーン
- 01横スクロール式ポートフォリオの作成
- 02製品ギャラリーへの固定スクロール演出
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ rheinmir/ setup --skill gsap-scrolltrigger-pinインストール後、Claude Code で/gsap-scrolltrigger-pinを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
assets/demo.htmlgsap-scrolltrigger-pin.cssgsap-scrolltrigger-pin.js詳細
スキル:gsap-scrolltrigger-pin
スクロールして到達するとセクションをその場にピン留めし、ユーザーの縦スクロールを ScrollTrigger が読み取って、複数のスライドを含むトラックの横方向のスライドに変換します。これは標準的な「ピン留めされた横スクロールセクション」の手法です。
WHAT
目的とコンテキスト
- 目的: スクロールして到達するとセクションをピン留めし、縦スクロールを GSAP ScrollTrigger が複数のスライドを含むトラックの横方向のスライドに変換します。デフォルトでは
Rheinmir/uiux-assetのオリジナル版をそのまま使用します。 - トリガー(使用するタイミング):
- ユーザーが通常どおり縦にスクロールしながら閲覧できる、「横スクロールギャラリー」形式のセクション(ケーススタディ、ポートフォリオ、製品など)が必要なページ。
- ユーザーが「セクションをピン留め」「横スクロール」「horizontal scroll section」「scroll-driven horizontal」「gsap scrolltrigger」または /gsap-scrolltrigger-pin と言った場合。
- 対象外: ピン留めが不要な軽いスクロールエフェクトには使用しないでください(
scroll-effectsを使用)。ページ全体のスクロール感を滑らかにする用途にも使用しないでください(lenis-smooth-scrollを使用)。これら2つのスキルは GSAP 依存関係を追加しません。このスキルは、特定の1つのセクションをピン留めする場合にのみ使用します。
メンタルモデル
[data-hp-section] > .hp-pin (pin) > [data-hp-track] (tween xPercent, scrub) > [data-hp-slide] × N。end は refresh() のたびに track.scrollWidth を再計測する関数です。matchMedia が GSAP の分岐か、reduced-motion 用の分岐(通常の CSS 横スクロール)を選択します。
入力と出力の契約
| フィールド | 必須? | 意味 | |
|---|---|---|---|
| In | セクションのスライドコンテンツ | はい | ケーススタディ/ポートフォリオ/製品 |
| In | 外部ライブラリ(GSAP)の追加許可 | はい | ライブラリを追加できない場合は、簡略版の assets/ を使用します。GSAP は引き続き必須です |
| In | プロジェクトの design.md | いいえ | ある場合は、色のトークンをそれに合わせて変更します |
| Out | プロジェクト内のピン留めセクションと横スクロールトラック | はい | オリジナルファイルをそのままコピー(クレジットコメントを保持)するか、assets/ を適用します |
| Out | playwright-verify による検証の証拠 | はい | 適切なタイミングでピン留めされること、横方向にオーバーフローしないこと、リサイズ後も正常に動作すること |
ルールと機能
- RULE-01 (MUST):GSAP への依存は必須です — GSAP と ScrollTrigger プラグインがない場合、このスキルは動作しません。次のいずれかの方法でインストールしてください。
- CDN(demo.html のように):
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.5/gsap.min.js"></script>と.../ScrollTrigger.min.jsを、スキルのスクリプトより前に読み込みます。 - npm:
npm install gsapを実行し、import gsap from "gsap"; import { ScrollTrigger } from "gsap/ScrollTrigger"; gsap.registerPlugin(ScrollTrigger);を実行します。
- CDN(demo.html のように):
- RULE-02 (MUST):
prefers-reduced-motion: reduceの場合、GSAP の分岐では何も初期化しません(ScrollTrigger、ピン留め、scrub は使用しません)。CSS が.hp-pinをoverflow-x: autoに切り替え、通常の横スクロール(scroll-snap-type: x mandatory)にします。この分岐に JavaScript アニメーションを追加しないでください。 - RULE-03 (MUST):トラックには
x(px)ではなくxPercentを使用します。xPercentはスライドコンテンツのサイズが変わってもトラックの実際の幅に追従するため、px 単位のオフセットを手動で再計算する必要がありません。 - RULE-04 (MUST):
playwright-verifyで検証します。セクション全体を縦にスクロールし、トラックのスライドが終わるまでビューポートがさらに縦スクロールしないことを確認して、セクションが適切なタイミングでピン留めされることをアサートします。ページの残りの部分に横方向のオーバーフローがないことをアサートします。ビューポートのサイズを変更してから再度スクロールし、新しいレイアウトがScrollTrigger.refresh()に反映されていることを確認します。 - 機能:オリジナル版(Web/Git)とスキルのアセット、
design.mdを読み取り、HTML/CSS/JS を対象プロジェクトに記述し、ヘッドレスブラウザーを実行して検証します。
失敗時の境界
- GSAP と ScrollTrigger がなく、依存関係を追加できない場合 → blocked(RULE-01)。実際の要件にピン留めが不要であれば、
scroll-effects/lenis-smooth-scrollを提案します。 - ファイルを
file://で開いた場合 → 正しく動作しません。HTTP 経由でローカル実行する必要があります。 - 検証アサーションが失敗(ピン留めされない、横方向にオーバーフローする、リサイズで壊れる) → failed。修正して再度検証します。
HOW
メインワークフロー
| ステップ | 種類 | 入力 | アクション | 出力/終了条件 | 失敗時/次の手順 |
|---|---|---|---|---|---|
| W01 | 判断 | 要件 | ピン留め+横スクロールが必要か確認します(scroll-effects/lenis-smooth-scrollではありません) | スキルを選択 | ピン留めが不要 → 別のスキルに切り替え |
| W02 | 効果 | 元のPen | 実行リンクを開き、.htmlファイル全体(+_assets/)をプロジェクトにコピーし、クレジットコメントを残します | プロジェクト内の元ファイル | 外部ライブラリを追加できない → B01 |
| W03 | 効果 | ファイル+design.md | 内容/画像/色のみを変更します | 適用済みセクション | — |
| W04 | 決定論的 | HTTP経由で実行中のページ | playwright-verifyでRULE-04を検証します | アサーション成功 | 失敗 → 修正し、W04を繰り返す |
分岐
| ID | 種類 | 条件 | 動作 | スキップ/失敗 | 再合流 |
|---|---|---|---|---|---|
| B01 | 条件付き必須 | プロジェクトで外部ライブラリの追加が禁止されている(元の実装) | Vanillaの簡易版assets/(Reference — Assetsの項)を使い、読み込んでから適用します | それでもGSAPが必要(RULE-01) | W04 |
| B02 | 条件付き必須 | prefers-reduced-motion: reduce | GSAPを初期化せず、通常のCSS横スクロールを使います(RULE-02) | — | W04 |
検証と終了条件
W04で決定論的なアサーションを実行します(適切なタイミングでピン留めされること、横方向にはみ出さないこと、リサイズ後に再度スクロールしても正しいこと)。内容/色がプロジェクトに合っているかは目視が必要です。アサーションが成功したら終了します。2回を超えて繰り返しても失敗する場合は、画像を添えてユーザーに報告します。
例
- 成功例:「ポートフォリオの横スクロールセクションを作成」→
Rheinmir/uiux-assetからhorizontal-scroll-section-with-gsap-and-locomotive-scroll.htmlをコピーし、画像/テキストを変更します → Playwrightで縦スクロールし、セクションがピン留めされ、トラックがすべてのスライドを通過してから解除され、横方向にはみ出さないことを確認します。 - 境界/失敗例:
xPercentの代わりにx: -2000(px)を使う → ビューポートのサイズを変えるとトラックがずれ、最後のスライドが欠けます → RULE-03違反のため、xPercent: -100 * (slideCount - 1)に変更してから、リサイズ後に再検証します。
参考 — 元の実装 — 先に使用(ファイル全体をコピーし、書き直さない)
作者のオリジナルコード(公開CodePen=MIT)は、外部リポジトリ**Rheinmir/uiux-asset**にあります — 実際に動作するギャラリー:https://rheinmir.github.io/uiux-asset/scroll-effects/ 。
手順:実行リンクを開いて正しい効果を確認 → .htmlファイル全体(ファイルから参照されている場合は_assets/フォルダーも)をプロジェクトにコピー → 先頭行のクレジットコメントを残す → 内容/画像/色のみを変更します。file://ではなく、HTTP経由でローカル実行します。
オフライン用に一式が必要な場合は、git clone --depth 1 https://github.com/Rheinmir/uiux-assetを実行します。
| 元のPen — 作者 | リンク |
|---|---|
| Horizontal Scroll Section with GSAP and Locomotive Scroll — cameronknight | 実行 · コード |
| Smooth Scroll Stacking Accordion — supah | 実行 · コード |
| Infinite Horizontal Scroll with Progress Tracking — haptichash | 実行 · コード |
| Pinned Split-Screen Mask Reveal — gridmorphic | 実行 · コード |
| Scroll-Driven SVG Map Editorial Gallery — knyttneve | 実行 · コード |
このスキルのassets/は、自作したVanillaの簡易版のみです — プロジェクトで外部ライブラリの追加が禁止されている場合に使用します。通常は上記の元の実装を使用してください。
リファレンス — アセット
assets/demo.html + assets/gsap-scrolltrigger-pin.css + assets/gsap-scrolltrigger-pin.js — 読んでから適用してください(スライドの内容を変更し、プロジェクトに design.md があれば、そこに記載されたカラートークンを使用してください)。demo.html をブラウザーで直接開くと、実際の動作を確認できます(アセットは CDN 経由で GSAP を読み込みます)。
リファレンス — 仕組み
- マークアップ:
[data-hp-section] > .hp-pin > [data-hp-track] > [data-hp-slide] × N— track は flex-row で、各スライドはflex: 0 0 100vw、合計幅は N × 100vw です(レイアウトに従って自動的に決まるため、手動で計算する必要はありません)。 ScrollTriggerで.hp-pinをピン留めし(pin: true、start: "top top")、scrub: 1でアニメーションの進行をスクロール位置に正確に連動させます。時間経過でアニメーションが実行されるわけではありません。- アニメーションは
gsap.to(track, { xPercent: -100 * (slideCount - 1) })です。slideCountはtrack.querySelectorAll('[data-hp-slide]').lengthから取得し、コードにスライド数をハードコードしません。 endは関数です:() => "+=" + (track.scrollWidth - window.innerWidth)—ScrollTrigger.refresh()の実行ごとに再計算されます(その時点での実際の DOM のtrack.scrollWidthに基づいて再測定されます)。固定値ではありません。ScrollTrigger.matchMedia()で初期化処理全体を囲みます。ビューポートのブレークポイント、またはprefers-reduced-motionが変わると、GSAP は古い分岐を自動的に元に戻し、条件に合う分岐を再実行します。これは、独自の resize リスナーを手書きする代わりに、リサイズに適切に対応する標準的な方法です。window.addEventListener('load', () => ScrollTrigger.refresh())で、画像やフォントの読み込み完了後に track の実際のscrollWidthが変わるケースにも対応します。
Origin
Batch 180926 — 元の原文は Rheinmir/uiux-asset/scroll-effects/ にあります(上記の「原文」を参照してください)。assets/ は独自に書き直した簡易版の vanilla です。