[英]Can´t animate multiple instances of an element with javascript. Only the first animation will be executed
I have created an element called Particel.我创建了一个名为 Particlel 的元素。 Single animation of this element also work.
此元素的单个动画也有效。 But as soon as I try to run multiple animations, only one animation gets performed.
但是一旦我尝试运行多个动画,只会执行一个动画。 I think the problem is the requestAnimationFrame(this.animate.bind(this))-call, but i dont know how to change it to accept multiple animations at once.
我认为问题是 requestAnimationFrame(this.animate.bind(this)) 调用,但我不知道如何更改它以一次接受多个动画。 Any ideas how to fix this?
任何想法如何解决这一问题?
js-code 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));
}
}```
The major problem is clearing the canvas inside the animate
method of each particle.主要问题是清除每个粒子的
animate
方法内的画布。 So if you draw multiple particles, each particle update
call clears the canvas, overwriting previous particle data, which only leaves the last particle visible.因此,如果您绘制多个粒子,则每次粒子
update
调用都会清除画布,覆盖之前的粒子数据,只保留最后一个粒子可见。
You could try removing the您可以尝试删除
ctx.clearRect(0,0, canvas.width, canvas.height);
line from where it is and create a createAnimationFrame
call back in init
to clear the canvas before amimating particles:从它所在的位置开始,并在
init
创建一个createAnimationFrame
回调以在动画粒子之前清除画布:
function init() {
// ....
requestAnimationFrame( ()=> ctx.clearRect(0,0, canvas.width, canvas.height));
// existing for loop:
for(let i = 0; i < numberParticels; i++){
// ... .
}
However this creates (one plus the number of particles) requests for an animation frame.但是,这会创建(一加粒子数)对动画帧的请求。 A better solution would be to remove requesting animation frames from the
Particel
class and create a single requestAnimationFrame
callback which goes through the particels
array and calls a class method to redraw each particle on the canvas with updated position.一个更好的解决办法是从移除请求动画帧
Particel
类和创建单个requestAnimationFrame
回调其穿过particels
数组,并调用一类方法来重绘与更新的位置在画布上每个颗粒。
Also the code generates an error in strict mode that bound
has not been declared.此外,该代码在严格模式下会生成一个错误,即尚未声明
bound
。 I suggest declaring it globally rather than relying on sloppy mode JavaScript creating it as a window
property for you.我建议在全局范围内声明它,而不是依赖于草率模式 JavaScript 将其创建为
window
属性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.