简体   繁体   English

无法使用 javascript 为元素的多个实例设置动画。 只会执行第一个动画

[英]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.

相关问题 Javascript。 无法获得元素样式 - Javascript. Can't get element style .insertAfter or.append 到具有 Javascript 的元素 ID。 这是一个脚本标签,所以它不能与 $ - .insertAfter or .append to an Element Id with Javascript. it's a script tag so it can't be with $ Javascript:无法处理多个实例的事件 - Javascript: Can't handle events for multiple instances 我是 JavaScript 的新手。我想在多个地方使用这个类似动画的按钮,但 JavaScript 动画仅适用于第一个按钮 - I'm new to JavaScript. I want this animated like button on multiple places, but the JavaScript animations are only applying on the first button Raphael element.animate(…)-指定要在动画的每个步骤执行的回调 - Raphael element.animate(…) - Specify a callback to be executed at every step of animation 使用 JavaScript 写入 HTML 标签的多个实例仅写入第一个标签 - Writing to multiple instances of HTML tag with JavaScript only writes to first tag JavaScript的。 悬停时的动画逻辑 - javascript. animation logic on hover 使用 Javascript 隐藏元素。 不适用于 IE 和 Chrome - Hide element with Javascript. Doesn't work with IE and Chrome splice无法删除javascript中的第一个元素 - splice can't remove the first element in javascript 无法在 javascript 中创建倒计时。有些东西不起作用:( - Can't create countdown in javascript. Something doesn't work :(
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM