JS 面向對象 實現煙花特效


基本效果如圖:

  

  這里的煙花特效 是配合鼠標點擊去實現的  (你要是想綁定別的事件也可)

  1. 創建一個煙花,從底部升起運動到目標位置
  2. 到達目標位置之后,刪除它的同時 炸出一堆煙花

 

HTML布局+CSS樣式

    <div class="container"></div>
 1     <style>
 2         .container{
 3             width: 80%;
 4             height: 300px;
 5             border: 2px solid red;
 6             background: #000;
 7             margin:20px auto;
 8             cursor: pointer;
 9             position: relative;
10             left: 0;
11             top: 0;
12             overflow: hidden;
13         }
14         .fire{
15             width: 10px;
16             height:10px;
17             position: absolute;
18             bottom: 0;
19         }
20     </style>

JavaScript 代碼

  1     <script>
  2     // OOA
  3         // 1.創建一個煙花元素
  4         // 2.元素運動 運動結束之后刪除
  5         // 3.煙花爆炸 循環多個煙花  爆炸之后也要刪除
  6         // 4.隨機位置
  7         // 5.煙花的隨機顏色
  8     // OOD
  9         // function Firework(x,y){
 10         //     this.init(x,y);
 11         // }
 12         
 13         // Firework.prototype = {
 14         //     constructor : Firework,
 15         //     // 初始化
 16         //     init : function(x,y){//xy是目標位置
 17         //         // 創建元素
 18         //         // 元素運動  把目標點當做參數x、y
 19         //         // 調用函數
 20 
 21         //     },
 22         //     // 1.創建元素
 23         //     createFireWorkEle : function(){
 24 
 25         //     },
 26         //     // 2.元素運動
 27         //     fireWorkUp : function(ele){
 28         //         // 2部分運動 left直接到達、top運動達到
 29         //     },
 30         //     // 3.煙花爆炸
 31         //     fireWorkBlast : function(){
 32         //         // 3.1創建非常多的元素
 33         //     },
 34         //     // 4.隨機位置
 35         //     randomBoundary : function(){
 36 
 37         //     },
 38         //     // 5.隨機顏色
 39         //     randomColor : function(ele){
 40 
 41         //     }
 42         // }
 43 
 44     // OOP
 45         function Firework(x,y , selector){
 46             // 選擇父級元素
 47             this.main = document.querySelector(selector);
 48             
 49             this.init(x,y);
 50         }
 51         
 52         Firework.prototype = {
 53             constructor : Firework,
 54             // 初始化
 55             init : function(x,y){
 56                 //x、y是點擊事件創建的煙花的位置
 57                 this.x = x;
 58                 this.y = y;
 59 
 60                 // 創建元素
 61                 this.ele = this.createFireWorkEle();
 62                 // 爆炸煙花的隨機位置 最大值
 63                 this.left_max = this.main.offsetWidth - this.ele.offsetWidth;
 64                 this.top_max = this.main.offsetHeight - this.ele.offsetHeight;
 65 
 66                 // 元素添加背景色
 67                 this.randomColor(this.ele);
 68                 // 煙花主體升起
 69                 this.fireWorkUp(this.ele );
 70                 // 煙花爆炸
 71                 this.fireWorkBlast(this.ele);
 72             },
 73             // 1.創建元素
 74             createFireWorkEle : function(){
 75                 // 往containe里面放進一個煙花fire
 76                 var ele = document.createElement("div");
 77                 ele.className = "fire";
 78                 // 在頁面顯示 
 79                 this.main.appendChild(ele);
 80                 return ele;
 81             },
 82             // 2.元素運動
 83             fireWorkUp : function(ele){
 84                 // 兩部分的運動 left直接到達、top運動達到
 85                 ele.style.left = this.x + "px";
 86                 animate(ele, {top : this.y} , function(){
 87                     // 煙花運動結束后 要刪除它
 88                     // console.log(this);//這時候指向windoe,用bind修改指向
 89                     ele.remove();
 90                     // 然后調用煙花爆炸
 91                     this.fireWorkBlast();
 92                 }.bind(this));
 93             },
 94             // 3.煙花爆炸
 95             fireWorkBlast : function(){
 96                 // 3.1創建非常多的元素
 97                 for(var i = 0 ; i < 20 ; i ++){
 98                     var ele = this.createFireWorkEle();
 99                     this.randomColor(ele);
100                     // 3.1初始樣式設置
101                     ele.style.left = this.x + "px";
102                     ele.style.top = this.y + "px";
103                     // 和點擊之后創建的煙花 區分開
104                     ele.style.borderRadius = "50%";
105                     // 3.3讓元素有運動目標
106                     animate(ele , this.randomBoundary(ele) , function(callback_ele){
107                         // 爆炸之后刪除所有元素
108                         // 用bind 給每個匿名函數都綁定一個ele。否則只會刪除最后一個ele
109                         callback_ele.remove();
110                     }.bind(this , ele));
111                 }
112             },
113             // 4.隨機位置
114             randomBoundary : function(){
115                 // min 是0 
116                 // max中offset性能消耗大,所以放在init()里,只獲取一次即可
117                 return{
118                     left : parseInt(Math.random()*(this.left_max + 1)),
119                     top : parseInt(Math.random()*(this.top_max + 1))
120                 }
121             },
122             // 5.隨機顏色
123             randomColor : function(ele){
124                 // 隨機顏色方法很多
125                 var r = parseInt(256 * Math.random());
126                 var g = parseInt(256 * Math.random());
127                 var b = parseInt(256 * Math.random());
128                 var random_color = "rgb("+r + "," + g + "," + b +")";
129                 return ele.style.backgroundColor = random_color;
130                 
131             }
132         }
133 
134         document.querySelector(".container").addEventListener("click",function(evt){
135             var e = evt || event;
136             new Firework(e.offsetX , e.offsetY , ".container");
137         })
138     </script>

