canvas實現煙花燃放效果程式碼例項

antzone發表於2017-03-23

分享一段程式碼例項,它利用canvas實現了煙花燃放效果。

程式碼例項如下:

[HTML] 純文字檢視 複製程式碼執行程式碼
<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="author" content="http://www.softwhy.com/" />
  <title>螞蟻部落</title>
  <style>
    body {
      padding: 0;
      margin: 0;
    }

    canvas {
      display: block;
    }
  </style>
  <script src="http://libs.baidu.com/jquery/1.9.0/jquery.js"></script>
  <script type="text/javascript">
$(function() {
  var canvas = $('#canvas')[0];
  canvas.width = $(window).width();
  canvas.height = $(window).height();
  var ctx = canvas.getContext('2d');

  // init
  ctx.fillStyle = '#000';
  ctx.fillRect(0, 0, canvas.width, canvas.height);
  // objects
  var listFire = [];
  var listFirework = [];
  var fireNumber = 10;
  var center = {
    x: canvas.width / 2,
    y: canvas.height / 2
  };
  var range = 100;
  for (var i = 0; i < fireNumber; i++) {
    var fire = {
      x: Math.random() * range / 2 - range / 4 + center.x,
      y: Math.random() * range * 2 + canvas.height,
      size: Math.random() + 0.5,
      fill: '#fd1',
      vx: Math.random() - 0.5,
      vy: -(Math.random() + 4),
      ax: Math.random() * 0.02 - 0.01,
      far: Math.random() * range + (center.y - range)
    };
    fire.base = {
      x: fire.x,
      y: fire.y,
      vx: fire.vx
    };
    //
    listFire.push(fire);
  }

  function randColor() {
    var r = Math.floor(Math.random() * 256);
    var g = Math.floor(Math.random() * 256);
    var b = Math.floor(Math.random() * 256);
    var color = 'rgb($r, $g, $b)';
    color = color.replace('$r', r);
    color = color.replace('$g', g);
    color = color.replace('$b', b);
    return color;
  }

  (function loop() {
    requestAnimationFrame(loop);
    update();
    draw();
  })();

  function update() {
    for (var index = 0; index < listFire.length; index++) {
      var fire = listFire[index];
      //
      if (fire.y <= fire.far) {
        // case add firework
        var color = randColor();
        for (var index = 0; index < fireNumber * 5; index++) {
          var firework = {
            x: fire.x,
            y: fire.y,
            size: Math.random() + 1.5,
            fill: color,
            vx: Math.random() * 5 - 2.5,
            vy: Math.random() * -5 + 1.5,
            ay: 0.05,
            alpha: 1,
            life: Math.round(Math.random() * range / 2) + range / 2
          };
          firework.base = {
            life: firework.life,
            size: firework.size
          };
          listFirework.push(firework);
        }
        // reset
        fire.y = fire.base.y;
        fire.x = fire.base.x;
        fire.vx = fire.base.vx;
        fire.ax = Math.random() * 0.02 - 0.01;
      }
      //
      fire.x += fire.vx;
      fire.y += fire.vy;
      fire.vx += fire.ax;
    }

    for (var index = listFirework.length - 1; index >= 0; index--) {
      var firework = listFirework[i];
      if (firework) {
        firework.x += firework.vx;
        firework.y += firework.vy;
        firework.vy += firework.ay;
        firework.alpha = firework.life / firework.base.life;
        firework.size = firework.alpha * firework.base.size;
        firework.alpha = firework.alpha > 0.6 ? 1 : firework.alpha;
        //
        firework.life--;
        if (firework.life <= 0) {
          listFirework.splice(index, 1);
        }
      }
    }
  }

  function draw() {
    // clear
    ctx.globalCompositeOperation = 'source-over';
    ctx.globalAlpha = 0.18;
    ctx.fillStyle = '#000';
    ctx.fillRect(0, 0, canvas.width, canvas.height);

    // re-draw
    ctx.globalCompositeOperation = 'screen';
    ctx.globalAlpha = 1;
    for (var index = 0; index < listFire.length; index++) {
      var fire = listFire[index];
      ctx.beginPath();
      ctx.arc(fire.x, fire.y, fire.size, 0, Math.PI * 2);
      ctx.closePath();
      ctx.fillStyle = fire.fill;
      ctx.fill();
    }

    for (var index = 0; index < listFirework.length; index++) {
      var firework = listFirework[index];
      ctx.globalAlpha = firework.alpha;
      ctx.beginPath();
      ctx.arc(firework.x, firework.y, firework.size, 0, Math.PI * 2);
      ctx.closePath();
      ctx.fillStyle = firework.fill;
      ctx.fill();
    }
  }
})
  </script>
</head>
<body>
  <canvas id="canvas"></canvas>
</body>
</html>

相關文章