Home  >  Article  >  Web Front-end  >  HTML5 Canvas realizes the special effects of fireworks blooming

HTML5 Canvas realizes the special effects of fireworks blooming

不言
不言Original
2018-07-03 12:00:4618029browse

This is a gorgeous HTML5 Canvas animation. It will simulate the animation special effects of fireworks blooming in our lives. The effect is very realistic. Let's briefly analyze the process and code of implementing this HTML5 fireworks special effect. Interested Friends, you can refer to

This article brings you a free, safe and environmentally friendly fireworks special effect implemented in HTML5 Canvas.

The effect is as follows:

The code is as follows:

<!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">
 </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>

is Don’t be stunned by the powerful effects of HTML5, just feast your eyes on it.

The above is the entire content of this article. I hope it will be helpful to everyone's study. For more related content, please pay attention to the PHP Chinese website!

Related recommendations:

canvas realizes the effect of dynamic ball overlapping code

canvas realizes the effect of love and rainbow rain

Code to use canvas to draw the "Doraemon" clock

##

The above is the detailed content of HTML5 Canvas realizes the special effects of fireworks blooming. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Previous article:Html5 shutter effect codeNext article:Html5 shutter effect code