iT邦幫忙

2024 iThome 鐵人賽

DAY 13
0
Modern Web

創意前端設計:用 Vue.js 打造 30 個互動實用功能系列 第 13

Day13 Vue.js 動效分類實戰 (5) 視差滾動特輯 - 用 GSAP 編織日夜交替的視覺詩歌

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20240927/20124462ybcPbcARkZ.jpg


讓畫面隨時光流動,用動效打造日與夜的邂逅!

哈囉大家!今天我們要來點浪漫的~🌙☀️
當我們說到網頁動效,你是不是也曾幻想過,能不能讓畫面隨著時間的流動變換出日夜交替的詩意感覺呢?

今天就要帶大家走進這個魔幻的世界!
透過 Vue.js 和 GSAP 的強大組合,我們不僅能創造出美麗的滾動視差效果,還能讓太陽和月亮在你的頁面上翩翩起舞~✨

想像一下,當你向下滾動頁面,白天漸漸變成夜晚,星星悄悄點亮,還有鳥在飛,這樣的視覺體驗是不是超級夢幻?
這不僅僅是動效的疊加,更是一場日夜相遇的浪漫之旅。

今天就讓我們一起來學習,如何用 GSAP 編織出這場時間的詩歌,讓你的網頁瞬間氣氛起來吧!🌌🚀


img


視差滾動的魅力

視差滾動(Parallax Scrolling)是一種在網頁設計中廣受歡迎的技術,它透過讓背景和前景元素以不同的速度移動,創造出一種深度感和層次感,彷彿頁面在動起來的同時,也讓你置身於一個立體的視覺世界。

當使用者滾動頁面時,這種技術就像是帶領他們進行一場動態的時空之旅,瞬間讓畫面變得栩栩如生。

視差滾動的魅力不僅在於其視覺效果,還能增強網站的互動性和趣味性與減少跳出率。
它能引導視線,強調內容重點,讓訪客不自覺地被畫面吸引,享受在虛實之間穿梭的奇妙體驗。

從展現產品故事到打造沉浸式品牌體驗,視差滾動已成為許多高端網站不可或缺的設計元素。
這種富有動感的技術,使得網頁設計不再只是平面的呈現,而是打破時空的視覺藝術,為使用者帶來一場絕佳的視覺盛宴!


設計思維與視覺策略

設計日夜交替的視差滾動效果是一場充滿浪漫與戲劇性的創作過程。
這樣的設計靈感源自於日夜之間的自然變換,將白天的光亮和夜晚的靜謐融入到網頁中,讓使用者不僅僅是在瀏覽內容,而是在感受時間的流動與變換。

1. 日夜交替的設計靈感

日與夜是大自然最美的對比:白天充滿活力和希望,夜晚則神秘而寧靜。

2. 視覺化轉換:色彩與光影的魔法

  • 色彩選擇:白天用溫暖的藍色、黃色來模擬日光,充滿陽光的感覺;夜晚則換上深藍和紫色,點綴著星光與月光,瞬間變得神秘又迷人!

  • 光影切換:白天柔和的光線和輕盈的陰影營造明亮的感覺;而夜晚則讓光影逐漸變暗,星光閃爍,讓畫面過渡得自然又不失戲劇性。

  • 層次安排:元素要分層呈現,遠近景、雲層、太陽和月亮的位置都精心安排,不同速度的移動更能強化視覺的深度感,帶來身臨其境的效果!

3. 技術程式面的核心實現

  • GSAP 動效控制:GSAP 作為核心動效工具,負責背景和元素的切換與移動。

    • 它通過時間軸控制動效的順序和節奏,例如將背景從白天的色調逐漸轉變為夜晚,並同步移動太陽和月亮的位置,使日夜交替的過程流暢自然。
    • GSAP 的緩動效果讓畫面切換不會過於生硬,增添了動效的柔和度和連續性。
  • ScrollTrigger 整合:ScrollTrigger 這個 GSAP 插件使得動效可以與頁面的滾動互動,成為實現視差滾動的關鍵。

  • 通過設置觸發器,動效的播放與頁面的滾動緊密結合,實現如日夜切換般的效果,將使用者的操作與視覺變化直接連接。

  • 層次移動速度的控制:視差效果的精髓在於不同層次的元素以不同速度移動,例如背景的移動速度較慢,而前景元素則稍快,這樣的速度差異由 GSAP 精確控制,使得滾動視差效果立體且富有深度。


