js面向对象之烟花效果

这个和之前一样,都是用到了多属性运动函数的。
烟花散开呈现的圆形的效果
在这里插入图片描述
CSS部分

	<style>
		#box{
		    width: 80%;
		    height: 600px;
		    border: 2px solid red;
		    background: #000;
		    margin:20px auto;
		    cursor: pointer;
		    position: relative;
		    left: 0;
		    top: 0;
			overflow: hidden;
		}
		.fire{
		    width: 20px;
		    height:20px;
		    position: absolute;
		    bottom: 0;
		}
		.small-fire{
		    width: 20px;
		    height:20px;
		    position: absolute;
		    border-radius: 50%;
		}
	</style>

html部分,,,,就一个框。。。。

引用下方的js文件

JS部分
var obox = document.querySelector("#box");
obox.onclick = function(eve){
var e = eve || window.event;
// 需要将鼠标点击的位置、box元素都传入到new构造函数中
new mainFire({
box:obox, //将obox传入,生成的主体烟花插入到obox中
x:e.pageX-obox.offsetLeft, //
y:e.pageY-obox.offsetTop //page 避免可视问题
});
}

	// OOP:
	
	function mainFire(options){
		// 将传入的三个参数与构造函数建立连接
		this.obox = options.box;
		this.x = options.x;
		this.y = options.y;
		
		this.addFire();
	}
	
	mainFire.prototype.addFire = function(){
		this.f = document.createElement("div");
		this.f.className = "fire";
		this.obox.appendChild(this.f);
		this.f.style.background = "red";
		//主体烟花初始位置为距离obox的left,== obox.offsetX;
		var l = this.x  -this.f.offsetWidth/2+ "px";
		
		this.f.style.left = l;
	
		this.move();
	}
	
	mainFire.prototype.move = function(){
	// 	//利用多属性运动move(),改变主体烟花的top距离为 obox.offsetY
	// 	//move()中传入回调函数,再执行删除主体烟花,创建小烟花
		move(this.f,{top:this.y-this.f.offsetHeight/2},()=>{
			this.f.remove();
			this.smallFire();
		})
		
	// 	var that = this;
	// 	move(this.f,{top:this.y},function(){
	// 		//可以用箭头函数,this指向上层,即指向实例,
	// 		that.f.remove();
	// 		that.smallFire();
	// 	});
	
	}
	mainFire.prototype.smallFire = function(){
		// 随机创建小烟花个数
		var num = random(5,10);
		//定义随机圆的半径
		var r = random(100,200);
		// console.log(num);
		for(var i = 0;i<num;i++){
			// 使用let声明变量。每次都是独立的区域。使每次循环一次,拿到一次i的值。每个都是独立的
			let s = document.createElement("div");
			this.obox.appendChild(s);
			s.className = "small-fire";
			// console.log(s.offsetWidth)
			s.style.left = this.x -s.offsetWidth/2 + "px";
			s.style.top = this.y - s.offsetHeight/2 + "px";
			s.style.background = "yellow";
			s.setAttribute("index",i);
			//小烟花爆炸的目标位置
			var target = {
                x:parseInt(Math.cos( Math.PI/180 * (360/num*i) ) * r) + this.x - s.offsetWidth/2,
                y:parseInt(Math.sin( Math.PI/180 * (360/num*i) ) * r) + this.y - s.offsetHeight/2 
			}
			// /fireworks
			// x = Math.sin(Math.PI/180*deg) * r 
			// y = Math.cos(Math.PI/180*deg) * r 
			// deg = (360 / 小烟花个数 * 第几个小烟花)	第几个小烟花的角度
			// 需要parseInt取整,因为每个小烟花的位置不一定是整数,没到达目标时就会一直在动。
			move(s,{
				left:target.x,
				top:target.y
			},()=>{
				//箭头函数没有自己的this,
				s.remove();
			})
		}
	}
	// 随机数
	function random(max,min){
		return Math.round(Math.random()*(max-min)+min);
	}

封装的多属性运动函数,直接引用到js中就行了。

		//data传入一个对象,key对应ele的样式属性,value对应ele的属性值,callback回调函数
		function move(ele, data, callback) {
			clearInterval(ele.t);
			//将for in 放入计时器中,节省性能,每次计时器开启,再进行for in的操作。
			ele.t = setInterval(function() {
				//1、设置目标到达状态
				var mySwitch = true;
				//for..in遍历对象,i为样式attr,data[i]为对象的value; 对应目标值target
				for (var i in data) {
					//获取元素的当前样式
					var iNow = parseInt(getStyle(ele, i));
					//设置步长(每次改变的值),每次为现在值和目标值的十分之一,speed永远不会为0
					var speed = (data[i] - iNow) / 10;
					//判断步长,小于0向下取整,大于0向上取整
					// if (speed < 0) {
					// 	speed = Math.floor(speed);
					// } else {
					// 	speed = Math.ceil(speed);
					// }
					// 下方简写
					speed = speed < 0 ? Math.floor(speed) : Math.ceil(speed);
					//开启之后,关闭之前,作一个判断
					//2、当有一个属性没到达目标时,改变状态,不清除计时器
					if (iNow != data[i]) {
						mySwitch = false;
					}
					ele.style[i] = iNow + speed + "px";
				}
				//3、(for循环结束)所有目标达到状态时清除计时器
				if (mySwitch) {
					//清除计时器,动画结束
					clearInterval(ele.t);
					//如果传入了callback,就执行。如果没有这个就不执行
					callback && callback();
				}
			}, 30)
		}


		//获取样式兼容写法
		function getStyle(ele, attr) {
			if (getComputedStyle) {
				return getComputedStyle(ele, false)[attr]; //false表示非伪元素
			} else {
				return ele.currentStyle[attr];
			}
		}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值