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