使用此关键字的 requestAnimationFrame

发布于 2024-11-08 17:16:52 字数 610 浏览 0 评论 0原文

我正在使用 webkitRequestAnimationFrame 但在对象内部使用它时遇到问题。如果我传递 this 关键字,它将使用 window 并且我找不到让它使用指定对象的方法。

示例:

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

  window.webkitRequestAnimationFrame(this.draw);
};

我也尝试过,但没有成功:

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);
};

I'm using webkitRequestAnimationFrame but I'm having trouble using it inside of an object. If I pass the this keyword it will use window and I can't find a way for it to use the specified object instead.

Example:

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

  window.webkitRequestAnimationFrame(this.draw);
};

I have also tried this but to no avail:

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);
};

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

怪我闹别瞎闹 2024-11-15 17:16:52

我正在尝试传递 webkitRequestAnimationFram 所在的函数display.draw。

webkitRequestAnimationFrame 可能会调用您传入的函数,如下所示:

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

此时,您已将 draw 函数与其调用上下文分离(分离)。您需要将函数 (draw) 绑定到其上下文(Display 的实例)。

您可以使用 Function.bind ,但这需要 JavaScript 1.8 支持(或者只使用推荐的补丁)。

Display.prototype.draw = function()
{
    // snip...

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

I'm trying to pass display.draw which is the function in which webkitRequestAnimationFram resides.

webkitRequestAnimationFrame will presumably call the function you pass in, something like this:

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

At this point, you have dissociated (detached) the draw function from its invocation context. You need to bind the function (draw) to its context (the instance of Display).

You can use Function.bind, but this requires JavaScript 1.8 support (or just use the recommended patch).

Display.prototype.draw = function()
{
    // snip...

    window.webkitRequestAnimationFrame(this.draw.bind(this));
};
旧故 2024-11-15 17:16:52

现在 ES6/2015 已经到来,如果您使用的是转译器,那么箭头函数具有词法 this 绑定,因此

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

您可以执行以下操作而不是::

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

这更干净一点。

我已经将 Typescript 转换为 ES5 来有效地使用它。

Now that ES6/2015 is here, if you are using a transpiler then an arrow function has lexical this binding so instead of:

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

you can do:

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

which is a bit cleaner.

I've used this effectively with Typescript transpiling to ES5.

他夏了夏天 2024-11-15 17:16:52

我不能保证这是一个好主意并且我是对的,但是在每个 requestAnimationFrame 上运行 .bind 意味着在每次迭代上创建一个新函数。这对我来说听起来不太合适。

这就是为什么在我的项目中我缓存了绑定函数以避免反模式。

简单的例子:

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

如果您有一个具有原型继承的更复杂的项目,您仍然可以创建一个在对象的构造函数中绑定“this”的缓存函数

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();


http://jsfiddle.net/3t9pboe8/ (在控制台中查看)

I can't guarantee that this is a good idea and that I'm right, but running .bind on every requestAnimationFrame means creating a new function on every iteration. It just doesn't sound right to me.

That's why in my project I cached the bound function to avoid the anti-pattern.

Simple example:

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

If you have a more complex project with prototype inheritance you can still create a cached function with "this" bound in object's constructor

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();

Thoughts?
http://jsfiddle.net/3t9pboe8/ (look in the console)

来日方长 2024-11-15 17:16:52

怎么样:

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) );
};

...假设你使用 jquery

how about this:

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) );
};

...assuming you use jquery

丘比特射中我 2024-11-15 17:16:52

除了 bind 方法和箭头函数解决方案(由 Jamaes World 的答案提供)之外,另一个(相当旧的)解决方法可能是:

var self = this
window.webkitRequestAnimationFrame(
    function() {
        self.draw()
    }
);

Beside bind method, and arrow function solution (offered by Jamaes World's answer), Another (rather old) work around could be:

var self = this
window.webkitRequestAnimationFrame(
    function() {
        self.draw()
    }
);
命硬 2024-11-15 17:16:52

你不必使用“这个”。
保持简单。

var game = {
      canvas:null,
      context:null,

    init:function(){
            // init canvas, context, etc
    },      

    update:function(){
        //do something
        game.render();                        
        requestAnimationFrame(game.update, game.canvas);        
    },            
};

you have not to use "this".
Keep it simple.

var game = {
      canvas:null,
      context:null,

    init:function(){
            // init canvas, context, etc
    },      

    update:function(){
        //do something
        game.render();                        
        requestAnimationFrame(game.update, game.canvas);        
    },            
};
皓月长歌 2024-11-15 17:16:52

而且您可能想使用 requestAnimationFrame shim 使其在所有浏览器上运行 https://github.com/kof /动画框架

And also you might want to use requestAnimationFrame shim to make it work on all browsers https://github.com/kof/animation-frame

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文