利用Three.js制作一個(gè)新聞聯(lián)播開(kāi)頭動(dòng)畫(huà)
在線體驗(yàn)地址:點(diǎn)我預(yù)覽
代碼地址:點(diǎn)我github
這里才是引言
五一居家隔離,閑著也是閑著,想著整個(gè)活兒,于是就有了這個(gè)項(xiàng)目。
項(xiàng)目本身不是很難,但是中間確實(shí)是遇到了一些小問(wèn)題,斷斷續(xù)續(xù)也是花費(fèi)了三四天時(shí)間才寫(xiě)完,還有一些需要優(yōu)化的地方,后續(xù)有時(shí)間再整。
我會(huì)從腳手架開(kāi)始,按照?qǐng)鼍爸谐霈F(xiàn)的物體順序逐條進(jìn)行講解制作,每個(gè)物體將分為獨(dú)立的一篇文章,方便理解。Go。
技術(shù)選型
- 選用
vite作為構(gòu)建工具; - 選用
three.js作為三維庫(kù); - 選用
tween.js作為動(dòng)畫(huà)庫(kù)(three.js包里自帶一個(gè),不需要額外安裝) - 其他就沒(méi)了,就這么簡(jiǎn)單。
場(chǎng)景分解
已經(jīng)忘記新聞聯(lián)播片頭的小伙伴可以搜一下視頻去回顧下。
我將片頭場(chǎng)景中出現(xiàn)的物體分為這幾個(gè):
- 背景音樂(lè)
- 背景圖:宇宙背景,有往外飛的射線和氤氳的氣
- 地球:從右下角飛到畫(huà)面正中間,不斷旋轉(zhuǎn),地球上方的云比地球轉(zhuǎn)得略慢
- 紅綠藍(lán)三條色帶:從畫(huà)面的三個(gè)角依次往對(duì)角線飛過(guò)
- 出現(xiàn)的三維文字:其實(shí)分為四段,依次有動(dòng)畫(huà),到文字章節(jié)的時(shí)候細(xì)說(shuō)


