Por favor, tengan paciencia conmigo... Estoy aprendiendo a usar requestAnimationFrame para animaciones simples (por ejemplo: mover la pelota por la pantalla). Obtuve un ejemplo de trabajo usando funciones javscript. Ahora quiero usar la clase y los métodos de JavaScript para hacer lo mismo. Estoy haciendo esto porque a continuación quiero instanciar la clase varias veces, correr y controlar varias bolas que se mueven por la pantalla. Problemas:
No estoy seguro si la sintaxis de mi clase es ideal. (Es un poco de un truco)
requestAnimationFrame está ejecutando la animación demasiado rápido.
...animationRequest = window.requestAnimationFrame(this.moveBall());
Funciona como funciones de javascript https://jsfiddle.net/tjqbpv1e/
pero va demasiado rápido (o nada) cuando creo una clase. https://jsfiddle.net/68vys0hL/
Tiene algunas variables no declaradas y adicionales, además de perder this
, pero aparte de eso, parece una clase decente. La razón por la que no hay animación (también conocida como demasiado rápida) es porque está ejecutando this.moveBall()
directamente en lugar de enviar this.moveBall
como devolución de llamada a requestAnimationFrame
. Además, no tienes nada que controle la velocidad en absoluto. Con requestAnimationFrame
, debe verificar cuánto tiempo pasó desde la devolución de llamada anterior, como lo hizo en el código original como variable diff
no utilizada.
Hablando de devoluciones de llamada, es un poco complicado enviar devoluciones de llamada con this
alcance, muy a menudo es posible que necesite .bind(this)
a la función de devolución de llamada:
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>