webkitrequestanimationframe w3schools react loop cancelanimationframe javascript object animation this

javascript - w3schools - requestAnimationFrame con esta palabra clave



requestanimationframe w3schools (6)

Estoy intentando pasar display.draw, que es la función en la que reside webkitRequestAnimationFram.

webkitRequestAnimationFrame presumiblemente llamará a la función que pasa, algo como esto:

function webkitRequestAnimationFrame(callback) { // stuff... callback(); // other stuff... }

En este punto, ha disociado (separado) la función de draw de su contexto de invocación. Debe vincular la función ( draw ) a su contexto (la instancia de Display ).

Puede usar Function.bind , pero esto requiere soporte de JavaScript 1.8 (o simplemente use el parche recomendado).

Display.prototype.draw = function() { // snip... window.webkitRequestAnimationFrame(this.draw.bind(this)); };

Estoy usando webkitRequestAnimationFrame pero estoy teniendo problemas para usarlo dentro de un objeto. Si paso la palabra clave this utilizará la window y no puedo encontrar la forma de que use el objeto especificado en su lugar.

Ejemplo:

Display.prototype.draw = function(){ this.cxt.clearRect(0, 0, this.canvas.width, this.canvas.height); //Animation stuff here. window.webkitRequestAnimationFrame(this.draw); };

También he intentado esto pero fue en vano:

Display.prototype.draw = function(){ this.cxt.clearRect(0, 0, this.canvas.width, this.canvas.height); //Animation stuff here. var draw = this.draw; window.webkitRequestAnimationFrame(draw); };


Ahora que ES6 / 2015 está aquí, si está utilizando un transpiler, entonces una función de flecha tiene un enlace léxico en lugar de:

window.webkitRequestAnimationFrame(this.draw.bind(this));

tu puedes hacer:

window.webkitRequestAnimationFrame(() => this.draw());

que es un poco más limpio

Lo he usado de manera efectiva con el transcrito de Typescript a ES5.


No puedo garantizar que sea una buena idea y estoy en lo cierto, pero ejecutar .bind en cada solicitudAnimationFrame significa crear una nueva función en cada iteración. Simplemente no me suena bien.

Es por eso que en mi proyecto guardé en caché la función enlazada para evitar el antipatrón.

Ejemplo simple:

var Game = function () { this.counter = 0; this.loop = function () { console.log(this.counter++); requestAnimationFrame(this.loop); }.bind(this); this.loop(); } var gameOne = new Game();

Si tienes un proyecto más complejo con herencia de prototipo, aún puedes crear una función en caché con "this" bound en el constructor del objeto

var Game = function () { this.counter = 0; this.loopBound = this.loop.bind(this); this.loopBound(); } Game.prototype.loop = function () { console.log(this.counter++); requestAnimationFrame(this.loopBound); } var gameOne = new Game();

¿Pensamientos? http://jsfiddle.net/3t9pboe8/ (mira en la consola)


Qué tal esto:

Display.prototype.draw = function(){ this.cxt.clearRect(0, 0, this.canvas.width, this.canvas.height); //Animation stuff here. window.webkitRequestAnimationFrame( $.proxy(function() {this.draw()}, this) ); };

... suponiendo que usas jquery



no tienes que usar "esto". Mantenlo simple.

var game = { canvas:null, context:null, init:function(){ // init canvas, context, etc }, update:function(){ //do something game.render(); requestAnimationFrame(game.update, game.canvas); }, };