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
Y también es posible que desee utilizar requestAnimationFrame shim para que funcione en todos los navegadores https://github.com/kof/animation-frame
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);
},
};