<script>引入的 "animate.js"  運動封裝

 

 1 //               元素,屬性,回調函數(動畫執行結束,調用這個函數)
 2 function animate( ele , attr_options , callback ){
 3     // 獲取當前屬性
 4     for(var attr in attr_options){
 5         // 同時判斷是否是opacity屬性
 6         attr_options[attr] = {
 7             // 目標點(傳入的數據)
 8             target : attr === "opacity" ? attr_options[attr] * 100 : attr_options[attr],
 9             // 元素當前的屬性值
10             iNow   : attr === "opacity" ? parseInt( getComputedStyle(ele)[attr] * 100 ) : parseInt( getComputedStyle(ele)[attr])
11         }
12     }
13     // 定時器的開啟和關閉
14     clearInterval( ele.timer );
15     ele.timer = setInterval( function(){
16         // 獲取運動所必須的值
17         for(var attr in attr_options){
18             // 取出每一條數據
19             var item = attr_options[attr];
20             // console.log(item , attr);//target和iNow , "屬性名"
21             var target = item.target;
22             var iNow   = item.iNow;
23             // 計算速度
24             var speed = (target - iNow) / 10;
25             // 速度取整
26             speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
27             // 運動的終止條件  
28             // (目標 - 當前位置) 的絕對值 <= 速度 , 此時判定已經到達
29             if( Math.abs( target - iNow) <= Math.abs(speed) ){
30                 // 送他到底目標點
31                 ele.style[attr] = attr === "opacity" ? target / 100 :  target + "px";
32                 // if里的終止條件不嚴謹:
33                 // 因為目標的不一致會讓運動次數執行不同,有可能會提前關閉定時器
34                 // 解決辦法:完成一條運動后 刪除對象里的數據
35                 delete attr_options[attr];
36             
37                 for(var num in attr_options){
38                     // 如果attr_options里面有屬性,不終止定時器
39                     return false;
40                 }
41                 // 如果對象里面沒有屬性了,就可以關閉定時器
42                 clearInterval(ele.timer);
43                 // 可能會不傳callback
44                 typeof callback === "function" ? callback() : "";
45             }else{
46                 // 元素繼續運動
47                 // 如果直接設置iNow 每次循環iNow都會被重置,iNow是一個臨時變量
48                 // 所以不能去操作iNow,要去操作iNow的數據源
49                 attr_options[attr].iNow += speed;
50                 ele.style[attr] = attr === "opacity" ? attr_options[attr].iNow / 100 : attr_options[attr].iNow + "px";
51             }
52         }
53     } , 30)
54 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM