js:烟花(面向对象)
源码
主页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.container{
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: 10px;
height:10px;
position: absolute;
bottom: 0;
}
</style>
</head>
<body>
<div class="container"></div>
<script src="./animate.js"></script>
<script>
// OOA
// 1.创建元素
// 2.元素运动
// 3.烟花爆炸
// 4.随机位置
// 5.随机颜色
//OOD
function FireWork( x , y , selector){
//优化 单例模式
//每次调用FireWork 都会进行元素选择 , 会导致元素选择次数太多
if(FireWork.main && FireWork.main.selector === selector){
this.main = FireWork.main.ele;
}else{
FireWork.main={
ele : document.querySelector( selector ),
selector : selector
}
this.main = FireWork.main.ele
}
this.init( x , y)
}
FireWork.prototype = {
constructor : FireWork,
init : function(x , y){
this.x = x
this.y = y
//创建元素
this.ele = this.createFireWorkEle();
//获取边界最大值
this.left_max = this.main.offsetWidth - this.ele.offsetWidth
this.top_max = this.main.offsetHeight - this.ele.offsetHeight
//元素运动 主体升起
this.fireWorkup(this.ele);
//随机颜色
this.randomColor(this.ele)
},
// 1.创建元素
createFireWorkEle : function(){
var ele = document.createElement("div")
ele.className = "fire"
this.main.appendChild(ele)
return ele;
},
// 2.元素运动
fireWorkup : function(ele){
ele.style.left = this.x + "px";
animate(ele , {
top : this.y
},function(){
ele.remove();
//直接调用烟花爆炸
this.fireWOrkBlast();
}.bind(this))
},
// 3.烟花爆炸
fireWOrkBlast : function(){
//要创建很多元素
for(var i = 0 ; i < 20 ; i++){
var ele = this.createFireWorkEle();
this.randomColor(ele)
//初始样式设置
ele.style.left = this.x + "px"
ele.style.top = this.y + "px"
ele.style.borderRadius = "50%"
//让元素有运动目标
animate(ele , this.randomBoundary() , function(callback_ele){
callback_ele.remove();
}.bind(this , ele))
}
},
// 4.随机位置
randomBoundary : function(){
return {
left : parseInt(Math.random() * this.left_max + 1),
top : parseInt(Math.random() * this.top_max + 1)
}
},
// 5.随机颜色
randomColor : function( ele ){
return ele.style.backgroundColor = "#" + parseInt(parseInt("ffffff" , 16) * Math.random()).toString(16).padStart(6,0)
}
}
var container_ele = document.querySelector(".container")
container_ele.addEventListener("click" , function(evt){
var e = evt || event ;
new FireWork( e.offsetX , e.offsetY, ".container")
})
</script>
</body>
</html>
元素运动封装函数
animate.js
function animate(ele , attr_options , callback){
for(var attr in attr_options){
attr_options[attr] = {
//目标点 传入的数据
//判断是否是opacity
target : attr === "opacity" ? attr_options[attr] * 100 : attr_options[attr],
//元素当前属性值
iNow : attr === "opacity" ? parseInt( getComputedStyle(ele)[attr] * 100) : parseInt( getComputedStyle(ele)[attr])
}
}
//关闭开启定时器
clearInterval(ele.timer);
ele.timer = setInterval(function(){
//获取 速度 目标值 当前值
for (var attr in attr_options){
var item = attr_options[attr]
var target = item.target ;
var iNow = item.iNow;
//计算速度
var speed = (target - iNow) / 10 ;
//速度取整
speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
//终止条件
if(Math.abs( target - iNow) <= Math.abs(speed)){
ele.style[attr] = attr === "opacity" ? target / 100 : target + "px";
//一条运动完成删除对象里面的数据
delete attr_options[attr];
//如果对象里没有属性了 , 那么我们关闭定时器
for(var num in attr_options){
// 如果attr_options里面有属性,那么此时我就不应该终止定时器;
return false;
}
clearInterval(ele.timer);
typeof callback === "function" ? callback() : "";
}else{
//运动元素
attr_options[attr].iNow += speed ;
ele.style[attr] = attr === "opacity" ? attr_options[attr].iNow / 100 : attr_options[attr].iNow + "px";
}
}
},30)
}