JavaScript實(shí)現(xiàn)煙花特效(面向?qū)ο?
本文實(shí)例為大家分享了JavaScript實(shí)現(xiàn)煙花特效的具體代碼,供大家參考,具體內(nèi)容如下
本特效使用面向?qū)ο缶幊?/strong>
分析
OOA
- 點(diǎn)擊觸發(fā)事件
- 煙花運(yùn)動(dòng)分成兩個(gè)階段
向上飛
爆炸
OOD
class FireWork{ constructor(){ } bindEvent(){ let _this = this; ele.onclick = function(){ //fly結(jié)束再去調(diào)用boom函數(shù) _this.fly(_this.boom); } } fly(boom){ } boom(){ } }
CSS設(shè)計(jì)實(shí)現(xiàn)
CSS代碼
*{ margin: 0; padding: 0; } #box{ width:800px; height:600px; position: relative; margin: 100px auto; background:#000000; border:2px solid red; overflow: hidden; } .ball{ width: 40px; height: 40px; border-radius: 50%; position: absolute; bottom: 0; }
JS編程實(shí)現(xiàn)
javascript代碼
<script src="./utils.js"></script> <script> // class FireWork{ constructor(){ this.box = document.getElementById("box"); this.box_offset = { left : box.offsetLeft, top : box.offsetTop } } bindEvent(){ let _this = this; this.box.onclick = function( e ){ e = e || event; _this.x = e.clientX - _this.box_offset.left; _this.y = e.clientY - _this.box_offset.top; _this.fly(_this.boom); } } fly( boom ){ let ele = this.createEle(); let _this = this; // 放入box之中; ele.style.left = this.x + "px"; let _left = this.x ; let _top = this.y ; animate( ele , { top : this.y } , function(){ ele.remove(); _this.boom( _left , _top ); }); } boom( x , y ){ let r = 100; let count = 0 ; let _this = this; for(let i = 0 ; i < 20 ; i ++){ let ele = this.createEle(); ele.style.left = x +"px"; ele.style.top = y + "px"; let _left = parseInt(Math.cos( Math.PI / 10 * i ) * r ) + x ; let _top = parseInt(Math.sin( Math.PI / 10 * i ) * r) + y animate( ele , { left : _left, top : _top, opacity : 0 } , function(){ ele.remove(); }) } } createEle(){ let ele = document.createElement("div"); ele.className = "ball"; ele.style.backgroundColor = `rgb(${parseInt(Math.random() * 255)},${parseInt(Math.random() * 255)},${parseInt(Math.random() * 255)})`; this.box.appendChild( ele ); return ele ; } } new FireWork().bindEvent(); </script>
引用的utils.js文件
function on(dom, event_name, handler_selector, delegation_handler) { if( typeof handler_selector === "string" && typeof delegation_handler === "function"){ return delegation(dom, event_name, handler_selector, delegation_handler); } // 在dom對(duì)象里面建立一個(gè)事件名 : 事件處理函數(shù)對(duì)應(yīng)的數(shù)組; // 判定當(dāng)前事件處理函數(shù)是否在dom對(duì)象之中; var event_type = "_" + event_name; if (event_type in dom) { dom[event_type].push(handler_selector); } else { dom[event_type] = [handler_selector]; } // 如果直接用事件名當(dāng)成對(duì)象之中的key值,那么會(huì)和原有的dom功能名稱沖突; // 因?yàn)樘厥獾氖录麜?huì)導(dǎo)致事件無法觸發(fā),所以我們?cè)谶@里要對(duì)事件名進(jìn)行拆分處理; dom.addEventListener(event_name.split(".")[0], handler_selector) } function off(dom, event_name) { // 獲取到dom對(duì)象里面事件名對(duì)應(yīng)的一組事件處理函數(shù); var callback_list = dom["_" + event_name]; // 根據(jù)列表里面的所有函數(shù)進(jìn)行事件移除 ; callback_list.forEach(function (event_handler) { dom.removeEventListener(event_name.split(".")[0], event_handler); }) // 清空dom對(duì)象里面的事件處理函數(shù)組; dom["_" + event_name].length = 0; } function trigger(dom, event_type) { dom.dispatchEvent(new Event(event_type)); } function delegation(dom, event_name, selector, event_handler) { dom.addEventListener(event_name, function (e) { e = e || event; var target = e.target || e.srcElement; while (target !== dom) { switch (selector[0]) { case ".": if (selector.slice(1) === target.className) { event_handler.call(target , e ) return; } case "#": if (selector.slice(1) === target.id) { event_handler.call(target, e) return; } default: if (selector.toUpperCase() === target.nodeName) { event_handler.call(target, e) return; } } target = target.parentNode; } }) } function animate( dom , attrs , callback , transition = "buffer", speed = 10 ){ // transition : 有兩種動(dòng)畫方式 "buffer" , "liner" var _style = getComputedStyle( dom ); // - 1. 數(shù)據(jù)變形 ; for(var attr in attrs ){ attrs[attr] = { target : attrs[attr], now : _style[attr] } // - 2. 速度 : 勻速運(yùn)動(dòng)速度正負(fù) ; if( transition === "liner" ){ attrs[attr].speed = attrs[attr].target > attrs[attr].now ? speed : - speed; } if( attr === "opacity"){ attrs[attr].target *= 100 attrs[attr].now *= 100 }else{ attrs[attr].now = parseInt(attrs[attr].now) } } // - 關(guān)閉開啟定時(shí)器; clearInterval( dom.interval ); dom.interval = setInterval( function(){ for(var attr in attrs ){ // 取出當(dāng)前值和屬性值 ; // attrs[attr].target : 目標(biāo)值; // attrs[attr].now : 當(dāng)前值; let { target , now } = attrs[attr]; // 緩沖運(yùn)動(dòng)時(shí)候的速度; if( transition === "buffer" ){ var speed = (target - now ) / 10 ; speed = speed > 0 ? Math.ceil( speed ) : Math.floor( speed ); }else if(transition === "liner"){ var speed = attrs[attr].speed; } if( Math.abs(target - now) <= Math.abs( speed ) ){ if( attr === "opacity"){ dom.style[attr] = target / 100; }else{ dom.style[attr] = target + "px"; } delete attrs[attr]; for(var attr in attrs ){ // 如果有數(shù)據(jù)循環(huán)會(huì)執(zhí)行至少一次; return false; } clearInterval(dom.interval); typeof callback === "function" ? callback() : ""; }else{ now += speed; if( attr === "opacity"){ dom.style[attr] = now / 100; }else{ dom.style[attr] = now + "px"; } // 給對(duì)象賦值; attrs[attr].now = now; } } } , 30) }
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
JavaScript中第三方庫(kù)Apollo的使用詳解
Apollo 是一個(gè)廣泛使用的 JavaScript 第三方庫(kù),主要用于構(gòu)建與 GraphQL API 交互的應(yīng)用程序,下面就跟隨小編一起來學(xué)習(xí)一下它的具體應(yīng)用吧2024-02-02npm install jquery報(bào)錯(cuò)問題解決
這篇文章主要為大家介紹了npm install jquery報(bào)錯(cuò)問題解決分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-10-10Javascript 頁(yè)面模板化很多人沒有使用過的方法
今天遇到一個(gè)問題,這個(gè)問題也是我以前遇到的問題,以前的方式,也是大多數(shù)人使用的方式。大家可以看看我的文章2012-06-06JavaScript中子函數(shù)訪問外部變量的3種解決方法
任何在函數(shù)中定義的變量,都可認(rèn)為是私有變量,因?yàn)椴荒茉诤瘮?shù)外部訪問這些變量,這篇文章主要給大家介紹了關(guān)于JavaScript中子函數(shù)訪問外部變量的3種解決方法,需要的朋友可以參考下2021-06-06Bootstrap中的Dropdown下拉菜單更改為懸停(hover)觸發(fā)
在使用bootstrap制作響應(yīng)式導(dǎo)航條時(shí),dropdown組件用的比較多,dropdown默認(rèn)鼠標(biāo)左鍵單擊才展開,如果使用鼠標(biāo)放上去(hover)就展開則會(huì)省去點(diǎn)擊時(shí)間,這樣能提高效率,下面小編給大家解答下實(shí)現(xiàn)思路2016-08-08在JavaScript中監(jiān)聽I(yíng)ME鍵盤輸入事件
在 JavaScript 中監(jiān)聽用戶的鍵盤輸入是很容易的事情,但用戶一旦使用了輸入法,問題就變得復(fù)雜了。2011-05-05Javascript hasOwnProperty 方法 & in 關(guān)鍵字
hasOwnProperty :如果 object 具有指定名稱的屬性,那么方法返回 true;反之則返回 false。2008-11-11JavaScript設(shè)計(jì)模式之構(gòu)造函數(shù)模式實(shí)例教程
這篇文章主要介紹了JavaScript設(shè)計(jì)模式之構(gòu)造函數(shù)模式,結(jié)合實(shí)例形式分析了構(gòu)造函數(shù)模式的概念、功能、定義及使用方法,需要的朋友可以參考下2018-07-07