网络编程
位置:首页>> 网络编程>> JavaScript>> JavaScript实现烟花特效(面向对象)

JavaScript实现烟花特效(面向对象)

作者:山河不识  发布时间:2024-02-26 22:44:50 

标签:js,烟花

本文实例为大家分享了JavaScript实现烟花特效的具体代码,供大家参考,具体内容如下

本特效使用面向对象编程

分析

OOA

  • 点击触发事件

  • 烟花运动分成两个阶段

          向上飞
           *

OOD


class FireWork{
   constructor(){

}
   bindEvent(){
       let _this = this;
       ele.onclick = function(){
           //fly结束再去调用boom函数
           _this.fly(_this.boom);
       }
   }
   fly(boom){

}
   boom(){

}
}

CSS设计实现

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编程实现

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对象里面建立一个事件名 : 事件处理函数对应的数组;
   // 判定当前事件处理函数是否在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, 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 : 有两种动画方式 "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)
}

来源:https://blog.csdn.net/ZeroEQ/article/details/119836994

0
投稿

猜你喜欢

手机版 网络编程 asp之家 www.aspxhome.com