煙花效果(Canvas和Proton)

最近看了不少的煙花效果,我本身的感受就是代碼不是很難,只是須要對它的原理好好理解一下。咱們都知道一個煙花從發射到炸裂通過的幾個階段,以及這些過程當中涉及到了那些東西。那些量會對最後的炸開效果有影響,咱們首相應該把這些量考慮好,以後才能上手去寫這個程序,我不知道第一我的是怎麼寫出的可是我看出基本上全部的煙花效果都是那幾個量,沒什麼區別只是有一些具體的值的大小可能不同。下面我就分享一下我從網上找的一段代碼:javascript

這個煙花效果是自動隨機產生煙花,不是咱們控制的,相對比較簡單。css

  1 <!DOCTYPE html>
  2 <html>
  3 
  4 <head>
  5     <meta charset="utf-8">
  6     <title>Canvas煙花</title>
  7     <meta name="description" content="">
  8     <meta name="keywords" content="">
  9     <link href="" rel="stylesheet">
 10     <style type="text/css">
 11         body {
 12             padding: 0;
 13             margin: 0;
 14             background: #000;
 15         }
 16     </style>
 17 </head>
 18 
 19 <body>
 20     <canvas id="canvas">Canvas is not supported in your browser.</canvas> 
 21     <script type="text/javascript">
 22         window.requestAnimationFrame = (function() {
 23             return window.requestAnimationFrame ||
 24                 window.webkitRequestAnimationFrame ||
 25                 window.mozRequestAnimationFrame ||
 26                 function(callback) {
 27                     window.setTimeout(callback, 1000 / 60); //每秒60幀
 28                 }
 29         })();
 30 
 31         var canvas = document.getElementById("canvas"),
 32             ctx = canvas.getContext("2d"),
 33             cw = window.innerWidth,
 34             ch = window.innerHeight,
 35             fireworks = [], //煙花數組
 36             particles = [], //煙花爆炸屑數字
 37             hue = 120, //初始色調0/360 紅色 120 綠色240 藍色
 38             timerTotal = 80, //每隔80下釋放一次煙花
 39             timerTick = 0;
 40 
 41         canvas.width = cw;
 42         canvas.height = ch;
 43 
 44         // 生成隨機數
 45         function random(min, max) {
 46             return Math.random() * (max - min) + min;
 47         }
 48         // 計算點(sx,sy)到點(tx,ty)之間的距離
 49         function caculateDistance(sx, sy, tx, ty) {
 50             var xDistance = sx - tx,
 51                 yDistance = sy - ty;
 52             return Math.sqrt(Math.pow(xDistance, 2) + Math.pow(yDistance, 2));
 53         }
 54         // 煙花對象(sx,sy)初始位置(tx,ty)目標位置
 55         function Firework(sx, sy, tx, ty) {
 56             this.x = sx; //實時運行座標x
 57             this.y = sy; //實時運行座標y
 58             this.sx = sx; //初始位置座標x
 59             this.sy = sy; //初始位置座標y
 60             this.tx = tx; //目標位置座標x
 61             this.ty = ty; //目標位置座標y
 62             this.distanceToTarget = caculateDistance(sx, sy, tx, ty); //計算初始位置到目標位置之間的距離
 63             this.distanceTraveled = 0; //已運行距離
 64             this.coordinates = []; //這是一個輔助變量,用於生成實時運行軌跡
 65             this.coordinatesCount = 3;
 66             while (this.coordinatesCount--) {
 67                 this.coordinates.push([this.x, this.y]);
 68             }
 69             this.angle = Math.atan2(ty - sy, tx - sx); //初始位置和目標位置之間的角度
 70             this.speed = 2; //初始速度
 71             this.acceleration = 1.05 //加速度
 72             this.brightness = random(50, 70); //明度
 73             this.targetRadius = 1; //目標位置標示圓圈的初始半徑
 74         }
 75         // 更新煙花的位置
 76         Firework.prototype.update = function(index) {
 77             this.coordinates.pop();
 78             this.coordinates.unshift([this.x, this.y]);
 79             // 上面是一個技巧吧 先將數組最後一個移除,而後將當前煙花位置插入到第一個,那數組最後一個座標和更新以後的座標之間就造成了一條軌跡
 80             // 讓目標標示處圓圈動起來
 81             if (this.targetRadius < 8) {
 82                 this.targetRadius += 0.3;
 83             } else {
 84                 this.targetRadius = 1;
 85             }
 86             this.speed *= this.acceleration; //根據加速度變換速度
 87             var vx = Math.cos(this.angle) * this.speed, //計算水平方向速度
 88                 vy = Math.sin(this.angle) * this.speed; //計算垂直方向速度
 89             this.distanceTraveled = caculateDistance(this.sx, this.sy, this.x + vx, this.y + vy); //從新計算煙花已運行的距離
 90             // 若是煙花運行距離大於或等於初始位置到目標之間的距離,生成新煙花並移除當前煙花,不然更新煙花位置
 91             if (this.distanceTraveled >= this.distanceToTarget) {
 92                 createParticles(this.tx, this.ty);
 93                 fireworks.splice(index, 1);
 94             } else {
 95                 this.x += vx;
 96                 this.y += vy;
 97             }
 98         }
 99 
