iT邦幫忙

2025 iThome 鐵人賽

DAY 25
0
自我挑戰組

請問這是魔法嗎?前端轉職菜雞的修煉之路!系列 第 25

DAY 25 招喚滾動的魔法卷軸 - GSAP - ScrollTrigger

  • 分享至 

  • xImage
  •  

連續講了五天的鬼故事後,今天打開電腦,腦袋還是空空的,感覺去年的這些事還歷歷在目,簡直 PTSD...

在前幾篇文章中,提到有陣子我一直在忙前公司承接的案子。這一開始是由一位前同事開發,直到他要離職,才交接給我,而當時只剩下其中一個頁面需要我接手。我稍微了解一下專案內部之後,不得不稱讚這位前同事寫得好乾淨,首頁更是炫的不得了!是一台 3D 太空船模型,搭配背景的空間模型,藉由 GSAP 的 ScrollTrigger,讓使用者滾動頁面時,觸發播放兩個模型的 glb 檔中的動畫,看起來真的就像有一台太空船在瀏覽器中飛翔一樣!

今天就來簡單介紹 GSAP (GreenSock Animation Platform)~它是一個非常強大的 JavaScript 動畫函式庫,很適合用來製作複雜、精確且流暢的網頁動畫,裏面供許多的 API 可以讓程式碼既乾淨又能達到需求。

其中,ScrollTrigger 是 GSAP 最受歡迎的插件之一,可以讓你在「畫面捲動到某個位置」時觸發或控制 GSAP 動畫,也就是,它主要是依靠「位置」來觸發動畫。來簡單介紹一下如何使用吧:

  1. 招喚滾動的魔法卷軸第一步:安裝

    npm install gsap @gsap/react
    
  2. 招喚滾動的魔法卷軸第二步:匯入與註冊
    GSAP 的外掛必須手動註冊才能使用

    import { gsap } from "gsap";
    import { ScrollTrigger } from "gsap/ScrollTrigger";
    import { useGSAP } from "@gsap/react";
    
    gsap.registerPlugin(ScrollTrigger);
    
  3. 招喚滾動的魔法卷軸第三步:建立滾動
    範例:當使用者往下滾動到 .box 時,它會從左側滑入並旋轉

    "use client";
    
    import { useRef } from "react";
    import { gsap } from "gsap";
    import { ScrollTrigger } from "gsap/ScrollTrigger";
    import { useGSAP } from "@gsap/react";
    
    gsap.registerPlugin(ScrollTrigger);
    
    export default function App() {
      const boxRef = useRef(null);
    
      // useGSAP 會在組件掛載後執行動畫
      useGSAP(() => {
        gsap.to(boxRef.current, {
          x: 300, // 往右移動 300px
          rotation: 360, // 順時針旋轉 360 度
          duration: 2, // 動畫持續 2 秒
          scrollTrigger: {
            trigger: boxRef.current, // 觸發元素
            start: "top 80%", // 元素頂端到視窗 80% 時觸發
            end: "bottom 20%", // 元素底端到達視窗 20% 時結束
            scrub: true, // 動畫隨滾動進度移動
            markers: true, // 顯示輔助線(開發時可開啟true)
          },
        });
      }, []);
    
      return (
        <div className="h-[200vh] flex items-center justify-center">
          <div ref={boxRef} className="w-20 h-20 bg-blue-500"></div>
        </div>
      );
    }
    
    

    這個只是單一元素的動畫,如果有多個元素要依序動畫,可以搭配 Timeline 來做:

    "use client";
    
    import { useRef } from "react";
    import { gsap } from "gsap";
    import { ScrollTrigger } from "gsap/ScrollTrigger";
    import { useGSAP } from "@gsap/react";
    
    gsap.registerPlugin(ScrollTrigger);
    
    export default function App() {
      const sectionRef = useRef<HTMLDivElement>(null);
    
      useGSAP(() => {
        const tl = gsap.timeline({
          scrollTrigger: {
            trigger: sectionRef.current,
            start: "top 80%",
            end: "bottom 20%",
            scrub: 1,
            markers: true,
          },
        });
    
        // 定義時間軸動畫
         tl.to(".title", { opacity: 1, y: -30, duration: 1 })
          .to(".image", { scale: 1.2, duration: 1 })
          .to(".text", { x: 100, opacity: 1, duration: 1 });
      }, []);
    
      return (
        <div className="h-[200vh] bg-gray-100">
          {/* 用來讓畫面可滾動的空白區塊 */}
          <div className="h-[100vh] flex items-center justify-center text-gray-400">
            <p>往下滾動開始動畫</p>
          </div>
    
       {/* 主要動畫區域 */}
          <section ref={sectionRef} className="section flex flex-col items-center justify-center h-[100vh] bg-white rounded-2xl shadow-lg mx-auto w-3/4 p-10">
            <h2 className="title opacity-0 text-4xl font-bold mb-6">
              滾動觸發動畫
            </h2>
    
            <img
              src="https://placekitten.com/300/200"
              alt="kitten"
              className="image w-60 h-40 object-cover rounded-lg mb-6"
            />
    
            <p className="text opacity-0 text-lg text-gray-700 max-w-md text-center">
              當你往下滾動時,文字、圖片與標題會依序出現。
              <br />
              這是 ScrollTrigger + Timeline 的範例。
            </p>
          </section>
    
          {/* 增加底部空間讓滾動自然結束 */}
          <div className="h-[100vh]"></div>
         </div>
      );
    }
    

上一篇
DAY 24 蠶食鯨吞耐心的黑魔法 - 職場鬼故事 (5) - 主詞搞錯了、門要不要先鎖一下
系列文
請問這是魔法嗎?前端轉職菜雞的修煉之路!25
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言