繁体   English   中英

如何在5秒后停止此画布动画绘制新粒子并在点击时从零粒子重新启动它?

[英]How can I stop this canvas animation drawing new particles after 5 seconds and restart it from zero particles on click?

我想在5秒后停止绘制新粒子,并在任何地方点击重新开始绘图。

这是动画的代码https://codepen.io/Jeremboo/pen/ENVaMY

现在它一直在绘制,直到你点击屏幕再次重新启动它。

我想要的是在5秒后停止绘制然后点击任何地方从零粒子重新启动它。 我尝试了以下停止,但我无法再次启动它。

这是js代码

/**/ const canvas = document.createElement('canvas');
/**/ const context = canvas.getContext('2d');
/**/ let windowWidth = canvas.width = window.innerWidth;
/**/ let windowHeight = canvas.height = window.innerHeight;
/**/ canvas.id = 'canvas';
/**/ document.body.insertBefore(canvas, document.body.firstChild);
/**/ /* ---- CORE END ---- */
/* ---- CREATING ZONE ---- */

/* ---- SETTINGS ---- */
const numberParticlesStart = 1000;
const particleSpeed = 0.3;
const velocity = 0.9;
const circleWidth = 50;

/* ---- INIT ---- */
let particles = [];

const getRandomFloat = (min, max) => (Math.random() * (max - min) + min);


/* ---- Particle ---- */
function Particle (x, y) {
  this.x = x;
  this.y = y;

  this.vel = {
    x : getRandomFloat(-20, 20)/100,
    y : getRandomFloat(-20, 20)/100,
    min : getRandomFloat(2, 10),
    max : getRandomFloat(10, 100)/10
  }

  this.color = 'rgba(255, 255, 255, 0.05)';
}
Particle.prototype.render = function() {
  context.beginPath();
  context.fillStyle = this.color;
  context.arc(this.x, this.y, 1, 0, Math.PI * 2);
  context.fill();
};
Particle.prototype.update = function() {

  const forceDirection = {
    x: getRandomFloat(-1, 1),
    y: getRandomFloat(-1, 1),
  };

  if (Math.abs(this.vel.x + forceDirection.x) < this.vel.max) {
    this.vel.x += forceDirection.x;
  }
  if (Math.abs(this.vel.y + forceDirection.y) < this.vel.max) {
    this.vel.y += forceDirection.y;
  }

  this.x += this.vel.x * particleSpeed;
  this.y += this.vel.y * particleSpeed;

  if (Math.abs(this.vel.x) > this.vel.min) {
    this.vel.x *= velocity;
  }
  if (Math.abs(this.vel.y) > this.vel.min) {
    this.vel.y *= velocity;
  }

  this.testBorder();
};
Particle.prototype.testBorder = function() {
  if (this.x > windowWidth) {
    this.setPosition(this.x, 'x');
  } else if (this.x < 0) {
    this.setPosition(windowWidth, 'x');
  }
  if (this.y > windowHeight) {
    this.setPosition(this.y, 'y');
  } else if (this.y < 0) {
    this.setPosition(windowHeight, 'y');
  }
};
Particle.prototype.setPosition = function(pos, coor) {
  if (coor === 'x') {
    this.x = pos;
  } else if (coor === 'y') {
    this.y = pos;
  }
};

/* ---- Functions ----*/
function loop() {
  let i;
  const length = particles.length;
  for (i = 0; i < length; i++) {
    particles[i].update();
    particles[i].render();
  }
  requestAnimationFrame(loop);
}

/* ---- START ---- */
function init() {
  let i;
  for (i = 0; i < numberParticlesStart; i++) {
    const angle = Math.random() * 360;
    particles.push(new Particle(
      windowWidth * 0.5 + (Math.cos(angle) * circleWidth),
      windowHeight * 0.5 - (Math.sin(angle) * circleWidth),
  ));
  }
}
init();
window.onresize = () => {
   windowWidth = canvas.width = window.innerWidth;
   windowHeight = canvas.height = window.innerHeight;
   particles = [];
   context.clearRect(0,0, windowWidth, windowHeight);
   init();
}

window.addEventListener('click', () => {
  particles = [];
  context.clearRect(0,0, windowWidth, windowHeight);
  init();
});

loop();

我用这个替换了函数loop(),在5秒后停止它 -

function loop(stp) {
  let i;
  const length = particles.length;
  for (i = 0; i < length; i++) {
    particles[i].update();
    particles[i].render();
  }
if (stp > 5000) return;
  requestAnimationFrame(loop);
}

尝试依赖系统时钟,因为setTimeoutsetInterval 不准确

let start;
function loop(startTime) {
  let i;
  if(startTime){
     // Set the current time in milliseconds from 1st of jenuary 1970
     start = new Date().getTime();
  }
  const length = particles.length;
  for (i = 0; i < length; i++) {
    particles[i].update();
    particles[i].render();
  }
// Comparison from current dateTime with the stored one
// as setInterval and setTimeout are not accurate
if (start - (new Date().getTime() >= 5000) return;
  requestAnimationFrame(loop);
}
loop(true);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM