[英]Can´t animate multiple instances of an element with javascript. Only the first animation will be executed
我创建了一个名为 Particlel 的元素。 此元素的单个动画也有效。 但是一旦我尝试运行多个动画,只会执行一个动画。 我认为问题是 requestAnimationFrame(this.animate.bind(this)) 调用,但我不知道如何更改它以一次接受多个动画。 任何想法如何解决这一问题?
js代码
//gloabl vars
let particels = [];
let numberParticels = 120;
let canvas;
let ctx;
let title;
let mesaureTitle;
let boundRadius;
let animations;
window.onload = function () {
this.init();
for(let i = 0; i < numberParticels; i++){
particels[i].update();
particels[i].draw();
particels[i].animate(0);
}
}
function init(){
canvas = document.getElementById("c");
ctx = canvas.getContext("2d");
title = document.getElementById("title");
mesaureTitle = title.getBoundingClientRect();
bound = {
x: mesaureTitle.x,
y: mesaureTitle.y,
width: mesaureTitle.width,
height: mesaureTitle.height,
};
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
for(let i = 0; i < numberParticels; i++){
let x = Math.floor(Math.random() * window.innerWidth);
let y = Math.floor(Math.random() * window.innerHeight);
let size = Math.floor(Math.random() * 25) + 3;
let weight = Math.floor(Math.random() * 11) + 2;
particels.push(new Particel(x, y, size, weight));
}
}
class Particel {
constructor (x,y,size, weight) {
this.x = x;
this.y = y;
this.size = size;
this.directionX = 0.15332;
this.resetWeight = weight;
this.weight = weight;
this.lastTime = 0;
this.interval = 1000/60;
this.timer = 0;
}
update(){
this.weight += 0.02;
this.y = this.y + this.weight;
this.x += this.directionX;
//check for collision with textField
if (this.x < bound.x + bound.width
&& this.x + this.size > bound.x &&
this.y < bound.y + bound.height &&
this.y + this.size > bound.y) {
this.y -= 3;
this.weight *= -0.3;
}
}
draw(){
if(this.y > canvas.height){
this.y = 0 - this.size;
this.weight = this.resetWeight;
//create random start point
this.x = Math.floor(Math.random() * canvas.width);
}
ctx.fillStyle = "rgb(0, 180, 97)";
ctx.beginPath();
ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
ctx.closePath();
ctx.fill();
}
animate(timeStamp){
const deltaTime = timeStamp - this.lastTime;
this.lastTime = timeStamp;
if(this.timer > this.interval){
ctx.clearRect(0,0, canvas.width, canvas.height);
this.update();
this.draw();
this.timer = 0;
}else {
this.timer += deltaTime;
}
ctx.fillStyle = "rgba(0, 0, 0, 0.3)";
requestAnimationFrame(this.animate.bind(this));
}
}```
主要问题是清除每个粒子的animate
方法内的画布。 因此,如果您绘制多个粒子,则每次粒子update
调用都会清除画布,覆盖之前的粒子数据,只保留最后一个粒子可见。
您可以尝试删除
ctx.clearRect(0,0, canvas.width, canvas.height);
从它所在的位置开始,并在init
创建一个createAnimationFrame
回调以在动画粒子之前清除画布:
function init() {
// ....
requestAnimationFrame( ()=> ctx.clearRect(0,0, canvas.width, canvas.height));
// existing for loop:
for(let i = 0; i < numberParticels; i++){
// ... .
}
但是,这会创建(一加粒子数)对动画帧的请求。 一个更好的解决办法是从移除请求动画帧Particel
类和创建单个requestAnimationFrame
回调其穿过particels
数组,并调用一类方法来重绘与更新的位置在画布上每个颗粒。
此外,该代码在严格模式下会生成一个错误,即尚未声明bound
。 我建议在全局范围内声明它,而不是依赖于草率模式 JavaScript 将其创建为window
属性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.