JS面向对象编程实例——烟花(随即落下)

css样式

/*给box添加样式*/
.box{width:1000px;height:500px;background:black;margin:20px auto;cursor:pointer;position:relative;overflow: hidden}
/*为烟花上升过程中的元素添加样式*/
.box .fire{width:10px;height:10px;position:absolute;bottom:0;}
/*为将来烟花炸开的小元素添加样式*/
.box .s_fire{width:10px;height:10px;position:absolute;border-radius:50%;}

网页结构

//设置一个div模拟夜空,将来点击夜空的时候,烟花从鼠标下方升起,到达点击位置炸开
<div class="box"></div>

JavaScript代码

class Fire{	//利用ES6新增的class构造一个函数,用来模拟烟花上升过程
	constructor(pos){  
		this.cont=document.querySelector(".box");  //选择元素
		this.x=pos.x;		//获取鼠标点击的位置
		this.y=pos.y;
	}
	create(){  		//创建create方法,用来给页面添加元素(烟花上升过程的元素)
		this.f=document.createElement("div");
		this.f.style.background=randomColor();
		this.f.className="fire";
		this.cont.appendChild(this.f);
		this.f.style.left=this.x+"px";   //设置烟花初始位置
		this.move();	//调用move方法运动
	} 
	move(){		//创建move方法,模拟烟花上升的过程
		move(this.f,{top:this.y},()=>{  //调用全局的move函数
			this.f.remove();
			var sum=random(20,30);   //随机生成炸开的小元素个数
			for(var i=0;i<sum;i++){
				var sf=new SmallFire({x:this.x,
					y:this.y,
					cont:this.cont
				});   //创建炸开的小烟花实例,将鼠标点击获取到的位置传到实例中
				sf.create();  //执行创建小烟花的方法
			}
		});
	}
}
class SmallFire{   //构造一个SmallFire函数,模拟烟花炸开效果
	constructor(obj){
		this.x=obj.x;
		this.y=obj.y;
		this.cont=obj.cont; 
	}
	create(){   //创建小烟花的方法
		this.f=document.createElement("div");
		this.f.style.background=randomColor();
		this.f.className="s_fire";
		this.cont.appendChild(this.f);
		this.f.style.left=this.x+"px";  //设置小烟花的初始位置
		this.f.style.top=this.y+"px";
		this.move();   //执行move方法,小烟花开始运动
	}
	move(){
		var speedX=random(-10,10);	//随机生成一个数字,表示烟花每一次的运动的距离
		var speedY=random(-10,10);
		this.f.t=setInterval(()=>{  //开启一个计时器,实现烟花的加速效果
			if(this.f.offsetTop>this.cont.offsetHight){
				clearInterval(this.f.t);  //如果烟花超出了背景,清除计时器,并删除对应的小烟花
				this.f.remove();
			}else{		
				//如果没有超出,根据随机生成的距离移动
				this.f.style.left=this.f.offsetLeft+speedX+"px";
				//在移动过程中,将垂直方向的值不断增大,形成重力加速效果
				this.f.style.top=this.f.offsetTop+speedY++ +"px";
			}
		},30)
	}
}
var ocont=document.querySelector(".box");
ocont.onclick=function(eve){	//给夜空添加点击事件
	var e=eve||window.event;
	var x=e.pageX-ocont.offsetLeft;		//获取鼠标点击是,相对于夜空的位置
	var y=e.pageY-ocont.offsetTop;
	var f=new Fire({x:x,y:y});	//将获取到的位置传给Fire函数
	f.create();	//执行Fire函数中的creat方法,创建上升烟花的元素
}
	
function random(a,b){	//封装一个随机数函数,在随机生成颜色的函数中调用
	return Math.round(Math.random()*(a-b)+b);
}
function randomColor(){	//封装一个随机颜色的函数
	return `rgb(${random(0,255)},${random(0,255)},${random(0,255)})`;
}
function move(ele,obj,cb){	//封装一个move方法,实现缓冲运动效果
    clearInterval(ele.t);
    ele.t = setInterval(() => {
        // 假设状态为:可以清除计时器
        var i = true;
        // 因为在计时器中才开始使用到对象中的信息,所以在计时器中遍历
        // 并提前换来的属性和目标变量
        for(var attr in obj){
            var iNow = parseInt(getStyle(ele,attr));
            }
            let speed = (obj[attr] - iNow)/10;
            speed = speed < 0 ? Math.floor(speed) : Math.ceil(speed);
            if(iNow !== obj[attr]){
                i = false;
            }
            ele.style[attr] = iNow + speed + "px";
        }
        // 如果每次计时器执行结束,所有属性都执行了一遍之后,状态还是true,表示,没有被改成false,如果没有被改成false,表示没有属性没到终点,那么状态还是false就不清除
        if(i){
            clearInterval(ele.t);
            // 用户决定在动画结束时要执行的功能,万一用户没传参,做个默认判断
            cb && cb();
        }
    }, 30);
}

function getStyle(ele,attr){	//用来获取页面元素的属性
    if(ele.currentStyle){
        return ele.currentStyle[attr];
    }else{
        return getComputedStyle(ele,false)[attr];
    }
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值