/ 1 分鐘 / -- views

用 GSAP 做 scroll 互動的幾個小技巧

ScrollTrigger 的 pin、scrub、velocity 應用筆記。比較適合做 portfolio 跟 landing page,不太適合用在長文。

GSAP 從 2025 開始所有 plugin 免費了,包含以前要付錢的 ScrollTrigger、SplitText、MorphSVG。對個人站來說真的滿香的。

pin + scrub 不要過頭

pin: true 是一個很容易上癮的功能。你會想:「啊這段 hero 卡在那邊讓字慢慢變色多酷」。然後你做了三個 section 都用 pin,整個頁面就變得很黏,使用者捲不出去。

我自己的原則:

  • 整頁最多 1 個 pin section
  • pin 的距離不要超過 +=80%
  • 有意義的轉場才 pin(例如 hero 標題從 stroke → fill),純粹「卡一下」就算了

velocity 連動

ScrollTrigger 的 getVelocity() 可以拿到當下的捲動速度,做 marquee 反向加速很有趣:

ScrollTrigger.create({
  trigger: track,
  onUpdate: (self) => {
    scrollVel = self.getVelocity() / 200;
  },
});

每一 frame 把 scrollVel 拿來修改 marquee 的目標速度,捲快了文字會反向被「拖」一下。互動感比單純等速跑馬燈強很多。

refresh 時機

ScrollTrigger 內部會快取每個 trigger 的位置。如果你在頁面 mount 之後動態插入內容、或頁面剛切換完成,要手動 ScrollTrigger.refresh(),不然新內容的觸發點會錯亂。

我把所有 init 包成一個 boot(),在 DOMContentLoadedastro:after-swap 都呼叫一次。

reduce motion 是底線

const reduce = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
if (reduce) return;

如果使用者系統設定要求減少動畫,整套 ScrollTrigger 都不要跑。CSS 那邊另外用 media query 把 transition 砍短就好。不要用 reduce motion 還硬要播 hero pin。

點下去看看會發生什麼事 →

留言 / 想法

有疑問、建議或不同看法?歡迎在下方留言(需要 GitHub 帳號)。