SuperAPI AI Directory

gsap-scrolltrigger-pin

Frontend & websites

View repository

Updated 10-16 05:16

About this skill

Skill: gsap-scrolltrigger-pin

The section pins in place when scrolled to, the user's vertical scroll is read by ScrollTrigger and tweened into horizontal sliding of a track containing multiple slides — the industry-standard "pinned horizontal-scroll section" technique.

WHAT

Purpose and context

  • Purpose: a section pins in place when scrolled to, vertical scroll is converted by GSAP ScrollTrigger into horizontal sliding of a multi-slide track; by default use the verbatim original at Rheinmir/uiux-asset.
  • Trigger (when to use):
    • A page needs a "horizontal gallery"-style section (case study, portfolio, product) while the user still just scrolls the mouse vertically as usual.
    • User says "pin section", "horizontal scroll", "horizontal scroll section", "scroll-driven horizontal", "gsap scrolltrigger", or /gsap-scrolltrigger-pin.
  • Non-goals: NOT for light scroll effects that don't need pinning (use scroll-effects) or for smoothing the scroll feel of the whole page (use lenis-smooth-scroll) — those two skills do NOT pull in the GSAP dependency. Applies only to ONE specific pinned section.

Mental model

[data-hp-section] > .hp-pin (pin) > [data-hp-track] (tween xPercent, scrub) > [data-hp-slide] × N; end is the function that re-measures track.scrollWidth each refresh(); matchMedia chooses the GSAP branch or the reduce-motion branch (plain CSS horizontal scroll).

Input and output contract

Field Required? Meaning
In slide content of the section yes case study / portfolio / product
In permission to pull external libs (GSAP) yes if not allowed to pull libs → use the trimmed version assets/, GSAP is still required
In design.md of the project no if present, change the color tokens to match it
Out pinned section + horizontal track in the project yes copy the original file as-is (keep attribution comments) or adapt assets/
Out verification evidence playwright-verify yes pins at the right time, no horizontal overflow, survives resize

Rules and capabilities

  • RULE-01 (MUST): The GSAP dependency is required — this skill does NOT run without GSAP + the ScrollTrigger plugin. Install in one of two ways:
    • CDN (like demo.html): <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.5/gsap.min.js"></script> + .../ScrollTrigger.min.js, load BEFORE the skill's script.
    • npm: npm install gsap, then import gsap from "gsap"; import { ScrollTrigger } from "gsap/ScrollTrigger"; gsap.registerPlugin(ScrollTrigger);.
  • RULE-02 (MUST): prefers-reduced-motion: reduce → the GSAP branch does NOT init anything at all (no ScrollTrigger, no pin, no scrub) — CSS automatically converts .hp-pin into overflow-x: auto plain horizontal scroll (scroll-snap-type: x mandatory). Do not add any JS animation in this branch.
  • RULE-03 (MUST): Track uses xPercent, do not use x (px) — xPercent automatically follows the actual width of the track even when slide content changes size, no need to recalculate pixel offsets manually.
  • RULE-04 (MUST): Verify with playwright-verify: scroll vertically through the entire section, assert the section pins at the right time (viewport does not scroll vertically further while the track still has slides), assert there is no horizontal overflow in the rest of the page, test resizing the viewport then scroll again to make sure ScrollTrigger.refresh() has picked up the new layout.
  • Capabilities: read the original (web/git) + asset skill + design.md; write HTML/CSS/JS into the target project; run a headless browser to verify.

Failure boundaries

  • Missing GSAP + ScrollTrigger and not allowed to add a dependency → blocked (RULE-01), propose scroll-effects/lenis-smooth-scroll if the requirement actually doesn't need pinning.
  • Open the file with file:// → behavior is incorrect; must run locally over HTTP.
  • Assert verify is red (no pin, horizontal overflow, resize breaks) → failed, fix then verify again.

HOW

Main workflow

Step Type Inputs Action Outputs/exit Failure/next
W01 judgment requirement Confirm pinning + horizontal scrolling is needed (not scroll-effects/lenis-smooth-scroll) select skill no pinning needed → switch to another skill
W02 effect original Pen table Open the link run, copy the entire file .html (+ _assets/) into the project, keep the attribution comment original file in the project not allowed to pull in an external lib → B01
W03 effect file + design.md Only edit content/images/colors section has been adapted —
W04 deterministic page running over HTTP Verify RULE-04 with playwright-verify assert green red → fix, repeat W04

