1. 程式人生 > 程式設計 >JavaScript實現煙花特效(面向物件)

JavaScript實現煙花特效(面向物件)

本文例項為大家分享了實現煙花特效的具體程式碼,供大家參考,具體內容如下

本特效使用面向物件

分析

OOA

  • 點選觸發事件
  • 煙花運動分成兩個階段

向上飛
爆炸

OOD

class FireWork{
    constructor(){
        
    }
    bindEvent(){
        let _this = this;
        ele.onclick = function(){
            //fly結束再去呼叫boom函式
            _this.fly(_this.boom);
        }
    }
    fly(boom){
        
    }
    boom(){
        
    }
}

設計實現

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;
    }

程式設計實現

script程式碼

<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;
        lhttp://www.cppcns.com
et 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,delegation_handler);
    }
    // 在dom物件裡面建立一個事件名 : 事件處理函式對應的陣列; 
    // 判定當前事件處理函式是否在dom物件之中;
    var event_type = "_" + event_name;
    if (event_type in dom) {
        dom[event_type].push(handler_selector);
    } else {
        dom[event_type] = [handler_selector];
    }
    // 如果直接用事件名當成物件之中的key值,那麼會和原有的dom功能名稱衝突; 
    // 因為特殊的事件名會導致事件無法觸發,所以我們在這裡要對事件名進行拆分處理; 
    dom.addEventListener(event_name.split(".")[0],handler_selector)
}
function off(dom,event_name) {
    // 獲取到dom物件裡面事件名對應的一組事件處理函式; 
    var callback_list = dom["_" + event_name];
    // 根據列表裡面的所有函式進行事件移除 ; 
    callback_list.forEach(function (event_handler) {
        dom.removeEventListener(event_name.split(".")[0],event_handler);
    })
    // 清空dom物件裡面的事件處理函式組; 
    dom["_" + event_name].length = 0;
}
    
function trigger(dom,event_type) {
    dom.dispatchEvent(new Event(event_type));
}
    
function delegation(dom,shttp://www.cppcns.comelector,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) === targethttp://www.cppcns.com.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 : 有兩種動畫方式 "buffer","liner"
    var _style = getComputedStyle( dom );
    
    // - 1. 資料變形 ; 
    for(var attr in attrs ){
        attrs[attr] = {
              target : attrs[attr],now    : _style[attr]
        }
        // - 2. 速度 : 勻速運動速度正負 ; 
        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) 
        }
    }
    // - 關閉開啟定時器;    
    clearInterval( dom.interval );
    dom.interval = setInterval( function(){
        for(var attr in attrs ){
              // 取出當前值和屬性值 ; 
              // attrs[attr].target : 目標值; 
              // attrs[attr].now    : 當前值; 
    
              let { target,now } = attrs[attr];
    
              // 緩衝運動時候的速度; 
              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 ){
                          // 如果有資料迴圈會執行至少一次; 
                          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";
                    }
                    // 給物件賦值; 
                    attrs[attr].now = now;
              }
        }
    },30)
}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。