Loading...

使用 GSAP 和 ScrollTrigger 實現RWD的動態效果

隨著時代的演進,PM對於網頁特效的要求越來越高了。最近PM提出需要把使用者卡在頁面某個地方,隨滾動進度把動畫看完才放行的效果。於是我想到可以使用GSAP的scrolltrigger來達成。

更新於 2025-03-05 08:53:24
Written by   Jacky Yang@Jacky Yang

隨著時代的演進,PM對於網頁特效的要求越來越高了。最近PM提出需要把使用者卡在頁面某個地方,隨滾動進度把動畫看完才放行的效果。於是我想到可以使用GSAP的scrolltrigger來達成。

範例頁面: AFL4-W133-ADLP 的 Durable Aluminum Die Casting Housing

GSAP

GSAP,全名為 GreenSock Animation Platform,是一個強大且高效的 JavaScript 動畫庫。它提供了一個簡單易用的 API,讓開發者能夠輕鬆創建和控制動畫。GSAP 支援各種不同的動畫類型,包括 CSS 屬性、SVG、DOM 屬性等等。

ScrollTrigger

ScrollTrigger 是 GSAP (GreenSock Animation Platform) 的一個插件,它允許你在滾動頁面時觸發動畫。你可以在滾動到特定的元素或者特定的位置時開始、停止、暫停、恢復、反轉或者調整動畫的速度。


引用GSAP、ScrollTrigger

依照專案性質,可使用cdn或是npm的方式

npm

npm install gsap

註冊GSAP、ScrollTrigger

// index.js
import { gsap } from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
gsap.registerPlugin(ScrollTrigger);

CDN

<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.4/gsap.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.4/ScrollTrigger.min.js"></script> 

註冊GSAP、ScrollTrigger

// index.js
gsap.registerPlugin(ScrollTrigger);

建立TimeLine

GSAP Timeline 用於創建和管理動畫序列。你可以使用它來控制多個動畫的播放順序,包括同時播放、順序播放、延遲播放等。

可以直接在timeline中設定scrolltrigger的邏輯。整體播放的速度取決於scrub、end、以及fromTo function 設定的duration值,基本上end的值越大,動畫的duration就會越久。

let tl = gsap.timeline({
    scrollTrigger: {
        trigger: ".sec-6", // 滾動到 .sec-6 時觸發
        pin: true, // 釘選元素
        scrub: 0.9, // 動畫的速度,數字越大越慢
        start: "top top", // 當 .sec-6 的 top 與 viewport 的 top 對齊時觸發
        end: "+=350%", // 滑動到 .sec-6 的 下方 350% 時觸發
    },
});

ScrollTrigger 動畫邏輯

prodStartPos、prodEndPos 是元素的起始位置,為了RWD而將此參數獨立出來,在不同斷點調整起始位置。

fromTo 則是設定目標元素的起始(from)、結束(to)樣式。

"<" 代表跟上一個Tween(fromTo function)同步執行,如果沒有設定則是按照Tween的連鎖接續執行動畫

const sec6Animation = (prodStartPos,prodEndPos) => {
    tl.fromTo('.sec-6 .title',{
        yPercent: 50
    },{
        yPercent: 0
    })
    .fromTo('.sec-6 .prod',{
        yPercent: prodStartPos,
        opacity: 0,
        scale: 1.5,
    },{
        yPercent: prodEndPos,
        opacity: 1,
        scale: 1,
    },'<')
    .fromTo('.sec-6 .icons', {
        opacity: 0,
        yPercent: 30,
        duration: 3
    },{
        opacity: 1,
        yPercent: 0,
        
    })
}


RWD調整元素的起始位置

gsap允許我們客製自己的斷點來執行不同的動畫邏輯

let mm = gsap.matchMedia();
const RWDConfig = {
    isMobile: `(max-width: 767px)`,
    isTablet: `(min-width: 768px) and (max-width: 991px)`,
    isLaptop: `(min-width: 992px) and (max-width: 1199px)`,
    isPc: `(min-width: 1200px)`
}
mm.add(RWDConfig,(context) => {
    let { isMobile, isTablet, isLaptop, isPc } = context.conditions; // 取得RWDConfig

    // 因應不同斷點調整產品的起始位置
    if(isMobile) {
        sec6Animation(-350, -20);
    } else if(isTablet) {
        sec6Animation(-200, 100);
    } else if(isLaptop) {
        sec6Animation(-150, 100);
    } else if(isPc) {
        sec6Animation(-150, 45);
    }
})