100         Firework.prototype.draw = function() {
101                 // 畫出煙花運行軌跡
102                 ctx.beginPath();
103                 ctx.moveTo(this.coordinates[this.coordinates.length - 1][0], this.coordinates[this.coordinates.length - 1][1]);
104                 ctx.lineTo(this.x, this.y);
105                 ctx.strokeStyle = 'hsl(' + hue + ',100%,' + this.brightness + '%)';
106                 ctx.stroke();
107                 // 畫出目標位置的小圓圈
108                 ctx.beginPath();
109                 ctx.arc(this.tx, this.ty, this.targetRadius, 0, Math.PI * 2);
110                 ctx.stroke();
111             }
112             // 煙花爆炸屑對象
113         function Particle(x, y) {
114             this.x = x;
115             this.y = y;
116             this.coordinates = [];
117             this.coordinatesCount = 5;
118             while (this.coordinatesCount--) {
119                 this.coordinates.push([this.x, this.y]);
120             }
121             this.angle = random(0, 2 * Math.PI); //生成任意方向的碎屑
122             this.speed = random(1, 10); //隨機速度
123             this.friction = 0.95 //摩擦力
124             this.gravity = 1; //重力
125             this.hue = random(hue - 20, hue + 20); //生成與煙花色彩相近的碎屑
126             this.brightness = random(50, 80); //隨機明度
127             this.alpha = 1; //初始透明度
128             this.decay = random(0.015, 0.03); //碎屑小時的時間
129         }
130 
131         Particle.prototype.update = function(index) {
132             this.coordinates.pop();
133             this.coordinates.unshift([this.x, this.y]);
134             // 上面是一個技巧吧,先將數組最後一個移除,而後將當前煙花位置插入到第一個,那數組最後一個
135             // 元素和更新以後的座標就造成了一條軌跡
136             this.speed *= this.friction;
137             this.x += Math.cos(this.angle) * this.speed;
138             this.y += Math.sin(this.angle) * this.speed + this.gravity;
139             this.alpha -= this.decay;
140             if (this.alpha <= this.decay) {
141                 particles.splice(index, 1);
142             }
143         }
144 
145         Particle.prototype.draw = function() {
146             ctx.beginPath();
147             ctx.moveTo(this.coordinates[this.coordinates.length - 1][0], this.coordinates[this.coordinates.length - 1][1]);
148             ctx.lineTo(this.x, this.y);
149             ctx.strokeStyle = 'hsla(' + this.hue + ',100%,' + this.brightness + '%,' + this.alpha + ')';
150             ctx.stroke();
151         }
152 
153         function createParticles(x, y) {
154             // 生成30個煙花碎屑
155             var particleCount = 30;
156             while (particleCount--) {
157                 particles.push(new Particle(x, y));
158             }
159         }
160 
161         function loop() {
162             // 流暢的動畫過程
163             requestAnimationFrame(loop);
164             hue += 0.5;
165             ctx.globalCompositeOperation = 'destination-out';
166             ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';
167             ctx.fillRect(0, 0, cw, ch);
168             ctx.globalCompositeOperation = 'lighter';
169             var i = fireworks.length;
170             while (i--) {
171                 fireworks[i].draw();
172                 fireworks[i].update(i);
173             }
174             var i = particles.length;
175             while (i--) {
176                 particles[i].draw();
177                 particles[i].update(i);
178             }
179             if (timerTick >= timerTotal) {
180                 fireworks.push(new Firework(cw / 2, ch, random(0, cw), random(0, ch / 2)));
181                 timerTick = 0;
182             } else {
183                 timerTick++;
184             }
185         }
186         window.onload = loop;
187     </script>
188 </body>
189 
190 </html>

