Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
原本我是透過 AOS 這款 JavaScript 函式庫製作頁面捲動的動畫 (animation on scroll),但這次公司網站改版,需要較複雜的動畫,因此必須改用 GSAP 來製作更進階的捲動動畫。
首先,先分享實作結果,這是透過 ScrollTrigger 外掛,搭配 GSAP 中變更數值的方式,製作的數字跳動動畫。
See the Pen GSAP Integer Animation by Eric Chuang (@eric-chuang) on CodePen.
內容目錄
ScrollTrigger 的基本語法如下:
/* 除了需要在 <head> 中引入 JavaScript 資源外,須在 JavaScript 中註冊外掛 */ gsap.registerPlugin(ScrollTrigger); gsap.to("動畫物件選擇器", { scrollTrigger: "觸發選擇器", x: 500 // 向右移動 500px });
scrollTrigger
這個屬性的屬性值,除了觸發條件的選擇器外,也可以用物件的方式來設定觸發條件。
gsap.to( "動畫物件選擇器",{ scrollTrigger: { trigger: "觸發選擇器", pin: true, // 當動畫執行中的時候,讓觸發選擇器置頂 start: "top top", // 當觸發選擇器的頂端 (左邊的 top) 碰到檢視區頂端 (右邊的 top) 時啟用 end: "+=500", // 捲動 500px 後結束動畫 scrub: 1, // 是否根據捲動程度決定動畫完成程度, // 如果填寫數字,則在會延遲 n 秒後才到定位。 snap: { // 貼齊效果 snapTo: "labels", // 貼齊最近的標籤,須搭配 addLabel 方法 duration: { min: 0.2, max: 3 }, // 貼齊動畫須慢於 0.2 秒,不超過 3 秒 delay: 0.2, // 捲動完畢後延遲 0.2 秒才會執行貼齊動畫 ease: "power1.inOut" // 動畫加減速,預設是 power3 } } } );
用 GSAP 來製作動畫的基本觀念,是變更「CSS 樣式屬性值」。
但其實不只 CSS 屬性值,一般的數值也可以用 GSAP 來控制,並用來製作計數器。這次實作參考的 Codepen 如下:
See the Pen Tweenmax Integer Tween by Nicolaj Lund Hummel (@nicolund) on CodePen.
首先,範例中先給了 counter
這個物件中的 var
屬性一個預設值 0。
接著,透過補間 (tween) 的方式,讓 counter
這個物件的 var
屬性值,在 5 秒內從 0 變成 100。
而在數值變化的過程中,藉由 onUpdate
這個方法,讓 var
屬性值反映在 #tal
顯示的值之上。
然而,因為這個範例只有選擇 #tal
這個元素,並不是我原本預期的,可以同時變更多個元素的樣式。因此做了下列的修改:首先,把 tal 從原本的 ID 選擇器,改成用 Class 類別的選擇器,因此在標記的過程中,我們將 tal
改為 CSS 類別:
<div class="tals"> <div class="tal" data-end="10"> 0 </div> <div class="tal" data-end="20"> 0 </div> <div class="tal" data-end="30"> 0 </div> </div> <!-- 自訂 data-end 這個資料屬性,用來儲存動畫最後的數值 -->
接著定義初始值 start
。
let start = { val: 0 };
透過 gsap.utils.toArray
這個函式,搭配 forEach
,讓動畫效果可以套用到個別元素上。在這裡 trigger
需要以當前的物件 label
為選擇器,如果用 ".tal"
的方式作為選擇器,那麼只有第一個 .tal
會套用到動畫樣式。
gsap.utils.toArray( '.tal' ).forEach( function ( label ) { start.val = 0; // 這個作法的目的是歸零 start 的起始值,讓它可以重複利用 gsap.to( start, { // 這裡需要注意的是,要變化的是 start.val 的數值,而不是改變 label 的物件 duration: 1, scrollTrigger: { // 設定觸發條件 trigger: label, // 以當前的 label 作為觸發條件 toggleActions: "play none none none", // 不需要有任何回溯的效果,所以只有單向的 play start: "top center", // 當觸發選擇器的頂端碰到檢視區正中間時啟用 }, val: label.dataset.end, // 選取 data-end 資料屬性的值作為終點 onUpdate: ( function () { label.innerHTML = Math.floor( Number( start.val ) ); // 當 val 數值變更時,用 Math.floor 讓數字以整數形式呈現。 } ) } ); } );
這次因為公司網站改版的關係,更深入的學習 GSAP,更強烈的感受到這是一套強大且方便的函式庫。如果對於前端有興趣的話,這是一套非常值得投資時間學習的函式庫。