GSAP 與 Vue.js 的強強聯手

  • 技術實作心法

    • 步驟 1:設置場景 - 定義 template 結構,為日夜視差效果創建合適的基礎佈局。
    • 步驟 2:GSAP 動效設定 - 用 GSAP 設置滾動觸發器、動效控制時間軸,讓日夜效果隨滾動流暢切換。
    • 步驟 3:優化視覺體驗 - 加入細節動效,如背景的漸變、星星閃爍、太陽和月亮的移動等,讓視差效果更生動。
  • 完整程式碼的Github

視差滾動的核心動效實作

我們今天利用 Vue.js 與 GSAP 的 ScrollTrigger 插件,實現了豐富的視差滾動效果。
GSAP (GreenSock Animation Platform) 的參數配置是用來控制動效的細節與行為,每個參數都有其特定的用途,用於調整動效的執行方式。
以下將逐步解析各片段程式碼,說明每個動效的作用對象與效果,並解釋它們在捲動過程中的行為:

1. GSAP Timeline 和 ScrollTrigger

GSAP 的 timeline() 用於創建一系列順序或同時發生的動效,而 ScrollTrigger 是用來將滾動事件與動效進行同步。

gsap.timeline()

  • 說明:創建一個動效時間軸,可以將多個動效串聯在一起,按指定時間點或順序執行。
  • 效果:使多個動效按時間或觸發順序進行播放,為場景增添複雜動態效果。

2. ScrollTrigger 參數設定

ScrollTrigger.create({
    animation: scene1,
    trigger: ".scrollElement",
    start: "top top",
    end: "45% 100%",
    scrub: 3,
});
  • animation:指定與滾動綁定的動效,這裡使用的是 scene1,即該場景的動效序列。
  • trigger:滾動觸發的元素,通常為包覆動效的捲動區塊,例如 .scrollElement
  • start:設定動效開始的位置,格式為 "觸發點的位置 觸發區域的位置"。例如,"top top" 表示當 .scrollElement 的頂部到達視窗頂部時觸發。
  • end:設定動效結束的位置。例如,"45% 100%" 表示當 .scrollElement 的 45% 高度與視窗的底部對齊時結束。
  • scrub:控制動效的滾動同步程度。數值越高,動效執行的速度會與滾動更為同步,例如 scrub: 3 會使動效緩慢而平滑地與滾動同步。

3. 動效方法與屬性設定

to()fromTo()

這兩種方法是用來設定動效的初始與結束狀態:

  1. to() 方法
    • 用法gsap.to(element, { properties }, position)
    • 說明:將指定元素的屬性從當前狀態動效至目標狀態。
    • 例子scene1.to("#h1-1", { y: 3 * speed, x: 1 * speed, scale: 0.9, ease: "power1.in" }, 0);
    • 效果
      • y: 3 * speed:控制物件在垂直方向上的移動距離,這裡是向下移動。
      • x: 1 * speed:控制物件在水平方向上的移動距離。
      • scale: 0.9:縮放物件,0.9 表示縮小到 90%。
      • ease: "power1.in":設定緩動效果,使動效開始時比較平緩,然後加速進入狀態。
  2. fromTo() 方法
    • 用法gsap.fromTo(element, { fromProperties }, { toProperties }, position)
    • 說明:從指定的初始狀態轉換到目標狀態。
    • 例子scene2.fromTo("#h2-1", { y: 500, opacity: 0 }, { y: 0, opacity: 1 }, 0);
    • 效果
      • { y: 500, opacity: 0 }:初始狀態,物件在下方 (500 像素) 並且不可見。
      • { y: 0, opacity: 1 }:目標狀態,物件移動到其原始位置並完全顯現。
      • 位置0 代表動效的起始點在時間軸的第 0 秒。

