大家好,我是 Eric。
昨天介紹了在 WordPress 中加入 Animation on Scroll 的效果,並說明如何用 wp_enqueueu_scripts
在自己的 WordPress 網站中引入 JavaScript 函式庫。今天,我們要再來介紹另一款與動畫有關的函式庫:GSAP。
相較於昨天介紹的 AOS,是根據瀏覽器的捲動事件觸發動畫事件。GSAP 使用了「時間軸」的概念。對於繪製動畫,或是有剪輯影片經驗的人來說,時間軸有助於掌握動畫節奏。
除了時間軸以外,GSAP 也同時可以透過附加的外掛,來選擇特殊的 DOM 元素,例如虛擬元素。
和昨天一樣,我們先透過 wp_enqueue_scripts
的方式引用 GSAP。
function eric_enqueue_gsap(){
wp_enqueue_script( 'gsap', 'https://cdnjs.cloudflare.com/ajax/libs/gsap/3.5.1/gsap.min.js' );
wp_enqueue_script( 'gsap-set', '儲存路徑/gsap-set.js' );
/** 這個檔案主要是用來存放接下來提到的時間軸 */
}
add_action( 'wp_enqueue_scripts', 'eric_enqueue_gsap' );
GSAP 的基本語法如下:
var tl = new TimelineMax(); // 建立一條新的時間軸
tl.to( '選擇器', {duration: 秒數, 樣式屬性: 屬性值})
.to( '選擇器', 動畫持續秒數, {樣式屬性: 屬性值, 樣式屬性 2: 屬性值 2})
.to( '選擇器', 動畫持續秒數, {樣式屬性: 屬性值, 樣式屬性 2: 屬性值 2}, "時間延遲";
/* 2020/10/08 更新
* 從 GSAP 3.0 開始,官方建議改用 var tl = gsap.timeline(); 的方式建立時間軸,
* 並表示從 GSAP 4 以後,將會廢除 TimelineMax() 的方法。
*/
這邊簡單介紹一下上面語法中可以使用的屬性值:
名稱 | 說明
-------+-------
選擇器 | CSS 選擇器,無法選擇虛擬元素。
duration | 必須是數字秒數。
樣式屬性 | CSS 樣式,如果遇到像是 background-color
這種有 -
符號的屬性,則要用 backgroundColor 這種方式來表示。
時間延遲 | 預設是 0,代表前一個動畫結束後,立刻接續下一個動畫。如果是 "-=1",則是在前一動畫結束前 1 秒鐘,接續下一個動畫。
repeat | 重複次數,如果填 1,則代表除了原本第一次外,會「再」重複 1 次。
透過這個函式庫,我們可以先做出下列的動畫:
<style>
#animation1 {
opacity: 0;
}
</style>
<div id="animation1">
<p id="obj1">這是第一段</p>
</div>
<script>
var tl1 = new TimelineMax(); //建立一條新的時間軸
tl1.to("#animation1", {duration: 0.5,opacity:1,repeat:10});
//讓 #animation1 從原本不透明度 0,在 0.5 秒內變成 1,額外重複 10 次
</script>
透過 new TimelineMax();
,我們可以建立不只一條時間軸。
<div id="animation1">
<p id="obj1">這是第一段</p>
</div>
<div id="animation2">
<p id="obj2">這是第二段</p>
</div>
<script>
var tl1 = new TimelineMax();
tl1.to("#animation1", {duration: 0.5,opacity:1,repeat:10});
var tl2 = new TimelineMax();
tl2.to("#animation1", 5, {
color: "#ff02a8"
}, "-=1")
.to("#animation2", 1, {
color: "blue"
})
.to("#animation2", 1, {
backgroundColor: "#aaaa00",
padding: "10px"
})
.to("#obj2", 0.5, {
backgroundColor: "#fff",
width: "30%"
}, "-=1");
</script>
我們在第二條時間軸製作了比較多的設定,但是基本上我們還是能將兩條時間軸合併起來。除非我們要分別控制:
<button id="trigger-animation1">動畫 1 暫停</button>
<button id="trigger-animation2">動畫 2 暫停</button> <br />
<button id="resume-animation1">動畫 1 繼續</button>
<button id="resume-animation2">動畫 2 繼續</button>
<button id="reset">Restart</button>
<script>
$("#trigger-animation1").on("click",function(){
tl1.pause();
});
$("#trigger2").on("click",function(){
tl2.pause();
});
$("#resume-animation1").on("click",function(){
tl1.resume();
});
$("#resume-animation2").on("click",function(){
tl2.resume();
});
$("#reset").on("click",function(){
tl1.restart();
tl2.restart();
});
</script>
透過上面的作法,我們可以監聽點擊按鈕的事件,來個別控制時間軸。
這個 CodePen 中,包含了上述各個案例實做出來的樣貌,作為參考。
藉由 GSAP,我們可以為自己的網站加入預載動畫 (preload animation),可以參考這個 CodePen 或是直接體驗我們公司網站的效果。
<!-- 這邊是預載動畫的圖層 -->
<div id="preload">
<div id="logo_preload">
<div id="mask"></div>
</div>
<div id="bars">
<div class="bar" id="bar1"></div>
<div class="bar" id="bar2"></div>
<div class="bar" id="bar3"></div>
<div class="bar" id="bar4"></div>
<div class="bar" id="bar5"></div>
</div>
</div>
<!-- 以下是網站實際內容 --->
<div>
<header id="masthead" class="site-header"><div class="site-branding">
<a href="https://www.applemint.tech/">
<img src="https://www.applemint.tech/wp-content/themes/applemint/assets/applemint-logo.png" srcset="" alt="Website Logo" scale="0">
</a></div></header>
</div>
#preload {
position: fixed;
background-color: #fff;
width: 100%;
height: 100%;
top: 0;
left: 0;
}
#preload #logo_preload {
position: absolute;
width: 300px;
height: 300px;
top: 50%;
transform: translate(-50%, -50%);
left: 50%;
background-image: url("https://www.applemint.tech/wp-content/themes/applemint/assets/favicon25.svg");
background-repeat: no-repeat;
background-position: center;
}
#preload #logo_preload #mask {
position: absolute;
background: #fff;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
#preload #bars {
position: absolute;
z-index: 20;
width: 100%;
height: 100%;
opacity: 0;
}
#preload #bars .bar {
height: 20vh;
background: #00bbcc;
position: absolute;
width: 100%;
right: 0;
}
#preload #bars #bar1 {
top: 0%;
}
#preload #bars #bar2 {
top: 20%;
}
#preload #bars #bar3 {
top: 40%;
}
#preload #bars #bar4 {
top: 60%;
}
#preload #bars #bar5 {
top: 80%;
}
.site-header {
background-color: #fff;
display: flex;
height: 87px;
width: 100%;
align-items: center;
-ms-align-items: center;
z-index: 998;
}
/** 這段是參考這個 CodePen https://codepen.io/ahsanrathore/pen/MwppEB,主要的功能在估算頁面需要載入的時間 */
var height = 100, // height of a progress bar in percentage
perfData = window.performance.timing, // The PerformanceTiming interface
EstimatedTime = -(perfData.loadEventEnd - perfData.navigationStart), // Calculated Estimated Time of Page Load which returns negative value.
time = parseInt((EstimatedTime/1000)%60)*100; //Converting EstimatedTime from miliseconds to seconds.
/** 用 jQuery 來製作預載動畫顯示 logo 的效果 */
$("#mask").animate({
height: 100-height+"%",
}, time);
/** 在前面的動畫載入完畢後,接續製作水平長條的動畫 */
var tl = new TimelineMax();
setTimeout(function(){
// gasp.to("#bar1", );
tl.to("#logo_preload", {duration: 0.3,opacity:0})
.to("#bars", {duration:0.3,opacity:1}, "-=0.2")
.to("#bar1", {duration:0.3,width:0}, "-=0.1")
.to("#bar2", {duration:0.3,width:0}, "-=0.1")
.to("#bar3", {duration:0.3,width:0}, "-=0.1")
.to("#bar4", {duration:0.3,width:0}, "-=0.1")
.to("#bar5", {duration:0.3,width:0}, "-=0.1")
.to("#preload", {duration: 0.3, height:0});
}, time);
雖然物件導向本身就可以成為一次鐵人賽的主題,但我們這邊只針對 WordPress 與 JavaScript 所涉及的部分稍做簡介。
儘管物件導向聽起來很抽象,但我們平常在分類身邊周遭事物時,很自然的都會用上物件導向的觀念,譬如動物的分類,可以化簡為下面的語法:
function 動物( type, feet, specie) {
this.類型 = type;
this.腳數 = feet;
this.品種 = specie;
}
var 烏龜 = new 動物( '爬蟲類', 4, '綠蠵龜' );
烏龜['類型']; //回傳「爬蟲類」
其中 new
的意思,代表著我要把原本「動物」抽象的概念,實體化成一個真正的物體「烏龜」。除了烏龜以外,我們也可以重複創造新的動物,譬如 var 帝雉 = new 動物( '鳥類', 2, '台灣帝雉' );
。
今天之所以帶到物件導向的話題,是為了說明在 GSAP 中,new TimelineMax();
這個過程的意義。至於物件導向中的其他觀念,如「繼承」,則不在這次所要涵蓋的範圍中。
今天的主題和 WordPress 的直接關係比較少,主要仍是在介紹如何透過 GSAP 這款函式庫,使用時間軸來安排網頁動畫。事實上,WordPress 有許多頁面編輯器 (page builder) 外掛,替網站加入不同的動態效果,如 Elementor、Divi 與 Avada 等。
除了介紹 GSAP 的實作方法外,我們也藉此了解物件導向的基本概念。我們在後續篇章的例子中,繼續了解如何藉由將物件實體化,更加活用不同的函式庫,甚至是 WordPress 的核心功能。
下一章,我們將會介紹許多業主、客戶很喜歡的函式庫:投影片輪播 (sliders)。
Tips for Writing Animation Code Efficiently
GSAP 官方說明文件
GSAP 速查表