J'utilise webkitRequestAnimationFrame
mais je ne parviens pas à l'utiliser à l'intérieur d'un objet. Si je passe le mot clé this
, il utilisera window
et je ne trouverai pas le moyen de l'utiliser à la place.
Exemple:
Display.prototype.draw = function(){
this.cxt.clearRect(0, 0, this.canvas.width, this.canvas.height);
//Animation stuff here.
window.webkitRequestAnimationFrame(this.draw);
};
J'ai aussi essayé cela mais en vain:
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);
};
J'essaie de passer à display.draw, qui est la fonction dans laquelle réside webkitRequestAnimationFram.
webkitRequestAnimationFrame
appellera probablement la fonction que vous transmettez, quelque chose comme ceci:
function webkitRequestAnimationFrame(callback)
{
// stuff...
callback();
// other stuff...
}
À ce stade, vous avez dissocié (détaché) la fonction draw
de son contexte d’appel. Vous devez lier la fonction (draw
) à son contexte (l'instance de Display
).
Vous pouvez utiliser Function.bind
, mais nécessite le support de JavaScript 1.8 (ou utilisez simplement le correctif recommandé).
Display.prototype.draw = function()
{
// snip...
window.webkitRequestAnimationFrame(this.draw.bind(this));
};
Maintenant que ES6/2015 est arrivé, si vous utilisez un transpiler, une fonction de flèche possède une liaison lexicale this
de sorte que
window.webkitRequestAnimationFrame(this.draw.bind(this));
tu peux faire:
window.webkitRequestAnimationFrame(() => this.draw());
ce qui est un peu plus propre.
Je l'ai utilisé efficacement avec TypeScript transpiling to ES5.
Je ne peux pas garantir que c'est une bonne idée et que j'ai raison, mais exécuter .bind sur chaque requestAnimationFrame signifie créer une nouvelle fonction à chaque itération. Cela ne me semble pas juste.
C'est pourquoi, dans mon projet, j'ai mis en cache la fonction liée pour éviter l'anti-motif.
Exemple 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 vous avez un projet plus complexe avec un héritage prototype, vous pouvez toujours créer une fonction en cache avec "this" lié dans le constructeur de l'objet.
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();
Pensées? http://jsfiddle.net/3t9pboe8/ (regardez dans la console)
que dis-tu de ça:
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) );
};
... en supposant que vous utilisez jQuery
vous ne devez pas utiliser "this" . Restez simple.
var game = {
canvas:null,
context:null,
init:function(){
// init canvas, context, etc
},
update:function(){
//do something
game.render();
requestAnimationFrame(game.update, game.canvas);
},
};
Outre la méthode bind
et la solution de fonction de flèche (proposée par la réponse de Jamaes World), un autre travail (plutôt ancien) pourrait être:
var self = this
window.webkitRequestAnimationFrame(
function() {
self.draw()
}
);