A Rogue Otaku
A Rogue Otaku

Reputation: 923

canvas fillRect() not working

I am new to canvas and java script and have no idea why it is not working. The 2 alerts are firing but color of the canvas is not changing every 1 sec as I intended it to do.

    var canvas = function(width, height, color){
    this.width = width;
    this.height = height;
    this.color = color;
    var instance = document.createElement('canvas');
    document.body.appendChild(instance);
    instance.width = this.width;
    instance.height = this.height;
    var ctx = instance.getContext('2d');
    ctx.fillStyle = color;
    ctx.fillRect(0, 0, this.width, this.height);

    this.changeBackground = function(color){
        ctx.fillStyle = color;
        ctx.fillRect(0, 0, this.width, this.height);
    }

    this.clear = function(){
        ctx.clearRect(0, 0, this.width, this.height);
    }
    var flag = true;
    setInterval(function(){
        if(flag) {
            ctx.fillStyle = 'blue';
            ctx.fillRect(0, 0, this.width, this.height);
            alert('blue');
        }
        else {
            ctx.fillStyle = 'green';
            ctx.fillRect(0, 0, this.width, this.height);
            alert('green');
        }
        flag = !flag;
    },1000);
    }

    var gameCanvas = new canvas(800, 600, 'green');

Upvotes: 3

Views: 7225

Answers (3)

Charlie Martin
Charlie Martin

Reputation: 8406

The issue is this inside of setInterval is the global window object, so this.width is undefined. The easiest way to fix this is to convert the function passed to setInterval into an arrow function. Here is a fiddle

setInterval(() => {
    ...
},1000);

Arrow functions inherit their context, so this is still your canvas object.

Note: arrow functions are not supported in IE v11 and below. Here is the list of supported browsers.

If you can't use arrow functions, you can get the size of the canvas from the ctx with ctx.canvas.clientWidth and ctx.canvas.clientHeight Here is a fiddle

Upvotes: 3

katsos
katsos

Reputation: 91

Writing setInterval( () => { instead of setInterval(function(){ could solve this issue.

Fat-arrow function or lamda function or () => will point this to your class-function instead of window variable.

Using function() inside a callback will always point this to the object that the implementation of used function came from.
In your case setInterval is a function of window global variable

Upvotes: 1

gauravmuk
gauravmuk

Reputation: 1616

if(flag) {
 ctx.fillStyle = 'blue';
 ctx.fillRect(0, 0, canvas.width, canvas.height);
 alert('blue');
} 
else {
 ctx.fillStyle = 'green';
 ctx.fillRect(0, 0, canvas.width, canvas.height);
 alert('green');
}

this inside setInterval contexts to window. Fixing this would fix your issue.

Upvotes: 0

Related Questions