使用 javascript class 中的 requestAnimationFrame 在屏幕上移动 html 元素

moving html element across the screen using requestAnimationFrame in javascript class

请多多包涵... 我正在学习如何将 requestAnimationFrame 用于简单的动画(例如:在屏幕上移动球。)我得到了使用 javscript 函数的示例。现在我想使用 javascript class 和方法来做同样的事情。我这样做是因为接下来我想多次实例化 class,运行 并控制多个球在屏幕上移动。问题:

  1. 不确定我的 class 语法是否理想。 (有点hack)

  2. requestAnimationFrame 运行动画太快了。

    ...animationRequest = window.requestAnimationFrame(this.moveBall());

它作为 javascript 函数工作 https://jsfiddle.net/tjqbpv1e/

但是当我创建 class 时速度太快(或根本没有)。 https://jsfiddle.net/68vys0hL/

您有一些未声明的和额外的变量以及缺失的 this,但除此之外它看起来还不错 class。 没有动画(又名太快)的原因是因为您直接执行 this.moveBall() 而不是将 this.moveBall 作为回调发送到 requestAnimationFrame。此外,您根本没有任何可以控制速度的东西。使用 requestAnimationFrame 你必须检查自上次回调以来经过了多长时间,就像你在原始代码中作为未使用的 diff 变量一样。

说到回调,用 this 范围发送回调有点棘手,通常你可能需要 .bind(this) 到回调函数:

class AnimatedCircle {

  output;
  animated_circle;
  number;
  xpos;
  multiplier;
  animationRequest;
  myContainer;
  screen_width;
  prevTime;
  speed;

  constructor(val_1, val_2) {
    this.val_1 = val_1;  // example of passing values
    this.val_2 = val_2;

    this.animated_circle = document.getElementById('animated_circle');
    this.number = 0;
    this.xpos = 1;                 // new horizontal position
    this.multiplier = 1;
    this.animationRequest = null;
    this.myContainer = document.querySelector('#container');
    this.screen_width = this.myContainer.offsetWidth - 50;
    this.prevTime = 0;
    this.speed = Math.random() * 10; //random speed
  }

  // test method
  test_method() {
    return `${this.val_1} says hello.`;
  }

  moveBall(time) {

    this.animationRequest = window.requestAnimationFrame(this.moveBall.bind(this));
    if (time - this.prevTime < this.speed) //speed control
      return;

    this.prevTime = time;

    // if on screen 
    console.log("got here!");
    if (this.xpos < this.screen_width && this.xpos > 0) {
      this.number++;
    }
    else {
      // when we get to end of screen , then exit function
      return;
    }

    this.xpos = this.xpos + (5);    // horizontal position

    // move on X-Axis
    this.animated_circle.style.transform = `translateX(${this.xpos}px)`;
    console.log("loop");

  }

}
// instantiate class
myAnimatedCircle = new AnimatedCircle('Bob', 'Level22');
// call method
console.log(myAnimatedCircle.test_method());
console.log(myAnimatedCircle.moveBall());
#container{
            border: 1px solid gray;
            background-color: rgb(236, 225, 225);            
            height:60px;
            padding:0px;            
        }            
 #animated_circle{
            height: 35px;
            width: 35px;
            margin:10px;
            background-color: rgb(103, 74, 184);
            border-radius: 50%;
            display: inline-block;
        }
<p id="output"></p>
    <div id="container" >
        <p id="animated_circle"></p>
    </div>