Branches

ID Kind Guard Behavior Skip / failure Rejoin
B01 conditional_required the project is NOT allowed to pull in an external lib (original version) use the vanilla condensed version assets/ (section Reference — Assets), read then ADAPT still needs GSAP (RULE-01) W04
B02 conditional_required prefers-reduced-motion: reduce no GSAP init, plain CSS horizontal scrolling (RULE-02) — W04

Validation and stopping

Deterministic assert at W04 (pins at the right time, no horizontal overflow, resize then scroll back still correct). Needs eyes: content/colors match the project. Stop when the assert is green; if it stays red after more than 2 loops → notify the user with a screenshot.

Examples

  • Positive: "make a horizontal-scrolling portfolio section" → copy horizontal-scroll-section-with-gsap-and-locomotive-scroll.html from Rheinmir/uiux-asset, change images/text → playwright scrolls vertically: section pins, track slides through all slides before releasing, no horizontal overflow.
  • Boundary/failure: use x: -2000 (px) instead of xPercent → resizing the viewport makes the track drift/miss the last slide → violates RULE-03, switch to xPercent: -100 * (slideCount - 1) then verify by resizing again.

Reference — Original — use FIRST (copy the file as-is, don't rewrite it)

The author's VERBATIM original code (public CodePen = MIT) is in an external repo Rheinmir/uiux-asset — live gallery: https://rheinmir.github.io/uiux-asset/scroll-effects/ . Process: open the link run to see the exact effect → copy the file as-is .html (+ the folder _assets/ if the file references it) into the project → keep the attribution comment on the first line → only change content/images/colors. Run locally over HTTP, not file://. git clone --depth 1 https://github.com/Rheinmir/uiux-asset if you need the whole offline bundle.

Original Pen — author Link
Horizontal Scroll Section with GSAP and Locomotive Scroll — cameronknight run · code
Smooth Scroll Stacking Accordion — supah run · code
Infinite Horizontal Scroll with Progress Tracking — haptichash run · code
Pinned Split-Screen Mask Reveal — gridmorphic run · code
Scroll-Driven SVG Map Editorial Gallery — knyttneve run · code

assets/ in this skill is just a self-written vanilla condensed version — use it when the project is NOT allowed to pull external libs; by default use the original above.

Reference — Assets

assets/demo.html + assets/gsap-scrolltrigger-pin.css + assets/gsap-scrolltrigger-pin.js — read then ADAPT (change slide content, color tokens per the project's design.md if any). Open demo.html directly in a browser to see the mechanism running for real (the asset loads GSAP via CDN).

Reference — Mechanism

  • Markup: [data-hp-section] > .hp-pin > [data-hp-track] > [data-hp-slide] × N — the track is a flex-row, each slide flex: 0 0 100vw, total width = N × 100vw (naturally from layout, not computed by hand).
  • ScrollTrigger pin .hp-pin (pin: true, start: "top top"), scrub: 1 locks the animation progress to the exact scroll position — it's not a time-based animation.
  • The animation is gsap.to(track, { xPercent: -100 * (slideCount - 1) }) — slideCount read from track.querySelectorAll('[data-hp-slide]').length, not hardcoding the slide count in the code.
  • end is a FUNCTION: () => "+=" + (track.scrollWidth - window.innerWidth) — recomputed every time ScrollTrigger.refresh() runs (re-measured from the DOM's actual track.scrollWidth at that moment), not a fixed number.
  • ScrollTrigger.matchMedia() wrap the entire init: when the viewport changes breakpoint or prefers-reduced-motion changes, GSAP automatically reverts the old branch and reruns the matching branch — this is the standard way to "survive" resizes, instead of writing a resize listener by hand.
  • window.addEventListener('load', () => ScrollTrigger.refresh()) handle the case where images/fonts finish loading only then does scrollWidth of the track change.

Origin

Batch 180926 — the VERBATIM original is at Rheinmir/uiux-asset/scroll-effects/ (see the "Original" section above); assets/ is a shortened vanilla version written by hand.