Neil
Neil

Reputation: 1311

window.requestAnimationFrame() not working in Ionic2 application

I'm trying to use an HTML5 canvas for animation in my Ionic 2 app. For this, I have to use window.requestAnimationFrame() to animate my canvas. This is my code:

import { Component, ViewChild, Renderer } from '@angular/core';
import { Platform } from 'ionic-angular';
import { IonicPage, NavController, NavParams } from 'ionic-angular';

...

export class CubePage {
  @ViewChild('glCanvas') canvas: any;
  canvasElement: any;
  ctx: any;
  radius: number;
  leftBallX: number;
  leftBallY: number;
  rightBallX: number;
  rightBallY: number;

  constructor(public navCtrl: NavController, public navParams: NavParams, public renderer: Renderer, public platform: Platform) {
  }

  ngAfterViewInit() {
    console.log(this.canvas);
    this.radius = 25;
    this.canvasElement = this.canvas.nativeElement;

    this.renderer.setElementAttribute(this.canvasElement, 'width', this.platform.width() + "");
    this.renderer.setElementAttribute(this.canvasElement, 'height', this.platform.height() + "");
    this.ctx = this.canvasElement.getContext('2d');

    this.leftBallX = 5;
    this.leftBallY = 5;

    window.requestAnimationFrame(this.cycle);
  }


  cycle() {
    if (this.leftBallX < this.platform.width() / 2) {
      this.ctx.clearRect(0, 0, this.platform.width(), this.platform.height());
      this.drawCenterLine();
      this.updateLeftBall(this.leftBallX + 5, this.leftBallY);
      this.drawLeftBall();
    }
    window.requestAnimationFrame(this.cycle);
  }
...
    }

It gives the runtime error Cannot read property 'leftBallX' of undefined when I load the application in my web browser. However, when I eliminate the window.requestAnimationFrame(this.cycle) lines, replacing the first with this.cycle(), there are no errors. Is there a problem with using window in Ionic/Angular?

Upvotes: 1

Views: 1582

Answers (1)

Duannx
Duannx

Reputation: 8726

To solve your problem, first, you need to understand this context when you call a javascript function. Lets see the example:

foo = 0;
ngAfterViewInit(){
  let self = this;
  //way #1
  setTimeout(function(){
    console.log(this.foo); //undefinded; because this != self;
  },1000);
  //way #2
  setTimeout(()=>{
    console.log(this.foo); //0; because this == self;
  },1000)
}

When you call function by way #1, javascript re-bind this object, so you can not find foo propertive in this.
When you call function by way #2 (arrow function), javascript does not re-bind this object, so you can use this as expected.

Now you can solve your problem by using arrow function:

requestAnimationFrame(()=>{this.cycle()})

See more about arrow function

Upvotes: 4

Related Questions