Reputation: 1311
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
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