Frontend Lab
← 回到所有效果
G01S101gsap

Pin Section + Scrub

釘住區塊 + 滾動驅動

難度 ★★★★★標籤 scrollTrigger · pin · scrub3 min read

效果簡述

GSAP ScrollTrigger 的招牌:區塊滾到頂端時釘住,動畫被滾動進度驅動。 做 product walkthrough、scrollytelling 必備。Framer 也能做但語法繁瑣, GSAP 一行 pin: true + scrub: true 比較直覺。

↓ 滾我 · scrub: 1
釘住的我
預設|scrub 1, 釘住整段

Claude Code Prompt

💬 Claude Code Prompt
參考:S101 pin section + scrub
技術:gsap + ScrollTrigger (pin / scrub)

具體行為:
- gsap.registerPlugin(ScrollTrigger)
- 用 gsap.context 包,return ctx.revert() cleanup
- gsap.to(target, { ...動畫, scrollTrigger: { trigger, start: 'top top', end: '+=600', pin: true, scrub: 0.5 } })
- scrub 給數字(0.3~0.8)比 true 更自然,會有微微緩衝
- end 用 '+=px' 而不是寫死位置

限制:
- 父層別有 overflow: hidden(會破壞 pin)
- 一個頁面 pin 區塊 < 3 個(否則跟使用者打架)
- mobile 改 scrub: true(少一個小數值平滑,反而更穩)

完整程式碼

PinSectionScrub.tsx
'use client'

import gsap from 'gsap'
import { ScrollTrigger } from 'gsap/ScrollTrigger'
import { useEffect, useRef } from 'react'

export function PinSectionScrub() {
const ref = useRef<HTMLDivElement>(null)

useEffect(() => {
  gsap.registerPlugin(ScrollTrigger)
  const ctx = gsap.context(() => {
    gsap.to('.target', {
      rotate: 90,
      scale: 1.3,
      ease: 'none',
      scrollTrigger: {
        trigger: ref.current,
        start: 'top top',
        end: '+=600',
        pin: true,
        scrub: 0.5,
      },
    })
  }, ref)
  return () => ctx.revert()
}, [])

return (
  <section ref={ref} className="h-screen">
    <div className="target h-32 w-32 bg-orange-600" />
  </section>
)
}

何時用

  • ✅ 產品 walkthrough(每滾一段釋出一個 feature)
  • ✅ 案例 reveal(圖被釘住,文字滾過)
  • ✅ Long-form scrollytelling

何時別用

  • ❌ 純文字內容站(破壞閱讀節奏)
  • ❌ 一頁多個 pin(互相干擾)
  • ❌ 父層 overflow-hidden 或 transform 的容器內

我踩過的坑

  1. 沒 ctx.revert() 切頁殘留:ScrollTrigger 會留在 document 上。 一定要用 gsap.context() + ctx.revert()

  2. scrub: true 太敏感:滾動每一格立即同步,看起來抖。改成 scrub: 0.3~0.8 數字模式,有微緩衝更舒服。

  3. end 寫死位置遲早出問題:響應式高度會變。用 '+=600' 相對距離 比較穩。

相關效果

搜尋

按 ⌘K 隨時開啟