PHP前端开发

HTML5 Canvas实现烟花绽放的特效

百变鹏仔 3个月前 (10-18) #H5教程
文章标签 烟花

这是一个款绚丽的html5 canvas动画,它将模拟的是我们生活中烟花绽放的动画特效,效果非常逼真,下面我们来简单分析一下实现这款html5烟花特效的过程及代码,感兴趣的小伙伴们可以参考一下

本文为大家带来了一款,免费而又安全环保的HTML5 Canvas实现的放烟花特效。

效果如下:

代码如下:

立即学习“前端免费学习笔记(深入)”;

<!DOCTYPE HTML><html>  <head>    <title>Canvas 实现放烟花特效</title> <meta charset="utf-8">    <meta http-equiv="X-UA-Compatible" content="IE=edge">    <meta name="viewport" content="width=device-width,height=device-height,inital-scale=1.0,maximum-scale=1.0,user-scalable=no">    <style type="text/css">  html,body{height:100%;margin:0;padding:0}     ul,li{text-indent:0;text-decoration:none;margin:0;padding:0}     img{border:0}     body{background-color:#000;color:#999;font:100%/18px helvetica, arial, sans-serif}     canvas{cursor:crosshair;display:block;left:0;position:absolute;top:0;z-index:20}     #header img{width:100%; height:20%;}     #bg img{width:100%; height:80%;}     #header,#bg{position:fixed;left:0;right:0;z-index:10}     #header{top:0}     #bg{position:fixed;z-index:1;bottom:0}     audio{position:fixed;display:none;bottom:0;left:0;right:0;width:100%;z-index:5}    </style>  </head>  <body> <p id="bg">  <img  id="bgimg" src="http://img.ivsky.com/img/tupian/pre/201508/02/yuzhou_xingkong_yu_yueliang-006.jpg" alt="HTML5 Canvas实现烟花绽放的特效" > </p> <script src="http://cdn.bootcss.com/jquery/2.2.0/jquery.min.js"></script> <script>  $(function(){      var Fireworks = function(){       var self = this;       // 产生烟花随机数       var rand = function(rMi, rMa){        //按位取反运算符        return ~~((Math.random()*(rMa-rMi+1))+rMi);       },hitTest = function(x1, y1, w1, h1, x2, y2, w2, h2){        return !(x1 + w1 < x2 || x2 + w2 < x1 || y1 + h1 < y2 || y2 + h2 < y1);       };       //请求动画帧       window.requestAnimFrame=function(){        return window.requestAnimationFrame         ||window.webkitRequestAnimationFrame         ||window.mozRequestAnimationFrame         ||window.oRequestAnimationFrame         ||window.msRequestAnimationFrame         ||function(callback){          window.setTimeout(callback,1000/60);         }       }();       self.init = function(){         self.canvas = document.createElement(&#39;canvas&#39;);          //canvas 全屏        selfself.canvas.width = self.cw = $(window).innerWidth();        selfself.canvas.height = self.ch = $(window).innerHeight();          self.particles = [];         self.partCount = 150;        self.fireworks = [];         selfself.mx = self.cw/2;        selfself.my = self.ch/2;        self.currentHue = 30;        self.partSpeed = 5;        self.partSpeedVariance = 10;        self.partWind = 50;        self.partFriction = 5;        self.partGravity = 1;        self.hueMin = 0;        self.hueMax = 360;        self.fworkSpeed = 4;        self.fworkAccel = 10;        self.hueVariance = 30;        self.flickerDensity = 25;        self.showShockwave = true;        self.showTarget = false;        self.clearAlpha = 25;        $(document.body).append(self.canvas);        selfself.ctx = self.canvas.getContext(&#39;2d&#39;);        self.ctx.lineCap = &#39;round&#39;;        self.ctx.lineJoin = &#39;round&#39;;        self.lineWidth = 1;        self.bindEvents();           self.canvasLoop();        self.canvas.onselectstart = function() {         return false;        };       };         // 创建粒子       self.createParticles = function(x,y, hue){        var countdown = self.partCount;        while(countdown--){         var newParticle = {          x: x,          y: y,          coordLast: [           {x: x, y: y},           {x: x, y: y},           {x: x, y: y}          ],          angle: rand(0, 360),          speed: rand(((self.partSpeed - self.partSpeedVariance) <= 0) ? 1 : self.partSpeed - self.partSpeedVariance, (self.partSpeed + self.partSpeedVariance)),          friction: 1 - self.partFriction/100,          gravity: self.partGravity/2,          hue: rand(hue-self.hueVariance, hue+self.hueVariance),          brightness: rand(50, 80),          alpha: rand(40,100)/100,          decay: rand(10, 50)/1000,          wind: (rand(0, self.partWind) - (self.partWind/2))/25,          lineWidth: self.lineWidth         };             self.particles.push(newParticle);        }       };       // 更新粒子       self.updateParticles = function(){        var i = self.particles.length;        while(i--){         var p = self.particles[i];         var radians = p.angle * Math.PI / 180;         var vx = Math.cos(radians) * p.speed;         var vy = Math.sin(radians) * p.speed;         p.speed *= p.friction;         p.coordLast[2].x = p.coordLast[1].x;         p.coordLast[2].y = p.coordLast[1].y;         p.coordLast[1].x = p.coordLast[0].x;         p.coordLast[1].y = p.coordLast[0].y;         p.coordLast[0].x = p.x;         p.coordLast[0].y = p.y;         p.x += vx;         p.y += vy;         p.y += p.gravity;         p.angle += p.wind;             p.alpha -= p.decay;         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){               self.particles.splice(i, 1);          }        };       };       // 绘制粒子       self.drawParticles = function(){        var i = self.particles.length;        while(i--){         var p = self.particles[i];                var coordRand = (rand(1,3)-1);         self.ctx.beginPath();                 self.ctx.moveTo(Math.round(p.coordLast[coordRand].x), Math.round(p.coordLast[coordRand].y));         self.ctx.lineTo(Math.round(p.x), Math.round(p.y));         self.ctx.closePath();             self.ctx.strokeStyle = &#39;hsla(&#39;+p.hue+&#39;, 100%, &#39;+p.brightness+&#39;%, &#39;+p.alpha+&#39;)&#39;;         self.ctx.stroke();             if(self.flickerDensity > 0){          var inverseDensity = 50 - self.flickerDensity;               if(rand(0, inverseDensity) === inverseDensity){           self.ctx.beginPath();           self.ctx.arc(Math.round(p.x), Math.round(p.y), rand(p.lineWidth,p.lineWidth+3)/2, 0, Math.PI*2, false)           self.ctx.closePath();           var randrandAlpha = rand(50,100)/100;           self.ctx.fillStyle = &#39;hsla(&#39;+p.hue+&#39;, 100%, &#39;+p.brightness+&#39;%, &#39;+randAlpha+&#39;)&#39;;           self.ctx.fill();          }          }        };       };       // 创建烟花           self.createFireworks = function(startX, startY, targetX, targetY){        var newFirework = {         x: startX,         y: startY,         startX: startX,         startY: startY,         hitX: false,         hitY: false,         coordLast: [          {x: startX, y: startY},          {x: startX, y: startY},          {x: startX, y: startY}         ],         targetX: targetX,         targetY: targetY,         speed: self.fworkSpeed,         angle: Math.atan2(targetY - startY, targetX - startX),         shockwaveAngle: Math.atan2(targetY - startY, targetX - startX)+(90*(Math.PI/180)),         acceleration: self.fworkAccel/100,         hue: self.currentHue,         brightness: rand(50, 80),         alpha: rand(50,100)/100,         lineWidth: self.lineWidth        };           self.fireworks.push(newFirework);       };       // 更新烟花       self.updateFireworks = function(){        var i = self.fireworks.length;        while(i--){         var f = self.fireworks[i];         self.ctx.lineWidth = f.lineWidth;         vx = Math.cos(f.angle) * f.speed,         vy = Math.sin(f.angle) * f.speed;         f.speed *= 1 + f.acceleration;             f.coordLast[2].x = f.coordLast[1].x;         f.coordLast[2].y = f.coordLast[1].y;         f.coordLast[1].x = f.coordLast[0].x;         f.coordLast[1].y = f.coordLast[0].y;         f.coordLast[0].x = f.x;         f.coordLast[0].y = f.y;         if(f.startX >= f.targetX){          if(f.x + vx <= f.targetX){           ff.x = f.targetX;           f.hitX = true;          } else {           f.x += vx;          }         } else {          if(f.x + vx >= f.targetX){           ff.x = f.targetX;           f.hitX = true;          } else {           f.x += vx;          }         }         if(f.startY >= f.targetY){          if(f.y + vy <= f.targetY){           ff.y = f.targetY;           f.hitY = true;          } else {           f.y += vy;          }         } else {          if(f.y + vy >= f.targetY){           ff.y = f.targetY;           f.hitY = true;          } else {           f.y += vy;          }         }             if(f.hitX && f.hitY){          self.createParticles(f.targetX, f.targetY, f.hue);          self.fireworks.splice(i, 1);         }        };       };       // 绘制烟花       self.drawFireworks = function(){        var i = self.fireworks.length;        self.ctx.globalCompositeOperation = &#39;lighter&#39;;        while(i--){         var f = self.fireworks[i];           self.ctx.lineWidth = f.lineWidth;         var coordRand = (rand(1,3)-1);              self.ctx.beginPath();                self.ctx.moveTo(Math.round(f.coordLast[coordRand].x), Math.round(f.coordLast[coordRand].y));         self.ctx.lineTo(Math.round(f.x), Math.round(f.y));         self.ctx.closePath();         self.ctx.strokeStyle = &#39;hsla(&#39;+f.hue+&#39;, 100%, &#39;+f.brightness+&#39;%, &#39;+f.alpha+&#39;)&#39;;         self.ctx.stroke();          if(self.showTarget){          self.ctx.save();          self.ctx.beginPath();          self.ctx.arc(Math.round(f.targetX), Math.round(f.targetY), rand(1,8), 0, Math.PI*2, false)          self.ctx.closePath();          self.ctx.lineWidth = 1;          self.ctx.stroke();          self.ctx.restore();         }         if(self.showShockwave){          self.ctx.save();          self.ctx.translate(Math.round(f.x), Math.round(f.y));          self.ctx.rotate(f.shockwaveAngle);          self.ctx.beginPath();          self.ctx.arc(0, 0, 1*(f.speed/5), 0, Math.PI, true);          self.ctx.strokeStyle = &#39;hsla(&#39;+f.hue+&#39;, 100%, &#39;+f.brightness+&#39;%, &#39;+rand(25, 60)/100+&#39;)&#39;;          self.ctx.lineWidth = f.lineWidth;          self.ctx.stroke();          self.ctx.restore();         }        };       };       // 绑定事件       self.bindEvents = function(){        $(window).on(&#39;resize&#39;, function(){            clearTimeout(self.timeout);         self.timeout = setTimeout(function() {          selfself.canvas.width = self.cw = $(window).innerWidth();          selfself.canvas.height = self.ch = $(window).innerHeight();          self.ctx.lineCap = &#39;round&#39;;          self.ctx.lineJoin = &#39;round&#39;;         }, 100);        });        $(self.canvas).on(&#39;mousedown&#39;, function(e){         self.mx = e.pageX - self.canvas.offsetLeft;         self.my = e.pageY - self.canvas.offsetTop;         self.currentHue = rand(self.hueMin, self.hueMax);         self.createFireworks(self.cw/2, self.ch, self.mx, self.my);          $(self.canvas).on(&#39;mousemove.fireworks&#39;, function(e){          self.mx = e.pageX - self.canvas.offsetLeft;          self.my = e.pageY - self.canvas.offsetTop;          self.currentHue = rand(self.hueMin, self.hueMax);          self.createFireworks(self.cw/2, self.ch, self.mx, self.my);                  });            });        $(self.canvas).on(&#39;mouseup&#39;, function(e){         $(self.canvas).off(&#39;mousemove.fireworks&#39;);                 });       };       self.clear = function(){        self.particles = [];        self.fireworks = [];        self.ctx.clearRect(0, 0, self.cw, self.ch);       };       self.canvasLoop = function(){        requestAnimFrame(self.canvasLoop, self.canvas);           self.ctx.globalCompositeOperation = &#39;destination-out&#39;;        self.ctx.fillStyle = &#39;rgba(0,0,0,&#39;+self.clearAlpha/100+&#39;)&#39;;        self.ctx.fillRect(0,0,self.cw,self.ch);        self.updateFireworks();        self.updateParticles();        self.drawFireworks();           self.drawParticles();       };       self.init();        }      var fworks = new Fireworks();      $(&#39;#info-toggle&#39;).on(&#39;click&#39;, function(e){       $(&#39;#info-inner&#39;).stop(false, true).slideToggle(100);       e.preventDefault();      });      });    </script> <canvas width="1400" height="449"></canvas>  </body></html>

是不是被HTML5强大的效果惊呆了,一饱眼福了吧。