昨天我們將之前 GSAP 建立的網站拉回來還將按鈕有了功用可以在點擊的同時進入 Three.js 的世界,不過昨天的切換其實很簡單,只是把原本隱藏的畫面顯示出來,雖然是順利成功了,但總覺得少了一點「進入另一個世界」的感覺。所以今天就來把 GSAP 加進這個過程。
我的想法是點擊按鈕之後,我希望原本的文字先縮小並淡出,接著才慢慢顯示 Three.js ,這樣就不會有直接切換頁面的生硬感,而是有一個從 2D 網頁慢慢進入 3D 世界的過程。
gsap.to(".ending-content", {
scale: 0.8,
opacity: 0,幫
duration: 0.6,
ease: "power2.in"
});
這邊就是後續才顯示 Three.js。
gsap.set(threeWorld, {
display: "block"
});
gsap.to(threeWorld, {
opacity: 1,
duration: 0.8
});
既然前面的畫面有動畫,3D 物件當然也可以一起加入,先把物件縮小,等進入 Three.js 世界後,再讓它顯現出來,原本只是突然出現在畫面上的 3D 物件,現在就會從中間慢慢放大。
gsap.to(object.scale, {
x: 1,
y: 1,
z: 1,
duration: 1.2,
ease: "back.out(1.7)"
});
除了大小,也可以同時控制 rotation ,這裡讓物件一開始先轉過一個角度,再慢慢回到原本的位置。
gsap.fromTo(
object.rotation,
{
y: -Math.PI
},
{
y: 0,
duration: 1.5,
ease: "power3.out"
}
);
我們剛剛講了很多 GSAP 的動畫效果,我們要將這些全部整合在一起,讓它可以接續出現到網頁上,這時候就會用到我們學過的 Timeline,這裡是已經全部整理好的進入動畫。
enterThreeBtn.addEventListener("click", function() {
const enterTimeline = gsap.timeline();
object.scale.set(0, 0, 0);
enterTimeline
.to(".ending-content", {
scale: 0.8,
opacity: 0,
duration: 0.6,
ease: "power2.in"
})
.set(threeWorld, {
display: "block"
})
.to(threeWorld, {
opacity: 1,
duration: 0.8,
ease: "power2.inOut"
})
.to(object.scale, {
x: 1,
y: 1,
z: 1,
duration: 1.2,
ease: "back.out(1.7)"
})
.fromTo(
object.rotation,
{
y: -Math.PI
},
{
y: 0,
duration: 1.2,
ease: "power3.out"
},
"<"
);
});
"<" 代表這個動畫會和前一個動畫一起開始,物件放大的同時,也會一起旋轉。
球原本一進去就是大顆的,現在加入動畫它就會由小到大

進去都有動畫,回來也不能缺席啊!!
backBtn.addEventListener("click", function() {
const backTimeline = gsap.timeline();
backTimeline
.to(object.scale, {
x: 0,
y: 0,
z: 0,
duration: 0.5
})
.to(threeWorld, {
opacity: 0,
duration: 0.6
})
.set(threeWorld, {
display: "none"
})
.to(".ending-content", {
scale: 1,
opacity: 1,
duration: 0.6
});
});
這裡離開 Three.js 的世界中間的 3D 物件也會以縮小方式離開。
就是中間那顆紫色小小的唷。
做到這裡,我覺得 GSAP 和 Three.js 的分工開始變得更清楚了。
| Library | 負責什麼 |
|---|---|
| Three.js | 3D 場景、物件、材質、燈光、Camera |
| GSAP | 什麼時候出現、怎麼進場、怎麼旋轉、怎麼切換畫面 |
原本分開學的東西,現在真的開始組在一起了,前面是把兩個世界接起來,而今天則是讓「進入 3D 世界」這件事情不再只是切換畫面。
下一篇就是最後的作品整理,把前面學過的 JavaScript、GSAP、ScrollTrigger 和 Three.js 全部收進同一個網站。