下面還有一段代碼也是一個煙花效果,不過這個是一個更加完善的煙花效果,它是咱們鼠標點擊哪里哪里就產生煙花。html

  1 <!DOCTYPE html>
  2 <!-- saved from url=http://keyup.cn -->
  3 <html>
  4 
  5 <head>
  6     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  7 
  8     <meta content="width=device-width,height=device-height,inital-scale=1.0,maximum-scale=1.0,user-scalable=no" name="viewport">
  9 
 10     <meta name="apple-mobile-web-app-capable" content="yes">
 11 
 12     <meta name="apple-mobile-web-app-status-bar-style" content="black">
 13 
 14     <title>放煙花嘍-前端開發知識</title>
 15 
 16     <style type="text/css">
 17         html,
 18         body {
 19             height: 100%;
 20             margin: 0;
 21             padding: 0
 22         }
 23 
 24         ul,
 25         li {
 26             text-indent: 0;
 27             text-decoration: none;
 28             margin: 0;
 29             padding: 0
 30         }
 31 
 32         img {
 33             border: 0
 34         }
 35 
 36         body {
 37             background-color: #000;
 38             color: #999;
 39             font: 100%/18px helvetica, arial, sans-serif
 40         }
 41 
 42         canvas {
 43             cursor: crosshair;
 44             display: block;
 45             left: 0;
 46             position: absolute;
 47             top: 0;
 48             z-index: 20
 49         }
 50 
 51         #header img {
 52             width: 100%;
 53             height: 20%;
 54         }
 55 
 56         #bg img {
 57             width: 100%;
 58             height: 80%;
 59         }
 60 
 61         #header,
 62         #bg {
 63             position: fixed;
 64             left: 0;
 65             right: 0;
 66             z-index: 10
 67         }
 68 
 69         #header {
 70             top: 0
 71         }
 72 
 73         #bg {
 74             position: fixed;
 75             z-index: 1;
 76         }
 77 
 78         audio {
 79             position: fixed;
 80             display: none;
 81             bottom: 0;
 82             left: 0;
 83             right: 0;
 84             width: 100%;
 85             z-index: 5
 86         }
 87     </style>
 88 
 89     <!-- <link rel="shortcut icon" type="image/x-icon" href=""> -->
 90 
 91     <style type="text/css"></style>
 92     <style id="style-1-cropbar-clipper">
 93         .en-markup-crop-options {
 94             top: 18px !important;
 95             left: 50% !important;
 96             margin-left: -100px !important;
 97             width: 200px !important;
 98             border: 2px rgba(255, 255, 255, .38) solid !important;
 99             border-radius: 4px !important;
100         }
101 
102         .en-markup-crop-options div div:first-of-type {
103             margin-left: 0px !important;
104         }
105     </style>
106 </head>
107 
108 <body>
109     <div id="bg"><img id="bgimg" src="a1.jpg"></div>
110     <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
111     <script type="text/javascript">
112         $(function() {
113             var Fireworks = function() {
114                 var self = this;
115                 var rand = function(rMi, rMa) {
116                     return ~~((Math.random() * (rMa - rMi + 1)) + rMi);
117                 }
118                 var hitTest = function(x1, y1, w1, h1, x2, y2, w2, h2) {
119                     return !(x1 + w1 < x2 || x2 + w2 < x1 || y1 + h1 < y2 || y2 + h2 < y1);
120                 };
121                 window.requestAnimFrame = function() {
122                     return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(a) {
123                         window.setTimeout(a, 1E3 / 60)
124                     }
125                 }();
126 
127                 self.init = function() {
128                     self.canvas = document.createElement('canvas');
129                     // cw:畫布的寬 ch:畫布的高
130                     self.canvas.width = self.cw = $(window).innerWidth();
131                     self.canvas.height = self.ch = $(window).innerHeight();
132                     // 自身的粒子
133                     self.particles = [];//煙花爆炸屑的數字
134                     self.partCount = 250;//煙花的數量
135                     self.fireworks = []; //煙花數組
136                     self.mx = self.cw / 2;
137                     self.my = self.ch / 2;
138                     self.currentHue = 30;// 當前色調
139                     self.partSpeed = 5; // 煙花散開的速度
140                     self.partSpeedVariance = 10; // 加速度
141                     self.partWind = 50; // 煙花散開以後的一個曲線值
142                     self.partFriction = 5; // 摩擦力
143                     self.partGravity = 1; // 重力
144                     self.hueMin = 0; // 最小色調
145                     self.hueMax = 360; // 最大色調
146                     self.fworkSpeed = 4; // 煙花子彈的速度
147                     self.fworkAccel = 10; //煙花子彈加速度
148                     self.hueVariance = 80; //色調的多樣性
149                     self.flickerDensity = 25; //閃光密度
150                     self.showShockwave = true; //
151                     self.showTarget = false; //
152                     self.clearAlpha = 25; //阿爾法通道值即透明度值
153 
154                     // 設置畫板的一些參數
155                     $(document.body).append(self.canvas);
156                     self.ctx = self.canvas.getContext('2d');
157                     self.ctx.lineCap = 'round';
158                     self.ctx.lineJoin = 'round';
159                     self.lineWidth = 1;
160                     self.bindEvents();
161                     self.canvasLoop();
162 
163                     self.canvas.onselectstart = function() {
164                         return false;
165                     };
166                 };
167                 // 建立煙花炸屑
168                 self.createParticles = function(x, y, hue) {
169                     var countdown = self.partCount;
170                     while (countdown--) {
171                         var newParticle = {
172                             x: x,
173                             y: y,
174                             coordLast: [{
175                                 x: x,
176                                 y: y
177                             }, {
178                                 x: x,
179                                 y: y
180                             }, {
181                                 x: x,
182                                 y: y
183                             }],
184                             // 角度
185                             angle: rand(0, 360),
186                             // 速度
187                             speed: rand(((self.partSpeed - self.partSpeedVariance) <= 0) ? 1 : self.partSpeed - self.partSpeedVariance, (self.partSpeed + self.partSpeedVariance)),
188                             // 摩擦力
189                             friction: 1 - self.partFriction / 100,
190                             // 重力
191                             gravity: self.partGravity / 2,
192                             // 色調
193                             hue: rand(hue - self.hueVariance, hue + self.hueVariance),
194                             // 明亮度
195                             brightness: rand(50, 80),
196                             // 加速度
197                             alpha: rand(40, 100) / 100,
198                             // 衰退
199                             decay: rand(10, 50) / 1000,
200                             // 彎曲度
201                             wind: (rand(0, self.partWind) - (self.partWind / 2)) / 25,
202                             // 線寬
203                             lineWidth: self.lineWidth
204                         };
205                         self.particles.push(newParticle);
206                     }
207                 };
208 
209                 // 上升的煙花彈
210                 self.updateParticles = function() {
211                     var i = self.particles.length;
212                     while (i--) {
213                         var p = self.particles[i];
214                         // 定義弧度
215                         var radians = p.angle * Math.PI / 180;
216                         // x軸速度
217                         var vx = Math.cos(radians) * p.speed;
218                         // y軸速度
219                         var vy = Math.sin(radians) * p.speed;
220                         // 速度等於自身乘上摩擦力
221                         p.speed *= p.friction;
222 
223                         // 我不是很理解這一段尤爲是coordLast但願懂得人能給解釋一下
224                         p.coordLast[2].x = p.coordLast[1].x;
225                         p.coordLast[2].y = p.coordLast[1].y;
226                         p.coordLast[1].x = p.coordLast[0].x;
227                         p.coordLast[1].y = p.coordLast[0].y;
228                         p.coordLast[0].x = p.x;
229                         p.coordLast[0].y = p.y;
230 
231                         // 這裏主要是座標的變化
232                         p.x += vx;
233                         p.y += vy;
234                         p.y += p.gravity;
235 
236                         // 這裏主要是角度的變化公式和透明度的改變
237                         p.angle += p.wind;
238                         p.alpha -= p.decay;
239                         // hitTest 碰撞檢測
240                         if (!hitTest(0, 0, self.cw, self.ch, p.x - p.radius, p.y - p.radius, p.radius * 2, p.radius * 2) || p.alpha < .05) {
241                             self.particles.splice(i, 1);
242                         }
243                     };
244                 };
245 
246                 self.drawParticles = function() {
247                     var i = self.particles.length;
248                     while (i--) {
249                         var p = self.particles[i];
250 
251                         var coordRand = (rand(1, 3) - 1);
252                         self.ctx.beginPath();
253                         self.ctx.moveTo(Math.round(p.coordLast[coordRand].x), Math.round(p.coordLast[coordRand].y));
254                         self.ctx.lineTo(Math.round(p.x), Math.round(p.y));
255                         self.ctx.closePath();
256                         self.ctx.strokeStyle = 'hsla(' + p.hue + ', 100%, ' + p.brightness + '%, ' + p.alpha + ')';
257                         self.ctx.stroke();
258 
259                         if (self.flickerDensity > 0) {
260                             var inverseDensity = 50 - self.flickerDensity;
261                             if (rand(0, inverseDensity) === inverseDensity) {
262                                 self.ctx.beginPath();
263                                 self.ctx.arc(Math.round(p.x), Math.round(p.y), rand(p.lineWidth, p.lineWidth + 3) / 2, 0, Math.PI * 2, false)
264                                 self.ctx.closePath();
265                                 var randAlpha = rand(50, 100) / 100;
266                                 self.ctx.fillStyle = 'hsla(' + p.hue + ', 100%, ' + p.brightness + '%, ' + randAlpha + ')';
267                                 self.ctx.fill();
268                             }
269                         }
270                     };
271                 };
272 
273 
274                 self.createFireworks = function(startX, startY, targetX, targetY) {
275                     var newFirework = {
276                         x: startX,
277                         y: startY,
278                         startX: startX,
279                         startY: startY,
280                         hitX: false,
281                         hitY: false,
282                         coordLast: [{
283                             x: startX,
284                             y: startY
285                         }, {
286                             x: startX,
287                             y: startY
288                         }, {
289                             x: startX,
290                             y: startY
291                         }],
292                         targetX: targetX,
293                         targetY: targetY,
294                         speed: self.fworkSpeed,
295                         angle: Math.atan2(targetY - startY, targetX - startX),
296                         shockwaveAngle: Math.atan2(targetY - startY, targetX - startX) + (90 * (Math.PI / 180)),
297                         acceleration: self.fworkAccel / 100,
298                         hue: self.currentHue,
299                         brightness: rand(50, 80),
300                         alpha: rand(50, 100) / 100,
301                         lineWidth: self.lineWidth
302                     };
303                     self.fireworks.push(newFirework);
304 
305                 };
306 
307 
308                 self.updateFireworks = function() {
309                     var i = self.fireworks.length;
310 
311                     while (i--) {
312                         var f = self.fireworks[i];
313                         self.ctx.lineWidth = f.lineWidth;
314 
315                         vx = Math.cos(f.angle) * f.speed,
316                             vy = Math.sin(f.angle) * f.speed;
317                         f.speed *= 1 + f.acceleration;
318                         f.coordLast[2].x = f.coordLast[1].x;
319                         f.coordLast[2].y = f.coordLast[1].y;
320                         f.coordLast[1].x = f.coordLast[0].x;
321                         f.coordLast[1].y = f.coordLast[0].y;
322                         f.coordLast[0].x = f.x;
323                         f.coordLast[0].y = f.y;
324 
325                         if (f.startX >= f.targetX) {
326                             if (f.x + vx <= f.targetX) {
327                                 f.x = f.targetX;
328                                 f.hitX = true;
329                             } else {
330                                 f.x += vx;
331                             }
332                         } else {
333                             if (f.x + vx >= f.targetX) {
334                                 f.x = f.targetX;
335                                 f.hitX = true;
336                             } else {
337                                 f.x += vx;
338                             }
339                         }
340 
341                         if (f.startY >= f.targetY) {
342                             if (f.y + vy <= f.targetY) {
343                                 f.y = f.targetY;
344                                 f.hitY = true;
345                             } else {
346                                 f.y += vy;
347                             }
348                         } else {
349                             if (f.y + vy >= f.targetY) {
350                                 f.y = f.targetY;
351                                 f.hitY = true;
352                             } else {
353                                 f.y += vy;
354                             }
355                         }
356 
357                         if (f.hitX && f.hitY) {
358                             self.createParticles(f.targetX, f.targetY, f.hue);
359                             self.fireworks.splice(i, 1);
360 
361                         }
362                     };
363                 };
364 
365                 self.drawFireworks = function() {
366                     var i = self.fireworks.length;
367                     self.ctx.globalCompositeOperation = 'lighter';
368                     while (i--) {
369                         var f = self.fireworks[i];
370                         self.ctx.lineWidth = f.lineWidth;
371 
372                         var coordRand = (rand(1, 3) - 1);
373                         self.ctx.beginPath();
374                         self.ctx.moveTo(Math.round(f.coordLast[coordRand].x), Math.round(f.coordLast[coordRand].y));
375                         self.ctx.lineTo(Math.round(f.x), Math.round(f.y));
376                         self.ctx.closePath();
377                         self.ctx.strokeStyle = 'hsla(' + f.hue + ', 100%, ' + f.brightness + '%, ' + f.alpha + ')';
378                         self.ctx.stroke();
379 
380                         if (self.showTarget) {
381                             self.ctx.save();
382                             self.ctx.beginPath();
383                             self.ctx.arc(Math.round(f.targetX), Math.round(f.targetY), rand(1, 8), 0, Math.PI * 2, false)
384                             self.ctx.closePath();
385                             self.ctx.lineWidth = 1;
386                             self.ctx.stroke();
387                             self.ctx.restore();
388                         }
389 
390                         if (self.showShockwave) {
391                             self.ctx.save();
392                             self.ctx.translate(Math.round(f.x), Math.round(f.y));
393                             self.ctx.rotate(f.shockwaveAngle);
394                             self.ctx.beginPath();
395                             self.ctx.arc(0, 0, 1 * (f.speed / 5), 0, Math.PI, true);
396                             self.ctx.strokeStyle = 'hsla(' + f.hue + ', 100%, ' + f.brightness + '%, ' + rand(25, 60) / 100 + ')';
397                             self.ctx.lineWidth = f.lineWidth;
398                             self.ctx.stroke();
399                             self.ctx.restore();
400                         }
401                     };
402                 };
403 
404                 self.bindEvents = function() {
405                     $(window).on('resize', function() {
406                         clearTimeout(self.timeout);
407                         self.timeout = setTimeout(function() {
408                             self.canvas.width = self.cw = $(window).innerWidth();
409                             self.canvas.height = self.ch = $(window).innerHeight();
410                             self.ctx.lineCap = 'round';
411                             self.ctx.lineJoin = 'round';
412                         }, 100);
413                     });
414 
415                     $(self.canvas).on('mousedown', function(e) {
416                         self.mx = e.pageX - self.canvas.offsetLeft;
417                         self.my = e.pageY - self.canvas.offsetTop;
418                         self.currentHue = rand(self.hueMin, self.hueMax);
419                         self.createFireworks(self.cw / 2, self.ch, self.mx, self.my);
420 
421                         $(self.canvas).on('mousemove.fireworks', function(e) {
422                             self.mx = e.pageX - self.canvas.offsetLeft;
423                             self.my = e.pageY - self.canvas.offsetTop;
424                             self.currentHue = rand(self.hueMin, self.hueMax);
425                             self.createFireworks(self.cw / 2, self.ch, self.mx, self.my);
426                         });
427                     });
428 
429                     $(self.canvas).on('mouseup', function(e) {
430                         $(self.canvas).off('mousemove.fireworks');
431                     });
432 
433                 }
434 
435                 self.clear = function() {
436                     self.particles = [];
437                     self.fireworks = [];
438                     self.ctx.clearRect(0, 0, self.cw, self.ch);
439                 };
440 
441 
442                 self.canvasLoop = function() {
443                     requestAnimFrame(self.canvasLoop, self.canvas);
444                     self.ctx.globalCompositeOperation = 'destination-out';
445                     self.ctx.fillStyle = 'rgba(0,0,0,' + self.clearAlpha / 100 + ')';
446                     self.ctx.fillRect(0, 0, self.cw, self.ch);
447                     self.updateFireworks();
448                     self.updateParticles();
449                     self.drawFireworks();
450                     self.drawParticles();
451 
452                 };
453 
454                 self.init();
455 
456             }
457             var fworks = new Fireworks();
458 
459         });
460     </script>
461     <script type="text/javascript">
462         $(document).ready(function() {
463             setTimeout(function() {
464                 $("#header").hide("slow");
465             }, 2000);
466         });
467     </script>
468 </body>
469 
470 </html>