4. 緩動效果 (ease)

  • ease:指定動效的緩動方式,控制動效的速度變化曲線。
    • power1.in:動效由慢到快。
    • power2.out:動效由快到慢。
    • power3.out:更強的加速和減速效果。
  • 效果:使動效看起來更自然或符合物理效果,而非線性運動。

5. 動效同步與反應 (onEnteronLeave)

  • onEnter:當觸發點進入視窗時執行的動作。
  • onLeave:當觸發點離開視窗時執行的動作。
  • 效果:增加互動性,如鳥飛入畫面後改變方向 (scaleX: 1) 或飛出畫面 (scaleX: -1),旋轉並模擬自然飛行行為。

動效場景設計實作

1. Scene 1:場景一的動效設定

const setupScene1 = () => {
    const scene1 = gsap.timeline();
    ScrollTrigger.create({
        animation: scene1,
        trigger: ".scrollElement",
        start: "top top",
        end: "45% 100%",
        scrub: 3,
    });
    // Hills animation
    scene1.to("#h1-1", { y: 3 * speed, x: 1 * speed, scale: 0.9, ease: "power1.in" }, 0);
    scene1.to("#h1-2", { y: 2.6 * speed, x: -0.6 * speed, ease: "power1.in" }, 0);
    scene1.to("#h1-3", { y: 1.7 * speed, x: 1.2 * speed }, 0.03);
    scene1.to("#h1-4", { y: 3 * speed, x: 1 * speed }, 0.03);
    scene1.to("#h1-5", { y: 2 * speed, x: 1 * speed }, 0.03);
    scene1.to("#h1-6", { y: 2.3 * speed, x: -2.5 * speed }, 0);
    scene1.to("#h1-7", { y: 5 * speed, x: 1.6 * speed }, 0);
    scene1.to("#h1-8", { y: 3.5 * speed, x: 0.2 * speed }, 0);
    scene1.to("#h1-9", { y: 3.5 * speed, x: -0.2 * speed }, 0);

    // Animate text
    scene1.to("#info", { y: 8 * speed }, 0);
};

