js實(shí)現(xiàn)炫酷的煙花效果
本文實(shí)例為大家分享了js實(shí)現(xiàn)炫酷的煙花效果的具體代碼,供大家參考,具體內(nèi)容如下
我們要理清整個(gè)流程的思路。
首先建立一塊畫布,用于展示煙花的效果,然后就要去思考煙花燃放的流程,我們都知道煙花通常都是先有一份飛上天,然后再分散成很多個(gè)小煙花,并且每一個(gè)小煙花都有不同的樣式以及運(yùn)動(dòng)方式。
所有整體思路就是先建立一個(gè)div作為我們的大煙花,當(dāng)大煙花運(yùn)動(dòng)到我們鼠標(biāo)點(diǎn)擊的位置的時(shí)候,大煙花就會(huì)消失,然后就會(huì)產(chǎn)生更多的小煙花,并且這些小煙花的運(yùn)動(dòng)軌跡樣式各不相同。
1.建立一塊畫布(div)用于展示煙花的效果
/*給畫布設(shè)置css樣式 */ #container { width: 80%; height: 600px; border: 1px red solid; position: relative; margin: 20px auto; cursor: pointer; background: black; } <!-- 設(shè)置一個(gè)div --> <div id="container"></div>
2.獲取節(jié)點(diǎn)
//獲取節(jié)點(diǎn) var app = document.getElementById('container'); //給app設(shè)置一個(gè)綁定事件 app.onclick = function(event) { var e = event || window.event //獲得鼠標(biāo)點(diǎn)擊的位置的坐標(biāo) var pos = { cy: e.offsetY, cx: e.offsetX } new Fire(app, pos) }
煙花的實(shí)現(xiàn)過(guò)程:先實(shí)現(xiàn)一個(gè)大的div運(yùn)動(dòng)到鼠標(biāo)點(diǎn)擊的位置,然后在散開成為很多個(gè)div
3.先實(shí)現(xiàn)大煙花(需要調(diào)用隨機(jī)數(shù)方法,隨機(jī)顏色方法,以及運(yùn)動(dòng)函數(shù))
// 構(gòu)造函數(shù) function Fire(app, pos) { //把屬性設(shè)置成變量 this.app = app; this.pos = pos; //創(chuàng)建一個(gè)大的div this.bf = document.createElement('div'); //設(shè)置一個(gè)類名 this.bf.className = 'fire'; //設(shè)置樣式 this.bf.style.left = this.pos.cx + 'px'; this.bf.style.background = this.getColor(); this.app.appendChild(this.bf); //調(diào)用運(yùn)動(dòng)函數(shù) this.move(this.bf, { top: this.pos.cy }, () => { this.bf.remove(); this.smallFire(); }) }
3.1首先先設(shè)置fire的樣式
這是fire的初始樣式
.fire { background: red; position: absolute; /* 設(shè)置bottom時(shí),top獲取為最大值,減去鼠標(biāo)點(diǎn)擊位置 */ bottom: 0px; width: 6px; height: 6px; }
3.2設(shè)置一個(gè)隨機(jī)數(shù)和隨機(jī)顏色的方法(原型對(duì)象)
//獲得一個(gè)隨機(jī)數(shù)方法 Fire.prototype.rand = function(min, max) { return Math.round(Math.random() * (max - min) + min); } //獲得一個(gè)隨機(jī)顏色的方法 Fire.prototype.getColor = function() { let sum = '#'; for (let i = 0; i < 6; i++) { sum += this.rand(0, 15).toString(16) } return sum; }
3.3封裝一個(gè)運(yùn)動(dòng)函數(shù)(原型對(duì)象)
Fire.prototype.move = function(ele, target, cb) { // clearInterval(times); let times = setInterval(function() { // console.log(this); var onOff = true; // 遍歷運(yùn)動(dòng)的方向和目標(biāo) for (let attr in target) { // attr 表示運(yùn)動(dòng)的屬性 // console.log(attr); // 獲取元素屬性的實(shí)時(shí)值 let tmpVal = parseInt(this.getPos(ele, attr)) // 計(jì)算speed // console.log(tmpVal, attr); let speed = (target[attr] - tmpVal) / 10; // 取整 speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed); // 停止計(jì)時(shí)器,當(dāng)一個(gè)屬性運(yùn)動(dòng)到位置,設(shè)置開關(guān)狀態(tài) if (tmpVal == target[attr]) onOff = true; // 讓元素動(dòng)起來(lái) ele.style[attr] = tmpVal + speed + 'px'; } // 判斷開關(guān)狀態(tài),清除定時(shí)器 for (var moveAttr in target) { // 如果不相等,就說(shuō)明有屬性沒有運(yùn)動(dòng)到位置,定時(shí)器不能停止 if (target[moveAttr] !== parseInt(this.getPos(ele, moveAttr))) { onOff = false; break; } } if (onOff) { clearInterval(times); cb && cb(); } // console.log(1111); }.bind(this), 30) } // 獲取元素的實(shí)時(shí)位置的函數(shù) Fire.prototype.getPos = function(obj, attr) { if (obj.currentStyle) { // 獲取css的樣式 return obj.currentStyle[attr]; } else { return getComputedStyle(obj)[attr] } }
通過(guò)以上幾個(gè)步驟我們就可以得到大煙花的運(yùn)動(dòng)軌跡,大煙花運(yùn)動(dòng)到指定位置后就會(huì)消失,并且從消失的地方產(chǎn)生許多小煙花。由前面的分析可以知道,小煙花的運(yùn)動(dòng)軌跡和樣式各不相同,接下來(lái)就是小煙花的實(shí)現(xiàn)
4.小煙花的實(shí)現(xiàn)
4.1設(shè)置samll-fire的樣式
這是samll-fire的初始屬性
.small-fire { width: 10px; height: 10px; position: absolute; border-radius: 50%; }
4.2設(shè)置小煙花的屬性
//小煙花 Fire.prototype.smallFire = function() { //首先我們?cè)O(shè)置小煙花的數(shù)量 let num = this.rand(50, 60) //遍歷 給每一個(gè)小煙花設(shè)置不同的樣式 for (let i = 0; i < num; i++) { let sf = document.createElement('div'); sf.className = 'small-fire'; sf.style.left = this.pos.cx + 'px'; sf.style.top = this.pos.cy + 'px'; sf.style.background = this.getColor(); //console.log(sf); //追加到頁(yè)面中 this.app.appendChild(sf); //使小煙花的運(yùn)動(dòng)軌跡成圓周運(yùn)動(dòng) //var top = parseInt(Math.sin(Math.PI / 180 * 360 / num * i) * r) + this.pos.cy; //var left = parseInt(Math.cos(Math.PI / 180 * 360 / num * i) * r) + this.pos.cx; //給小煙花一個(gè)隨機(jī)的位置,可以是在畫布里面的任意一個(gè)位置 let top = this.rand(0, this.app.offsetHeight - sf.offsetHeight); let left = this.rand(0, this.app.offsetWidth - sf.offsetWidth); //調(diào)用運(yùn)動(dòng)函數(shù) this.move(sf, { top: top, left: left }, function() { sf.remove(); }) } }
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
JS實(shí)現(xiàn)圖片無(wú)間斷滾動(dòng)代碼匯總
這篇文章主要介紹了JS實(shí)現(xiàn)圖片無(wú)間斷滾動(dòng)代碼匯總,非常實(shí)用的特效代碼,需要的朋友可以參考下2014-07-07JS實(shí)現(xiàn)兩表格里數(shù)據(jù)來(lái)回轉(zhuǎn)移的方法
這篇文章主要介紹了JS實(shí)現(xiàn)兩表格里數(shù)據(jù)來(lái)回轉(zhuǎn)移的方法,涉及javascript鼠標(biāo)事件及頁(yè)面元素的相關(guān)操作技巧,需要的朋友可以參考下2015-05-05前端實(shí)現(xiàn)讀取word文件并將其原樣式展示的幾種方案
在前端直接讀取并原樣展示W(wǎng)ord文檔是一個(gè)相對(duì)復(fù)雜的任務(wù),因?yàn)閃ord文檔的格式(如.doc或.docx)與Web技術(shù)棧使用的格式(HTML、CSS)不兼容,這篇文章主要給大家介紹了關(guān)于前端實(shí)現(xiàn)讀取word文件并將其原樣式展示的幾種方案,需要的朋友可以參考下2024-08-08js基于FileSaver.js 瀏覽器導(dǎo)出Excel文件的示例
本篇文章主要介紹了js基于FileSaver.js 瀏覽器導(dǎo)出Excel文件的示例,具有一定的參考價(jià)值,有興趣的可以了解一下2017-08-08關(guān)于字符串和對(duì)象互轉(zhuǎn)以及JSON.parse()的坑
這篇文章主要介紹了關(guān)于字符串和對(duì)象互轉(zhuǎn)以及JSON.parse()的坑及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09基于Leaflet的Webgis經(jīng)緯網(wǎng)格功能實(shí)現(xiàn)
本文將介紹一款Leaflet的經(jīng)緯網(wǎng)插件,基于這款經(jīng)緯網(wǎng)插件,詳細(xì)介紹如何實(shí)現(xiàn)經(jīng)緯網(wǎng)功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2023-12-12