typescriptthisrequestanimationframe

How to use requestAnimationFrame with a TypeScript object?


I have an object that i want to do drawing on a canvas. It will use requestAnimationFrame to start a game loop:

Contoso.ts

class Contoso
{
   //private ctx: CanvasRenderingContext2D;

   Initialize(ctx: CanvasRenderingContext2D) {
      //this.ctx = ctx;
      Render();
   }

   Render() {
      //...snip doing any actual drawing for the purpose of this question
      requestAnimationFrame(this.Render);
   }
}

app.ts

var contoso: Contoso;

contoso = new Contoso();
contoso.Initialize(canvas);

The first time someone calls Initialize, the requestAnimationFrame manages to correctly call Render.

The second time requestAnimationFrame calls Render, the this.Render is undefined and it crashes.

It's almost as though the object was destroyed after the initial call to Initialize.

What is going on?


Solution

  • You've lost this context. Two possible fixes:

    class Contoso
    {
       /* ... */
    
       // Use () => syntax so Render always gets 'this' context
       // from the class instance
       Render = () => {
          //...snip doing any actual drawing for the purpose of this question
          requestAnimationFrame(this.Render);
       }
    }
    

    The alternate fix is probably slightly clearer, but has the downside of making a lot more allocations (you probably don't want to allocate 1 closure per frame!)

       Render() {
          //...snip doing any actual drawing for the purpose of this question
          requestAnimationFrame(() => this.Render);
       }