說明:

  • 物件#h1-1#h1-9 代表不同的山丘元素,#info 是文字元素。
  • 效果:山丘隨滾動向上下或左右移動並縮放,營造視差效果。文字 (#info) 向下移動。
  • 執行過程:當使用者滾動到 .scrollElement,動效開始,startend 決定動效開始和結束的位置,scrub 控制動效與滾動同步的力度。

2. Bird Animation:鳥的動效設定

const setupBirdAnimation = () => {
    gsap.fromTo(
        "#bird",
        { opacity: 1 },
        {
            y: -250,
            x: 800,
            ease: "power2.out",
            scrollTrigger: {
                trigger: ".scrollElement",
                start: "15% top",
                end: "60% 100%",
                scrub: 4,
                onEnter: () => gsap.to("#bird", { scaleX: 1, rotation: 0 }),
                onLeave: () => gsap.to("#bird", { scaleX: -1, rotation: -15 }),
            },
        }
    );
};

說明:

  • 物件#bird 代表飛鳥元素。
  • 效果:鳥從螢幕外飛入,隨滾動向右移動,進入時旋轉調整方向。
  • 執行過程:當滾動到指定位置時,onEnteronLeave 控制鳥的轉向與旋轉,營造鳥在飛行中的動態感。

3. Clouds Animation:雲的動效設定

const setupClouds = () => {
    const clouds = gsap.timeline();
    ScrollTrigger.create({
        animation: clouds,
        trigger: ".scrollElement",
        start: "top top",
        end: "70% 100%",
        scrub: 1,
    });

    clouds.to("#cloud1", { x: 500 }, 0);
    clouds.to("#cloud2", { x: 1000 }, 0);
    clouds.to("#cloud3", { x: -1000 }, 0);
    clouds.to("#cloud4", { x: -700, y: 25 }, 0);
};

說明:

  • 物件#cloud1#cloud4 代表不同的雲朵。
  • 效果:雲朵隨滾動往左右方向移動,模擬自然的雲層漂移。
  • 執行過程:隨著滾動進行,雲朵平移出畫面,產生背景景深和移動的感覺。

4. Sun Motion:太陽的動效設定

const setupSun = () => {
    const sun = gsap.timeline();
    ScrollTrigger.create({
        animation: sun,
        trigger: ".scrollElement",
        start: "top top",
        end: "2200 100%",
        scrub: 1,
    });

    sun.to("#bg_grad", { attr: { cy: "330" } }, 0);
    sun.to("#sun", { attr: { offset: "0.15" } }, 0);
    sun.to("#bg_grad stop:nth-child(2)", { attr: { offset: "0.15" } }, 0);
    sun.to("#bg_grad stop:nth-child(3)", { attr: { offset: "0.18" } }, 0);
    sun.to("#bg_grad stop:nth-child(4)", { attr: { offset: "0.25" } }, 0);
    sun.to("#bg_grad stop:nth-child(5)", { attr: { offset: "0.46" } }, 0);
    sun.to("#bg_grad stop:nth-child(6)", { attr: { "stop-color": "#FF9171" } }, 0);
};

說明:

  • 物件#sun 和背景漸層 #bg_grad,控制日落效果。
  • 效果:太陽逐漸移動並改變顏色,模擬日落的過程。
  • 執行過程:捲動觸發動效,太陽位置和背景色變換,從明亮漸變至日落的橙紅色調。

5. Scene 3:第三場景過渡動效設定

const setScene3 = () => {
    // Scene Transition Animation Setup
    gsap.set("#scene3", { y: 580, visibility: "visible" });
    const sceneTransition = gsap.timeline();
    ScrollTrigger.create({
        animation: sceneTransition,
        trigger: ".scrollElement",
        start: "70% top",
        end: "bottom 100%",
        scrub: 3,
    });

    sceneTransition.to("#h2-1", { y: -680, scale: 1.5, transformOrigin: "50% 50%" }, 0);
    sceneTransition.to("#bg_grad", { attr: { cy: "-80" } }, 0);
    sceneTransition.to("#bg2", { y: 0 }, 0);
};

說明:

  • 物件#h2-1 是場景的元素,#bg_grad 控制背景漸層,#bg2 代表新背景。
  • 效果:元素移動和縮放,場景過渡至第三場景,背景改變位置,展現不同的視覺效果。
  • 執行過程:滾動至相應區域,啟動場景變化,元素的位移和縮放使場景之間的切換更為流暢。

結語

每個小小的動畫參數設定,就像是為畫面注入魔法的咒語,讓靜止的圖像變得靈動而有趣。
在這裡,程式不再只是冷冰冰的程式碼,而是承載創意的橋梁。

相信自己,哪怕是看似簡單的動畫效果,也能在細節的雕琢中發光發熱。

無論你是剛踏入前端世界的菜鳥,還是經驗豐富的老手,永遠記得編寫程式就像創作藝術一樣,隨著每一次的嘗試與探索,世界也將變得更加精彩。

加油,勇敢嘗試那些看似不可能的事吧,因為你永遠不知道下一行程式碼會帶給你什麼樣的驚喜!✨


上一篇
Day12 Vue.js 動效分類實戰 (4) 導航特輯 - 用 GSAP 打造超爆棚品牌感設計
下一篇
Day14 Vue.js 動效分類實戰 (6) 視覺炫彩特輯 - 元件化你的動態炫彩文字與按鈕
系列文
創意前端設計:用 Vue.js 打造 30 個互動實用功能30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言