基于JavaScript實(shí)現(xiàn)除夕煙花秀與隨機(jī)祝福語(yǔ)
項(xiàng)目截圖
進(jìn)入后的界面

點(diǎn)擊按鈕

點(diǎn)擊之后的動(dòng)畫(huà)

煙花結(jié)束后的界面

代碼實(shí)現(xiàn)
涉及的技術(shù):HTML5多媒體,CSS定位,動(dòng)畫(huà),js面向?qū)ο?,Jquery動(dòng)畫(huà)、事件
HTML代碼
<!DOCTYPE html>
<html lang="cn">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>2022</title>
<link rel="shortcut icon" href="./images/favicon.ico" rel="external nofollow" type="image/x-icon">
<link rel="stylesheet" href="./css/index.css" rel="external nofollow" >
<script src="./js/jquery-3.6.0.min.js"></script>
<script src="./js/index.js"></script>
</head>
<body>
<!--這個(gè)是點(diǎn)擊按鈕的盒子,算是煙花筒 -->
<div class="he">
<!--這個(gè)是點(diǎn)擊按鈕,點(diǎn)擊以后就開(kāi)始做一些處理 -->
<button id="fire"></button>
</div>
<!--這個(gè)是煙花哦-->
<div class="box">
</div>
<!--這個(gè)是煙花結(jié)束后,出現(xiàn)在上面的2022圖片
<div class="title"></div>
<!--這個(gè)就是隨機(jī)生成祝福語(yǔ)的大盒子啦-->
<div class="greetings">
<!--可以通過(guò)這個(gè)div來(lái)動(dòng)態(tài)的呈現(xiàn)祝福語(yǔ),默認(rèn)第一個(gè)是虎虎生威-->
<div class="yu"><span id="blessing">虎虎生威</span></div>
<!--這個(gè)是點(diǎn)擊按鈕,點(diǎn)擊后停下快閃的祝福語(yǔ)-->
<button id="btn">查看我的祝福</button>
</div>
<audio src="./meiti/chuxi.mp3"></audio>
<audio src="./meiti/yanhua.mp3"></audio>
</body>
</html>
上面的html代碼結(jié)構(gòu)就是,煙花盒(.he)、點(diǎn)火按鈕(.fire)、煙花(.box)、顯示2022虎年logo(.title)、祝福語(yǔ)盒子(.greetings)、顯示祝福的具體容器(.yu 和 .blessing)、暫??焖亠@示的按鈕(.btn)、兩個(gè)音頻。一共10個(gè)重要元素。
CSS代碼
/*清除默認(rèn)的邊距*/
* {
margin: 0;
padding: 0;
}
/*導(dǎo)入字體,用來(lái)設(shè)置在祝福語(yǔ)上*/
@font-face {
font-family: 'djs';
src: url(../font/datk6.ttf);
}
/*設(shè)置body超出隱藏,因?yàn)楹竺鏌熁〞?huì)超出,導(dǎo)致頁(yè)面被撐開(kāi)*/
body {
/* background: #EF3D04; */
overflow: hidden;
background: #F35708 url(../images/hebj.png)no-repeat center center/100% 100%;
}
/*煙花盒子我們讓他居于底部居中對(duì)齊*/
.he {
position: absolute;
width: 160px;
height: 120px;
background: url(../images/hebj.png)no-repeat center center/100% 100%;
border-radius: 5px 5px 0 0;
bottom: 0;
left: 50%;
transform: translateX(-50%);
z-index: 2;
transition: all 3s;
}
.he button {
position: absolute;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
border: 1px solid #C33830;
box-shadow: 0 0 5px #D7A057, 0 0 2px #D7A057 inset;
border-radius: 5px;
width: 50px;
height: 50px;
background: transparent url(../images/huzhua.png)no-repeat center center/100% 100%;
font-size: 12px;
color: yellow;
font-weight: 700;
}
/*煙花盒子,我們也要讓他在底部居中對(duì)齊,后期我們通過(guò)動(dòng)畫(huà),改變top值,實(shí)現(xiàn)由下而上的發(fā)射效果*/
.box {
position: absolute;
width: 50px;
height: 50px;
border-radius: 50%;
overflow: hidden;
transition: all;
top: calc(100% - 50px);
left: 50%;
transform: translateX(-50%);
}
/*這是煙花綻放生成的小點(diǎn),就是哪些五顏六色的小點(diǎn),后面通過(guò)js隨機(jī)生成個(gè)數(shù),位置,大小,因?yàn)槭请S機(jī)的所有這個(gè)只設(shè)置絕對(duì)定位,不給定具體的top和left值*/
.box span {
position: absolute;
display: inline-block;
border-radius: 50%;
}
/*當(dāng)box到達(dá)指定的top值后,我們就可以給box添加這個(gè)帶動(dòng)畫(huà)的樣式了,這個(gè)動(dòng)畫(huà)具體的效果我們寫(xiě)在后面*/
.fire {
left: 50%;
transform: translateX(-50%);
animation: suofang 4.5s linear;
}
/*2022虎年logo的樣式*/
.title {
position: absolute;
width: 300px;
height: 150px;
background: url(../images/hunian.png)no-repeat center center/100% 100%;
top: 10px;
left: 50%;
transform: translateX(-50%);
transition: all 1s;
display: none;
}
/*祝福語(yǔ)盒子的樣式,這里指的注意的是自身的目標(biāo)top值,必須加上.title的top值*/
.greetings {
position: absolute;
top: 180px;
width: 260px;
height: 400px;
background: #FFE5C8;
left: 50%;
transform: translateX(-50%);
display: flex;
flex-direction: column;
justify-content: center;
padding: 30px;
box-sizing: border-box;
border-radius: 20px;
overflow: hidden;
opacity: 0;
}
/*這是顯示句子的第二層盒子,其作用是讓文本垂直排列,居中對(duì)齊*/
.yu {
display: flex;
justify-content: center;
align-items: center;
writing-mode: tb;
width: 100%;
height: 85%;
border-radius: 10px;
background: url(../images/zhufu.png)no-repeat center center/100% 100%;
}
/*這就是祝福與顯示盒子的本體啦,這里主要設(shè)置字體樣式*/
#blessing {
font-size: 50px;
font-weight: 800;
color: rgba(0, 0, 0, 0.74);
letter-spacing: 6px;
font-family: 'djs';
}
/*暫停按鈕*/
#btn {
width: 100%;
height: 15%;
margin-top: 50px;
border-radius: 10px;
border: 1px solid #D7A057;
color: #D7A057;
font-size: 14px;
font-weight: 700;
background: url(../images/btn.png)no-repeat center center/100% 100%;
}
/*動(dòng)畫(huà)函數(shù),我在寫(xiě)這個(gè)動(dòng)畫(huà)函數(shù)之前,就猜測(cè),如果父元素縮放,
里面的子元素會(huì)不會(huì)隨著一起縮放,寫(xiě)出來(lái)后,證明我的猜測(cè)是正確的*/
@keyframes suofang {
0% {
transform: scale(1);
opacity: 1;
}
50% {
transform: scale(20);
opacity: .5;
}
100% {
transform: scale(100);
opacity: 0;
display: none;
}
}
以上的css代碼,可以看到,我使用了大量的定位。這是因?yàn)楹竺娴膭?dòng)畫(huà)都需要基于定位的left和top來(lái)實(shí)現(xiàn)。
好啦結(jié)構(gòu)和樣式都有了,我們就來(lái)看看js(行為)吧
javaScript代碼
1、生成煙花球和焰火
$(function() {
//封裝一個(gè)生成隨機(jī)數(shù)的函數(shù),方便后期隨機(jī)生成煙花焰火的個(gè)數(shù),大小,位置
function rand(min, max) {
return Math.random() * (max - min) + min;
}
//創(chuàng)建一個(gè)構(gòu)造函數(shù),構(gòu)造函數(shù)中調(diào)用隨機(jī)函數(shù),生成500-1000之間隨機(jī)的隨機(jī)數(shù),用于生成焰火的個(gè)數(shù)
function Birth() {
this.sum = parseInt(rand(500, 1000));
}
//在構(gòu)造函數(shù)的原型對(duì)象上添加隨機(jī)生成位置,大小的函數(shù),里面調(diào)用之前定義的隨機(jī)函數(shù)
Birth.prototype.suiji = function() {
//隨機(jī)生成一個(gè)X軸坐標(biāo)
this.x = parseInt(rand(0, 50));
//隨機(jī)生成一個(gè)Y軸坐標(biāo)
this.y = parseInt(rand(0, 50));
//隨機(jī)生成一個(gè)寬度,因?yàn)樯傻难婊鹗秸龍A,所以這里生成的焰火寬高式相等
this.w = parseInt(rand(1, 3));
//隨機(jī)生成一個(gè)rgb顏色(0-255之間哦)
this.color = parseInt(rand(0, 255));
//將生成的對(duì)象返回(拋出)
return this;
}
//將上面的構(gòu)造函數(shù)實(shí)例化為對(duì)象,這樣這個(gè)對(duì)象就可以訪問(wèn)上面構(gòu)造函數(shù)生成的所有數(shù)據(jù)了
const qiu = new Birth();
//定義一個(gè)文檔碎片,優(yōu)化程序性能(減少頁(yè)面重繪與回流)
const jsbox = document.createDocumentFragment();
//使用循環(huán)生成焰火,這里焰火使用span標(biāo)簽來(lái)表示
for (var i = 0; i < qiu.sum; i++) {
//獲取本次循環(huán)生成的x軸坐標(biāo)
var x = qiu.suiji().x;
//獲取本次循環(huán)生成的y軸坐標(biāo)
var y = qiu.suiji().y;
//獲取本次循環(huán)生成的高和寬
var w = qiu.suiji().w;
//生成span元素,并將其追加到文檔碎片中
$(jsbox).append('<span></span>').children().eq(i).css({ 'background': `rgb(${qiu.suiji().color},${qiu.suiji().color},${qiu.suiji().color})`, 'width': w, 'height': w, 'left': x, 'top': y });
}
//將文檔碎片追加到煙花盒子里,至此煙花部分結(jié)束
$('.box').append(jsbox);
})
2、祝福語(yǔ)快速切換與暫停查看
//我們將需要展示的祝福語(yǔ),寫(xiě)在數(shù)組中,后期遍歷這個(gè)數(shù)組就可以了
const arr = ['虎虎生威', '財(cái)源滾滾', '虎年大運(yùn)', '虎氣沖天', '虎越新春', '虎虎虎虎'];
//聲明一個(gè)全局變量,用來(lái)當(dāng)作下標(biāo)訪問(wèn)數(shù)組
let ind = 0;
/*聲明一個(gè)全局變量,用來(lái)當(dāng)作節(jié)流閥,防止用戶反復(fù)點(diǎn)擊導(dǎo)致定時(shí)器疊加,
祝福語(yǔ)切換太快,還能防止用戶反復(fù)點(diǎn)擊導(dǎo)致BGM重復(fù)播放*/
let isok = false;
//定義一個(gè)全局變量用來(lái)存儲(chǔ)頁(yè)面中的定時(shí)器
let t;
//快速切換祝福語(yǔ)的函數(shù)
function setZf() {
//使用定時(shí)器,每0.01秒執(zhí)行一次定時(shí)器中的代碼
t = setInterval(function() {
/*判斷ind是不是等于數(shù)組長(zhǎng)度-1,以免小標(biāo)超出數(shù)組實(shí)際長(zhǎng)度出現(xiàn)undefinde,
如果是,就將ind歸零,不是就繼續(xù)自加*/
if (ind >= arr.length - 1) {
ind = 0;
} else {
ind++;
}
/*將從數(shù)組中讀取出來(lái)的祝福語(yǔ),渲染到頁(yè)面中*/
$('#blessing')[0].innerHTML = arr[ind];
}, 10);
}
/*調(diào)用上面的函數(shù),讓頁(yè)面一打開(kāi)就開(kāi)始執(zhí)行,因?yàn)槠銫SS樣式設(shè)置了隱藏,
所以這里即使頁(yè)面一打開(kāi),用戶也看不見(jiàn)*/
setZf();
/*當(dāng)暫停按鈕被點(diǎn)擊后,我們開(kāi)始判斷,節(jié)流閥如果是真,就調(diào)用上面的函數(shù),
實(shí)現(xiàn)開(kāi)始切換祝福語(yǔ)的效果,并將節(jié)流閥關(guān)閉*/
$('#btn')[0].onclick = function() {
if (isok) {
setZf();
isok = false;
} else {
/*如果節(jié)流閥是關(guān)閉的(isok=false),就清除定時(shí)器,到達(dá)暫停的效果,
然后將節(jié)流閥打開(kāi),方便下次開(kāi)啟切換*/
clearInterval(t);
isok = true;
}
}
3、點(diǎn)擊開(kāi)火按鈕后所做的事情(一下代碼使用了Jquery)
//獲取元素并重新賦值
const box = $('.box');
const fire = $('#fire');
let count;
//當(dāng)點(diǎn)火按鈕被點(diǎn)擊時(shí),立馬讓煙花發(fā)射BGM開(kāi)始播放,并將按鈕設(shè)為禁止點(diǎn)擊,防止用戶反復(fù)點(diǎn)擊,造成BUG重疊
fire[0].onclick = function() {
$('audio')[1].play();
fire[0].disabled = true;
}
//當(dāng)開(kāi)火按鈕被點(diǎn)擊,利用這個(gè)事件的一點(diǎn)點(diǎn)的延遲效果(剛好是煙花發(fā)射BGM播放結(jié)束)播放新年BGM
fire.click(function() {
$('audio')[0].play();
//給煙花盒子添加CSS樣式,達(dá)到煙花居中顯示
box.css({
left: '50%',
transform: 'translateX(-50%)',
})
/*給煙花盒子添加動(dòng)畫(huà),改變的是top值,當(dāng)top等于100px時(shí)動(dòng)畫(huà)結(jié)束,因?yàn)閎ox的top
初始值位于屏幕的底部,讓其top值改為100px,就形成了慢慢向上移動(dòng)的視覺(jué)效果。*/
box.animate({
top: '100px',
/*動(dòng)畫(huà)結(jié)束后,開(kāi)始執(zhí)行的函數(shù)*/
}, function() {
/*當(dāng)煙花球到達(dá)指定位置后,給其添加帶有動(dòng)畫(huà)(縮放)效果的CSS樣式,達(dá)到煙花綻放的視覺(jué)效果*/
box.addClass('fire');
/*使用定時(shí)器判斷,煙花是否綻放完成,綻放完成就讓煙花球隱藏,讓2022虎年logo顯示,讓祝福語(yǔ)盒子顯示*/
count = setInterval(() => {
if (Math.abs(box.offset().top) == 100) {
box.css({ 'opacity': '0' })
$('.he').hide();
$('.title')[0].style.display = 'block';
$('.greetings')[0].style.opacity = '1';
$('body').css({
})
clearInterval(count);
}
}, 100);
});
})
以上就是這個(gè)項(xiàng)目的所有代碼,再次預(yù)祝大家新年快樂(lè),虎年大吉,財(cái)源滾滾。
項(xiàng)目體驗(yàn)鏈接:http://www.starqin920.cn/chuxi/index.html
以上就是基于JavaScript實(shí)現(xiàn)除夕煙花秀與隨機(jī)祝福語(yǔ)的詳細(xì)內(nèi)容,更多關(guān)于JavaScript煙花 隨機(jī)祝福語(yǔ)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
JavaScript面試必備之垃圾回收機(jī)制和內(nèi)存泄漏詳解
垃圾回收機(jī)制和內(nèi)存泄漏是JavaScript面試時(shí)常常問(wèn)到的問(wèn)題,這篇文章就為大家詳細(xì)整理了他們的相關(guān)知識(shí),感興趣的小伙伴可以跟隨小編一起了解一下2023-05-05
基于Javascript實(shí)現(xiàn)返回頂部按鈕
這篇文章主要為大家詳細(xì)介紹了基于Javascript實(shí)現(xiàn)返回頂部按鈕,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-02-02
Electron 使用 Nodemon 配置自動(dòng)重啟的方法
在Electron開(kāi)發(fā)過(guò)程中,每次代碼修改后需手動(dòng)重新啟動(dòng)應(yīng)用,這一過(guò)程可以通過(guò)引入Nodemon工具自動(dòng)化,Nodemon能夠監(jiān)測(cè)文件變化并自動(dòng)重啟服務(wù)器,本文給大家介紹Electron 使用 Nodemon 配置自動(dòng)重啟,感興趣的朋友一起看看吧2024-09-09
JS設(shè)置時(shí)間無(wú)效問(wèn)題的解決辦法
在發(fā)送短信息驗(yàn)證碼的時(shí)候要用到j(luò)s設(shè)置時(shí)間倒序問(wèn)題,有時(shí)候會(huì)導(dǎo)致js失效問(wèn)題,怎么辦呢?今天小編給大家分享JS設(shè)置時(shí)間無(wú)效問(wèn)題的解決辦法,需要的朋友參考下吧2017-02-02
JavaScript微信定位功能實(shí)現(xiàn)方法
這篇文章主要介紹了JavaScript微信定位功能實(shí)現(xiàn)方法,將定位到的經(jīng)緯度轉(zhuǎn)換為百度地圖對(duì)應(yīng)的經(jīng)緯度,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-11-11