代碼邏輯分解
有了場(chǎng)景分解后,我們只要去寫(xiě)對(duì)應(yīng)的代碼就可以了。通過(guò)three.js代碼生成相應(yīng)物體,并且使用tween.js給物體配上對(duì)應(yīng)的補(bǔ)間動(dòng)畫(huà),達(dá)到整個(gè)場(chǎng)景的運(yùn)動(dòng)效果。
值得注意的是,該項(xiàng)目中所有動(dòng)畫(huà)都是連貫播放的,所以需要將應(yīng)用到的素材都提前加載好,不然會(huì)出現(xiàn)物體一開(kāi)始是黑色的,運(yùn)動(dòng)了一會(huì)兒才有貼圖這種情況。
我們按照以上邏輯,預(yù)先建好各個(gè)js文件:
bg.js負(fù)責(zé)創(chuàng)建背景preload.js負(fù)責(zé)預(yù)加載資源initThree.js負(fù)責(zé)初始化三維場(chǎng)景rgb.js負(fù)責(zé)創(chuàng)建紅綠藍(lán)色條色帶及其動(dòng)畫(huà)earth.js負(fù)責(zé)創(chuàng)建地球及其動(dòng)畫(huà)text.js負(fù)責(zé)創(chuàng)建三維文字及其動(dòng)畫(huà)play.js最后一個(gè)js文件,負(fù)責(zé)開(kāi)始播放整個(gè)場(chǎng)景的動(dòng)畫(huà)
額外的,背景音樂(lè)通過(guò) audio 標(biāo)簽插入到dom中,并在play中隨動(dòng)畫(huà)一起觸發(fā)播放。
創(chuàng)建背景圖和背景音樂(lè)
本來(lái)作為 用three.js做一個(gè)新聞聯(lián)播開(kāi)頭動(dòng)畫(huà) 專(zhuān)題的序章,本文就應(yīng)該到此了,下一章按順序應(yīng)該介紹背景圖和背景音樂(lè)的創(chuàng)建。
但是想想背景圖和背景音樂(lè)不屬于three.js的范疇,篇幅也比較短,直接在此帶過(guò),下一章直接介紹地球的創(chuàng)建好了。
背景圖
正宗片頭中的背景圖是比較酷炫的,而我自己經(jīng)歷從 自己寫(xiě)shader 到 找一個(gè)類(lèi)似的gif背景 最后到 簡(jiǎn)單用css寫(xiě)一個(gè)背景拉倒了 的心理過(guò)程。
首先,我們?cè)趆tml中插入背景圖的div,并賦予id。
<div id="bg"></div>
其css如下,保證和three場(chǎng)景大小一致,并且疊在three場(chǎng)景下方。
#bg {
width: 100%;
height: 100%;
position: absolute;
overflow: hidden;
perspective: 10vmin;
background: radial-gradient(
circle farthest-corner at center center,
#b5bdca,
#666
);
}
.star {
z-index: 1;
--unit: 1.5vmin;
width: var(--unit);
height: var(--unit);
--rotate: rotateY(90deg);
transform: translateZ(-100vmin) var(--rotate) rotateX(var(--rx))
translateZ(var(--x)) scaleX(1);
position: absolute;
top: 0;
left: 0;
animation: none 1800ms infinite ease-in;
background: #d1e8f7;
}
@keyframes hyper {
0% {
opacity: 1;
}
90% {
opacity: 1;
}
100% {
opacity: 0;
transform: translateZ(0vmin) var(--rotate) rotateX(var(--rx))
translateZ(var(--x)) scaleX(2);
}
}我們使用css3的動(dòng)畫(huà)和變形,創(chuàng)造出宇宙射線向外設(shè)的效果, bg.js 中代碼如下 :
const starCount = 10;
const bgDom = document.getElementById("bg");
for (let i = 0; i < starCount; i++) {
const div = document.createElement("div");
div.classList.add("star");
bgDom.append(div);
let x = `${Math.random() * 200}vmax`;
let y = `${Math.random() * 100}vh`;
let z = `${Math.random() * 200 - 100}vmin`;
let rx = `${Math.random() * 360}deg`;
div.style.setProperty("--x", x);
div.style.setProperty("--y", y);
div.style.setProperty("--z", z);
div.style.setProperty("--rx", rx);
let delay = `${Math.random() * 2000}ms`;
div.style.animationDelay = delay;
div.style.animationName = "hyper";
}背景音樂(lè)
說(shuō)到這個(gè)屬實(shí)氣,各個(gè)瀏覽器兼容不一致,new Audio()出來(lái)的也會(huì)有不一致,一開(kāi)始繞了很大的彎子。
最后使用很傳統(tǒng)的方法,在html中插入 audio 標(biāo)簽,并將三種格式的音樂(lè)都引進(jìn)來(lái),根據(jù)瀏覽器的不同自動(dòng)判斷加載哪個(gè)。
需要注意的是,要加上preload屬性,表示預(yù)加載。
<audio preload="auto" id="bgm">
<source src="/assets/bgm.ogg" />
<source src="/assets/bgm.mp3" />
<source src="/assets/bgm.wav" />
</audio>創(chuàng)建完成后,在 play.js 中可通過(guò)id獲取到該音樂(lè)并播放,這是后話了。
到此這篇關(guān)于利用Three.js制作一個(gè)新聞聯(lián)播開(kāi)頭動(dòng)畫(huà)的文章就介紹到這了,更多相關(guān)Three.js 新聞聯(lián)播開(kāi)頭動(dòng)畫(huà)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- vue+threejs寫(xiě)物體動(dòng)畫(huà)之物體縮放動(dòng)畫(huà)效果
- three.js 實(shí)現(xiàn)露珠滴落動(dòng)畫(huà)效果的示例代碼
- vue頁(yè)面引入three.js實(shí)現(xiàn)3d動(dòng)畫(huà)場(chǎng)景操作
- Threejs實(shí)現(xiàn)滴滴官網(wǎng)首頁(yè)地球動(dòng)畫(huà)功能
- WebGL three.js學(xué)習(xí)筆記之陰影與實(shí)現(xiàn)物體的動(dòng)畫(huà)效果
- Three.js?Interpolant實(shí)現(xiàn)動(dòng)畫(huà)插值
相關(guān)文章
基于JS實(shí)現(xiàn)點(diǎn)擊圖片在彈出層顯示大圖效果
Javascript是個(gè)好東西。Jquery是基于這個(gè)好東西的一個(gè)強(qiáng)大的庫(kù)。本文將利用JavaScript實(shí)現(xiàn)點(diǎn)擊圖片在彈出層顯示大圖功能,感興趣的可以了解一下2022-08-08
如何使用json在前后臺(tái)進(jìn)行數(shù)據(jù)傳輸實(shí)例介紹
需要把這些輸入寫(xiě)入數(shù)據(jù)庫(kù),這里就用到j(luò)son傳入,先看一下后臺(tái)如何生成要傳輸?shù)臄?shù)據(jù),感興趣的朋友可以參考下,希望可以幫助到你2013-04-04
JavaScript使用Base64編碼和Blob對(duì)象加密圖像url地址
有時(shí)候會(huì)看到一些網(wǎng)站的圖片src中是blob:http://example.com/7c672acb-375c-4a26-9af9-99cb4c77f04d,這樣的圖片加載怎么實(shí)現(xiàn)呢?本文講解在瀏覽器中JavaScript使用解析Base64編碼和Blob對(duì)象技術(shù)來(lái)實(shí)現(xiàn),下面是實(shí)現(xiàn)的步驟和相應(yīng)的示例代碼,2023-12-12
javascript實(shí)現(xiàn)多邊形碰撞檢測(cè)
這篇文章主要介紹了javascript如何實(shí)現(xiàn)多邊形碰撞檢測(cè),幫助大家更好的理解和使用js,感興趣的朋友可以了解下2020-10-10
如何在指定的地方插入html內(nèi)容和文本內(nèi)容
本文為大家介紹個(gè)小技巧可以在指定的地方插入html內(nèi)容和文本內(nèi)容,示例如下,感興趣的朋友可以參考下2013-12-12
laydate如何根據(jù)開(kāi)始時(shí)間或者結(jié)束時(shí)間限制范圍
這篇文章主要為大家詳細(xì)介紹了laydate根據(jù)開(kāi)始時(shí)間或者結(jié)束時(shí)間限制范圍的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-11-11
JavaScript的防抖和節(jié)流一起來(lái)了解下
這篇文章主要為大家詳細(xì)介紹了JavaScript的防抖和節(jié)流,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助2022-03-03