這個煙花效果更加好一些,而且咱們能夠經過修改function init()裏邊的值來調整最後的效果,我改了一些最後產生了很炫的效果,大家能夠試試。咱們還能夠將這些值換成變量,咱們能夠弄幾個input經過value來傳咱們具體的值這樣咱們就能很隨意的看咱們想看的效果。這個我這裏就不試了。前端

下面是一個插件實現的煙花效果:java

下面我主要是推薦一個HTML5的粒子引擎,它就是Proton粒子引擎,官網:http://a-jie.github.io/Proton/,裏邊有不少的效果,這是它裏邊的煙花效果:http://a-jie.github.io/Proton/example/sparks/firework/fireworks.html,基本的代碼以下:jquery

  1 <!DOCTYPE HTML>
  2 <html>
  3 
  4 <head>
  5     <title>proton.js-game-fireworks</title>
  6     <meta charset="utf-8">
  7     <style type="text/css">
  8         body {
  9             font-family: Monospace;
 10             background-color: #f0f0f0;
 11             margin: 0px;
 12             overflow: hidden;
 13         }
 14 
 15         #testCanvas {
 16             background: #000000;
 17         }
 18     </style>
 19 </head>
 20 
 21 <body>
 22     <canvas id="testCanvas"></canvas>
 23     <script src="stats.min.js"></script>
 24     <script src="proton-2.1.0.min.js"></script>
 25     <script>
 26         var canvas;
 27         var context;
 28         var proton;
 29         var renderer;
 30         var emitter;
 31         var stats;
 32 
 33         Main();
 34 
 35         function Main() {
 36             canvas = document.getElementById("testCanvas");
 37             canvas.width = window.innerWidth;
 38             canvas.height = window.innerHeight;
 39             context = canvas.getContext('2d');
 40             //context.globalCompositeOperation = "lighter";
 41             addStats();
 42 
 43             createProton();
 44             tick();
 45         }
 46 
 47         function addStats() {
 48             stats = new Stats();
 49             stats.setMode(2);
 50             stats.domElement.style.position = 'absolute';
 51             stats.domElement.style.left = '0px';
 52             stats.domElement.style.top = '0px';
 53             document.body.appendChild(stats.domElement);
 54         }
 55 
 56         function createProton(image) {
 57             proton = new Proton;
 58             emitter = new Proton.Emitter();
 59             emitter.rate = new Proton.Rate(new Proton.Span(1, 3), 1);
 60             emitter.addInitialize(new Proton.Mass(1));
 61             emitter.addInitialize(new Proton.Radius(2, 4));
 62             emitter.addInitialize(new Proton.P(new Proton.LineZone(10, canvas.height, canvas.width - 10, canvas.height)));
 63             emitter.addInitialize(new Proton.Life(1, 1.5));
 64             emitter.addInitialize(new Proton.V(new Proton.Span(4, 6), new Proton.Span(0, 0, true), 'polar'));
 65             emitter.addBehaviour(new Proton.Gravity(1));
 66             emitter.addBehaviour(new Proton.Color('#ff0000', 'random'));
 67             emitter.emit();
 68             proton.addEmitter(emitter);
 69 
 70             renderer = new Proton.Renderer('canvas', proton, canvas);
 71             renderer.onProtonUpdate = function() {
 72                 context.fillStyle = "rgba(0, 0, 0, 0.1)";
 73                 context.fillRect(0, 0, canvas.width, canvas.height);
 74             };
 75             renderer.start();
 76 
 77             ////NOTICE :you can only use two emitters do this effect.In this demo I use more emitters want to test the emtter's life
 78             emitter.addEventListener(Proton.PARTICLE_DEAD, function(particle) {
 79                 if (Math.random() < .7)
 80                     createFirstEmitter(particle);
 81                 else
 82                     createSecendEmitter(particle);
 83             });
 84         }
 85 
 86         function createFirstEmitter(particle) {
 87             var subemitter = new Proton.Emitter();
 88             subemitter.rate = new Proton.Rate(new Proton.Span(250, 300), 1);
 89             subemitter.addInitialize(new Proton.Mass(1));
 90             subemitter.addInitialize(new Proton.Radius(1, 2));
 91             subemitter.addInitialize(new Proton.Life(1, 3));
 92             subemitter.addInitialize(new Proton.V(new Proton.Span(2, 4), new Proton.Span(0, 360), 'polar'));
 93             subemitter.addBehaviour(new Proton.RandomDrift(10, 10, .05));
 94             subemitter.addBehaviour(new Proton.Alpha(1, 0));
 95             subemitter.addBehaviour(new Proton.Gravity(3));
 96             var color = Math.random() > .3 ? Proton.MathUtils.randomColor() : 'random';
 97             subemitter.addBehaviour(new Proton.Color(color));
 98             subemitter.p.x = particle.p.x;
 99             subemitter.p.y = particle.p.y;
100             subemitter.emit('once', true);
101             proton.addEmitter(subemitter);
102         }
103 
104         function createSecendEmitter(particle) {
105             var subemitter = new Proton.Emitter();
106             subemitter.rate = new Proton.Rate(new Proton.Span(100, 120), 1);
107             subemitter.addInitialize(new Proton.Mass(1));
108             subemitter.addInitialize(new Proton.Radius(4, 8));
109             subemitter.addInitialize(new Proton.Life(1, 2));
110             subemitter.addInitialize(new Proton.V([1, 2], new Proton.Span(0, 360), 'polar'));
111             subemitter.addBehaviour(new Proton.Alpha(1, 0));
112             subemitter.addBehaviour(new Proton.Scale(1, .1));
113             subemitter.addBehaviour(new Proton.Gravity(1));
114             var color = Proton.MathUtils.randomColor();
115             subemitter.addBehaviour(new Proton.Color(color));
116             subemitter.p.x = particle.p.x;
117             subemitter.p.y = particle.p.y;
118             subemitter.emit('once', true);
119             proton.addEmitter(subemitter);
120         }
121 
122         function tick() {
123             requestAnimationFrame(tick);
124 
125             stats.begin();
126             proton.update();
127             stats.end();
128         }
129     </script>
130 </body>
131 
132 </html>

