Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

requestAnimationFrame with this keyword

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); }; 
like image 861
Ryan Avatar asked May 19 '11 21:05

Ryan


People also ask

What does requestAnimationFrame do in Javascript?

requestAnimationFrame() method tells the browser that you wish to perform an animation and requests that the browser calls a specified function to update an animation before the next repaint. The method takes a callback as an argument to be invoked before the repaint.

What FPS is requestAnimationFrame?

With requestAnimationFrame, your frame rate is typically around 60 frames per second (FPS). To repeat that differently, this means your requestAnimationFrame function and related code have the potential to refresh your screen 60 times every second.

Why should I use requestAnimationFrame?

To optimize system and browser resources, it is recommended to use requestAnimationFrame , which requests the browser to execute the code during the next repaint cycle. This allows the system to optimize resources and frame-rate to reduce unnecessary reflow/repaint calls.

Is requestAnimationFrame a Macrotask?

A macrotask queue is a queue for setTimeout and requestAnimationFrame .


2 Answers

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)); }; 
like image 158
Matt Ball Avatar answered Sep 22 '22 16:09

Matt Ball


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.

like image 33
James World Avatar answered Sep 18 '22 16:09

James World