使用HTML5 Canvas模拟Firework爆炸

时间:2017-12-07 14:44:10

标签: javascript html5-canvas

我目前正在尝试学习JavaScript并正在尝试使用canvas动画。我尝试使用canvas创建焰火效果。我使用this source作为参考。

到目前为止,我已经成功创建了一个单一粒子并让它射向天空。但是,我不能让它爆炸...... 我的代码和逻辑有问题吗?我真的很感激,如果有人能够查看我的代码并给我一些建议,我该怎么做才能纠正它。

以下是我的.js代码:

const canvas = document.getElementById('myCanvas');
const context = canvas.getContext('2d');

let w = canvas.width;
let h = canvas.height;
w = window.innerWidth;
h = window.innerHeight;

let particles = [];

class Particle{
  constructor(pos, vel, target){
    // firework animation properties
    this.gravity = 1;
    this.alpha    = 1;
    this.easing   = Math.random() * 0.02;
    this.fade     = Math.random() * 0.1;

    this.pos = {
      x: pos.x || 0,
      y: pos.y || 0
    };

    this.vel = {
      x: vel.x || 0,
      y: vel.y || 0
    };

    this.target = {
      y: target.y || 0
    };

    this.lastPos = {
      x: this.pos.x,
      y: this.pos.y
    };
  }
  update(){
    this.lastPos.x = this.pos.x;
    this.lastPos.y = this.pos.y;

    this.vel.y += this.gravity;
    this.pos.y += this.vel.y;
    this.alpha -= this.fade;

    this.distance = (this.target.y - this.pos.y);

    // ease the position
    this.pos.y += this.distance * (0.03 + this.easing);

    // cap to 1
    this.alpha = Math.min(this.distance * this.distance * 0.00005, 1);

    this.pos.x += this.vel.x;

    return (this.alpha < 0.005);

  }
  draw(){
    let x = Math.round(this.pos.x),
        y = Math.round(this.pos.y),
        xVel = (x - this.lastPos.x) * -5,
        yVel = (y - this.lastPos.y) * -5;

    context.fillStyle = "rgba(255,255,255,0.3)";
    context.beginPath();
    context.moveTo(this.pos.x, this.pos.y);
    context.lineTo(this.pos.x + 1.5, this.pos.y);
    context.lineTo(this.pos.x + xVel, this.pos.y + yVel);
    context.lineTo(this.pos.x - 1.5, this.pos.y);
    context.closePath();
    context.fill();
  }
}

const init = () =>{
  // set canvas size to window size
  onResize();
  document.addEventListener('mouseup', createParticle, true);
  // set off fireworks
  update();
}

const update = () =>{
  // clear up the canvas
  clearCanvas();
  // start the animation loop
  requestAnimFrame(update);
  createFireworks();
}

const createFireworks = () =>{
  for(let i = 0; i < particles.length; i++){
    if(particles[i].update()){
      // kill off the firework, replace it
      // with the particles for the exploded version
      particles.splice(particles.length, 1);
      explodeFireworks(particles[i]);
    }
    particles[i].draw();
  }
  console.log(particles.length);
}

const explodeFireworks = (firework) =>{
  let count = 100;
  let angle = (Math.PI * 2) / count;
  for(let i = 0; i < count; i++){
    let randomVelocity = 4 + Math.random() * 4;
    let particleAngle = count * angle;
    createParticle(
      firework.pos,
      {
        x: Math.cos(particleAngle) * randomVelocity,
        y: Math.sin(particleAngle) * randomVelocity
      },
      null
    );
  }
}

//without parameters create particle, with parameters create firework
const createParticle = (pos, vel, target) =>{
  pos = pos || {};
  vel = vel || {};
  target = target || {};
  particles.push(
    new Particle(
      {
        x: w/2,
        y: h
      },
      {
        x: vel.x || Math.random() * 3 - 1.5,
        y: vel.y || 0
      },
      {
        y: target.y || h/2
      }
    )
  );
}

const clearCanvas = () =>{
  context.clearRect(0,0,canvas.width, canvas.height);
}

const onResize =() => {
  canvas.width = window.innerWidth;
  canvas.height = window.innerHeight;
}

// Simple polyfill for browsers that don't support requestAnimationFrame
window.requestAnimFrame = (function(){
  return  window.requestAnimationFrame       ||
          window.webkitRequestAnimationFrame ||
          window.mozRequestAnimationFrame    ||
          function( callback ){
            window.setTimeout(callback, 1000 / 60);
          };
})();

window.addEventListener('load', init, false);

0 个答案:

没有答案