這裏邊主要用了倆個插件就是proton-2.1.0.min.js和stats.min.js,這倆都是倆個對象,引入代碼包以後對插件的一些屬性進行設置就能夠了,其中這個proton-2.1.0.min.js裏邊包含了不少特效,包括:火花,遊戲,渲染效果,文字效果帶等。感興趣的能夠看看,十分強大,效果十分炫。這款插件用法很簡單,做爲前端人員很快就能掌握。git

這是官網給出的用法:github

 1 var proton = new Proton();
 2 var emitter = new Proton.Emitter();
 3 //set Rate
 4 emitter.rate = new Proton.Rate(Proton.getSpan(10, 20), 0.1);
 5 //add Initialize
 6 emitter.addInitialize(new Proton.Radius(1, 12));
 7 emitter.addInitialize(new Proton.Life(2, 4));
 8 emitter.addInitialize(new Proton.Velocity(3, Proton.getSpan(0, 360), 'polar'));
 9 //add Behaviour
10 emitter.addBehaviour(new Proton.Color('ff0000', 'random'));
11 emitter.addBehaviour(new Proton.Alpha(1, 0));
12 //set emitter position
13 emitter.p.x = canvas.width / 2;
14 emitter.p.y = canvas.height / 2;
15 emitter.emit();
16 //add emitter to the proton
17 proton.addEmitter(emitter);
18 // add canvas renderer
19 var renderer = new Proton.Renderer('canvas', proton, canvas);
20 renderer.start();

 前端有不少很強大的插件,從此的博客中我還會介紹我認爲很強大的一些,還有具體的用法。web

相關文章
相關標籤/搜索