mcpField
G
gsap-scrolltrigger-pin

gsap-scrolltrigger-pin

github.com/rheinmir设计与 UI1075 次安装2 周前更新
代码仓库

关于 gsap-scrolltrigger-pin

用于制作滚动时固定的横向多页区块,将纵向滚动映射为横向滑动。它规定了 GSAP ScrollTrigger、减少动态效果的处理及浏览器验证方式。

主要功能

  1. 01固定式横向幻灯片轨道
  2. 02GSAP ScrollTrigger 滚动联动
  3. 03减少动态效果时改用 CSS
  4. 04验证尺寸调整与横向溢出

适用场景

  1. 01制作横向滚动的作品集区块
  2. 02将产品图库改为固定滚动交互

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/rheinmir/setup --skill gsap-scrolltrigger-pin

安装后在 Claude Code 中输入/gsap-scrolltrigger-pin确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

assets/
demo.html
gsap-scrolltrigger-pin.css
gsap-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)——这两个技能都不会引入 GSAP 依赖。仅用于一个特定的固定区块。
心智模型

[data-hp-section] > .hp-pin (pin) > [data-hp-track] (tween xPercent, scrub) > [data-hp-slide] × N;end 是一个函数,会在每次 refresh() 时重新测量 track.scrollWidth;matchMedia 负责选择 GSAP 分支或减少动态效果分支(普通 CSS 横向滚动)。

输入和输出约定
字段必填?含义
In区块的幻灯片内容是案例研究 / 作品集 / 产品
In是否允许引入外部库(GSAP)是不允许引入库 → 使用精简版 assets/,但仍必须使用 GSAP
In项目的 design.md否如有,则按其调整颜色 token
Out项目中的固定区块 + 水平轨道是原样复制源文件(保留署名注释)或改编 assets/
Outplaywright-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);。
  • RULE-02 (MUST):prefers-reduced-motion: reduce → GSAP 分支不执行任何初始化(不使用 ScrollTrigger、不固定、不 scrub)——CSS 会自动将 .hp-pin 切换为 overflow-x: auto 的普通横向滚动(scroll-snap-type: x mandatory)。此分支中不要添加任何 JS 动画。
  • RULE-03 (MUST):轨道使用 xPercent,不要使用 x(px)——无论幻灯片内容如何改变尺寸,xPercent 都会自动适配轨道的实际宽度,无需手动重新计算 px 偏移量。
  • RULE-04 (MUST):使用 playwright-verify 验证:垂直滚动穿过整个区块,断言区块在正确时机固定(轨道尚未播放完所有幻灯片时,视口不会继续垂直滚动);断言页面其余部分没有横向溢出;调整视口大小后重新滚动,确认 ScrollTrigger.refresh() 已适配新的布局。
  • 能力:读取原始版本(web/git)、技能资源和 design.md;将 HTML/CSS/JS 写入目标项目;运行无头浏览器进行验证。
失败边界
  • 缺少 GSAP + ScrollTrigger 且不允许添加依赖 → 受阻(RULE-01),如果实际需求并不需要固定效果,则建议使用 scroll-effects / lenis-smooth-scroll。
  • 使用 file:// 打开文件 → 行为异常;必须通过 HTTP 在本地运行。
  • 验证断言失败(未固定、横向溢出、调整大小后出现问题)→ 失败,修复后重新验证。

HOW

主要工作流
步骤类型输入操作输出/退出失败/下一步
W01判断需求确认是否需要固定 + 水平滚动(不是 scroll-effects/lenis-smooth-scroll)选择 skill不需要固定 → 切换到其他 skill
W02效果原始 Pen打开运行链接,复制整个 .html 文件(+ _assets/)到项目中,保留署名注释项目中的原始文件不允许引入外部库 → B01
W03效果文件 + design.md只修改内容/图片/颜色已适配的 section—
W04确定性通过 HTTP 运行的页面使用 playwright-verify 验证 RULE-04断言通过未通过 → 修改并重复 W04
分支
ID类型条件行为跳过 / 失败汇合
B01conditional_required项目不允许引入外部库(原始版本)使用精简版 vanilla assets/(见 Reference — Assets),阅读后再适配仍需要 GSAP(RULE-01)W04
B02conditional_requiredprefers-reduced-motion: reduce不初始化 GSAP,使用普通 CSS 水平滚动(RULE-02)—W04
验证与停止

W04 中进行确定性断言(正确固定、无水平溢出、调整大小后再次滚动仍正确)。需要人工检查:内容/颜色符合项目风格。断言通过后停止;重复超过 2 轮仍未通过 → 附上截图告知用户。

示例
  • 正例:“制作一个水平滚动的作品集 section” → 从 Rheinmir/uiux-asset 复制 horizontal-scroll-section-with-gsap-and-locomotive-scroll.html,更换图片/文字 → 使用 playwright 验证垂直滚动:section 固定,track 滑过所有 slide 后才释放,没有水平溢出。
  • **边界/失败:**使用 x: -2000(px)代替 xPercent → 调整 viewport 大小后,track 偏移/最后一个 slide 显示不全 → 违反 RULE-03,改为 xPercent: -100 * (slideCount - 1),然后再次验证调整大小后的效果。
参考 — 原始版本 — 优先使用(复制整个文件,不要重写)

作者的原始完整代码(公开的 CodePen = MIT)位于外部仓库 Rheinmir/uiux-asset — 可实际运行的 gallery:https://rheinmir.github.io/uiux-asset/scroll-effects/ 。 流程:打开运行链接查看实际效果 → 将整个 .html 文件(+ 文件引用的 _assets/ 目录)复制到项目中 → 保留首行署名注释 → 只修改内容/图片/颜色。通过 HTTP 在本地运行,不要使用 file://。 如果需要完整离线版本,可运行 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运行 · 代码

此 skill 中的 assets/ 仅为自行编写的精简版 vanilla 版本 — 仅在项目不允许引入外部库时使用;默认使用上方的原始版本。

参考 — 资源

assets/demo.html + assets/gsap-scrolltrigger-pin.css + assets/gsap-scrolltrigger-pin.js — 阅读后进行改编(如果项目有 design.md,则更换幻灯片内容和颜色 token)。直接用浏览器打开 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() 包裹整个初始化流程:当 viewport 切换断点或 prefers-reduced-motion 改变时,GSAP 会自动回滚旧分支并运行匹配的新分支——这是应对 resize 的标准方式,而不是手动编写 resize listener。
  • window.addEventListener('load', () => ScrollTrigger.refresh()) 用于处理图片/字体加载完成后 track 的实际 scrollWidth 才发生变化的情况。

来源

批次 180926 — 原始版本原封不动地位于 Rheinmir/uiux-asset/scroll-effects/(参见上文“原始版本”部分);assets/ 是自行编写的精简版原生实现。

评论

支持 Markdown