元宵节到了,我们一起放烟花吧!

582 阅读2分钟

马上就要过元宵节了,可是大城市是不允许燃放烟花这种空气污染的东西的。有没有很想念小时候在自家院子里放花的快乐时光呢。别急,下面就让小编教大家制作程序员的小浪漫----烟火

情景梳理

  1. 烟花都是在天空中绽放,我们用幕布与模拟天空 -- canvas
  2. 烟花绽放时,从一个中心点开始绽放
  3. 烟花绽放时呈“放射状”
  4. 烟花绽放后,会有一个缓慢下落的过程,直至消失

烟花幕布

先新建一个和网页可视区大小一样的canvas,并且通过监听显示区的resize事件,来改变canvas的大小。

var cdom = document.createElement("canvas");
cdom.id = "myCanvas";
cdom.style.position = "fixed";
cdom.style.left = "0";
cdom.style.top = "0";
cdom.style.zIndex = -1;
document.body.appendChild(cdom);

var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
function resizeCanvas() {
  canvas.width = window.innerWidth;
  canvas.height = window.innerHeight;
}
window.addEventListener('resize', resizeCanvas, false);
resizeCanvas();
clearCanvas();
function clearCanvas() {
  context.fillStyle = '#000000';
  context.fillRect(0, 0, canvas.width, canvas.height);
}

烟花粒子

烟花都是从一个点爆炸,伴随着不同的弧度散开,所以我们先绘制几个小圆点,环绕着一个圆心。有点像loading的小圈圈。这其实就是烟花最开始的状态...

document.addEventListener('mousedown', mouseDownHandler, false);

function mouseDownHandler(e) {
  var x = e.clientX;
  var y = e.clientY;

  drawFireworks(x, y);
}

function drawFireworks(sx, sy) {
  var count = 10;//烟花粒子数量
  var radius = 10;//烟花环绕半径

  for (var i = 0; i < count; i++) {
      var angle = 360 / count * i;//烟花粒子角度
      var radians = angle * Math.PI / 180;//烟花粒子弧度

      var vx = sx + Math.cos(radians) * radius;
      var vy = sy + Math.sin(radians) * radius;

      var size = 2;
      context.beginPath();
      context.arc(vx, vy, size, 0, Math.PI * 2, false)
      context.closePath();
      context.fillStyle = "#ff0000";
      context.fill();
  }
}

效果如下

烟花绽放

var radius = 0;
function fire(x, y) {
    createFireworks(x, y);
    function tick() {
        context.globalCompositeOperation = 'source-over';
        context.fillStyle = 'rgba(0,0,0,' + 10 / 100 + ')';
        context.fillRect(0, 0, canvas.width, canvas.height);
        context.globalCompositeOperation = 'lighter';
        drawFireworks();
        radius = requestAnimationFrame(tick);
    }
    cancelAnimationFrame(radius);
    tick();
}

function createFireworks(sx, sy) {
    particles = [];
    var hue = Math.floor(Math.random() * 51) + 150;
    var hueVariance = 30;
    var count = 100;
    for (var i = 0; i < count; i++) {
        var p = {};
        var angle = Math.floor(Math.random() * 360);
        p.radians = angle * Math.PI / 180;
        p.x = sx;
        p.y = sy;
        p.speed = (Math.random() * 5) + .4;
        p.radius = p.speed;
        p.size = Math.floor(Math.random() * 3) + 1;
        p.hue = Math.floor(Math.random() * ((hue + hueVariance) - (hue - hueVariance))) + (hue - hueVariance);
        p.brightness = Math.floor(Math.random() * 31) + 50;
        p.alpha = (Math.floor(Math.random() * 61) + 40) / 100;
        particles.push(p);
    }
}

再修改一下mouseDownHandler函数

