1实现原理 · 为什么它能做到
把一个插件当成一等主题:先用「注册」建立前置条件,再按配置面(trigger/start/end/scrub/pin…)给出一张 20+ 项的可查表。
ScrollTrigger is a plugin. After loading the script, register it once:
把 start/end 的字符串语法讲成「触发点 vs 视口点」的坐标模型,并给出 clamp()/相对值/函数三种进阶形态。
**start** / **end**: viewport position vs. trigger position. Format `"triggerPosition viewportPosition"`.
batch() 用一批 ScrollTrigger + 时间窗聚合回调,替代 IntersectionObserver 手写批处理:一次给到本轮进入视口的全部元素。
**ScrollTrigger.batch(triggers, vars)** creates one ScrollTrigger per target and **batches** their callbacks
scrollerProxy() 给出与第三方平滑滚动库共存的接法:用自定义 getter/setter 覆盖 scrollTop/scrollLeft,并把 ScrollTrigger.update 注册为滚动监听。
**Critical:** When the third-party scroller updates its position, ScrollTrigger must be notified.
「假横向滚动」模式被拆成四步固定配方,并把 ease: "none" 列为硬约束(否则滚动位置与横向位置不同步)。
The container animation must use **ease: "none"**.
生命周期纪律前置:refresh 的自动/手动边界 + 创建顺序/refreshPriority + kill 清理,防止 SPA 里遗留实例在陈旧节点上跑。
Create ScrollTriggers in the order they appear on the page (top to bottom, scroll 0 → max).
把「scrub 与 toggleActions 二选一」写成显式互斥,并告知同时存在时 scrub 胜出——这是查询式排障里最常见的困惑。
❌ Use **scrub** and **toggleActions** together on the same ScrollTrigger; choose one behavior. If both exist, **scrub** wins.
2核心能力
3外部依赖
| 类型 | 依赖 |
|---|---|
| package | gsap/ScrollTrigger(插件,须 registerPlugin) |
| network | GSAP 官方 ScrollTrigger 文档 |
| network | batch() 官方文档 |
| network | scrollerProxy() 官方文档 |
4风险提醒 风险提醒:绿色 · 放心使用
- pin/scrollerProxy 会真实改动页面布局与滚动行为 — pin 插入 spacer、scrollerProxy 接管 scrollTop 读写;用错(如 pin 动被固定元素、proxy 忘了通知 update)会造成滚动错位或抖动,必须真机验证。
- 清理纪律依赖开发者执行 — SPA 中换页/卸载不 kill 会留下绑定在陈旧节点上的实例;React 侧需配合 gsap-react 的 useGSAP 或 ctx.revert() 才能自动回收。
- containerAnimation 模式能力受限 — 官方限制(skill 已声明):该模式下 pin 与 snap 不可用,且必须 ease:none、触发元素需偏移 start/end——用错会得到「不同步」的假横向滚动。
- 版本敏感 — clamp() 需 v3.12+、SplitText/onSplit 等新 API 属 v3.13+;本分析只对 pin aed9cfd 负责,跨版本使用需自行核对 API。
5第二遍独立确认
- [ok] 目录资产面:仅 SKILL.md — skills/gsap-scrolltrigger/ 下唯一文件 SKILL.md(18,390 B);无 scripts/、references/、数据文件。
- [ok] external_deps 逐条核实调用点 — registerPlugin(ScrollTrigger) 代码块、三条 gsap.com URL(文档链接、batch()、scrollerProxy())均在文件内逐字命中,无自造端点。
- [ok] 「ease: none 是硬约束」是否有原文支撑 — 原文两处强调:配方第 2 步「Use **ease: "none"** on that tween」与 Caveats「The container animation must use **ease: "none"**.」,并解释原因是 1:1 映射会被缓动破坏。
- [ok] batch 回调签名描述(两参数)是否属实 — 原文明确「Batched callbacks receive **two** parameters (unlike normal ScrollTrigger callbacks, which receive the instance)」,与 GSAP 官方 batch 行为一致。
- [ok] scrollerProxy getter/setter 双态语义描述 — 原文「called **with** an argument, it is a setter; called **with no** argument → getter」并给出 arguments.length 判定的示例代码,符合官方 API。
- [ok] 安全反例搜索(隐藏脚本/网络/凭证) — 对该文件 token 扫描:curl/wget/fetch(/XMLHttpRequest/exec(/child_process/process.env/.env/API_KEY/secret 全零命中;URL 仅 3 条 gsap.com。
- [ok] 与 gsap-performance / gsap-react 的表述是否冲突 — 三者对 scrub、refresh、React 清理的说法一致(performance 提出去抖 refresh、react 提供 useGSAP 自动清理),无自相矛盾。
- [ok] 元数据与 pin — frontmatter license MIT;本地 HEAD = aed9cfd3277740755f6bfc1155c7aa645403b760;GitHub API stars 15326 / pushed_at 2026-07-29T17:36:08Z(晚于 pin,结论不跨版本)。
6结论
d77050ca6e9970e0…aed9cfd327