function mouseDownHandler(e) {
    var x = e.clientX;
    var y = e.clientY;

    fire(x, y)
}
function drawFireworks(sx, sy) {
  clearCanvas();
  for (var i = 0; i < particles.length; i++) {
      var p = particles[i];
      var vx = Math.cos(p.radians) * p.radius;
      var vy = Math.sin(p.radians) * p.radius + 0.4;
      p.x += vx;
      p.y += vy;
      p.radius *= 1 - p.speed / 300;
      p.alpha -= 0.006;
      context.beginPath();
      context.arc(p.x, p.y, p.size, 0, Math.PI * 2, false);
      context.closePath();
      context.fillStyle = 'hsla(' + p.hue + ', 100%, ' + p.brightness + '%, ' + p.alpha + ')';
      context.fill();
  }
}

效果如下

烟花书签

到这以为就玩了,No。还有更惊喜的,还可以让你在chrome中任意网页实现烟花绽放呢

效果图

源码

javascript: !(function () {
  var cdom = document.createElement("canvas");
  cdom.id = "myCanvas";
  cdom.style.position = "fixed";
  cdom.style.left = "0";
  cdom.style.top = "0";
  cdom.style.zIndex = -1;
  document.body.appendChild(cdom);
  var canvas = document.getElementById('myCanvas');
  var context = canvas.getContext('2d');
  function resizeCanvas() {
      canvas.width = window.innerWidth;
      canvas.height = window.innerHeight;
  }
  window.addEventListener('resize', resizeCanvas, false);
  resizeCanvas();
  clearCanvas();
  function clearCanvas() {
      context.fillStyle = '#000000';
      context.fillRect(0, 0, canvas.width, canvas.height);
  }
  function mouseDownHandler(e) {
      var x = e.clientX;
      var y = e.clientY;
      fire(x, y);
  }
  var rid;
  function fire(x, y) {
      createFireworks(x, y);
      function tick() {
          context.globalCompositeOperation = 'source-over';
          context.fillStyle = 'rgba(0,0,0,' + 10 / 100 + ')';
          context.fillRect(0, 0, canvas.width, canvas.height);
          context.globalCompositeOperation = 'lighter';
          drawFireworks();
          rid = requestAnimationFrame(tick);
      }
      cancelAnimationFrame(rid);
      tick();
  }
  var particles = [];
  function createFireworks(sx, sy) {
      particles = [];
      var hue = Math.floor(Math.random() * 51) + 150;
      var hueVariance = 30;
      var count = 100;
      for (var i = 0; i < count; i++) {
          var p = {};
          var angle = Math.floor(Math.random() * 360);
          p.radians = angle * Math.PI / 180;
          p.x = sx;
          p.y = sy;
          p.speed = (Math.random() * 5) + .4;
          p.radius = p.speed;
          p.size = Math.floor(Math.random() * 3) + 1;
          p.hue = Math.floor(Math.random() * ((hue + hueVariance) - (hue - hueVariance))) + (hue - hueVariance);
          p.brightness = Math.floor(Math.random() * 31) + 50;
          p.alpha = (Math.floor(Math.random() * 61) + 40) / 100;
          particles.push(p);
      }
  }
  function drawFireworks() {
      clearCanvas();
      for (var i = 0; i < particles.length; i++) {
          var p = particles[i];
          var vx = Math.cos(p.radians) * p.radius;
          var vy = Math.sin(p.radians) * p.radius + 0.4;
          p.x += vx;
          p.y += vy;
          p.radius *= 1 - p.speed / 300;
          p.alpha -= 0.006;
          context.beginPath();
          context.arc(p.x, p.y, p.size, 0, Math.PI * 2, false);
          context.closePath();
          context.fillStyle = 'hsla(' + p.hue + ', 100%, ' + p.brightness + '%, ' + p.alpha + ')';
          context.fill();
      }
  }
  document.addEventListener('mousedown', mouseDownHandler, false);
})();

关注

请点赞、关注、收藏小编,惊喜多多哦!