canvas fillRect()不起作用

3

我刚开始接触canvas和java script,并不知道为什么它不能正常工作。这两个警告框已经弹出,但是画布的颜色并没有按照我预期每隔1秒钟改变。

    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');

提供一个运行示例可以帮助您看到问题,也肯定会帮助其他人更快地得出答案。 :) (您可以使用jsbin、plunker、jsfiddle等工具) - katsos
你还应该注意到,使用控制台是调试的重要部分,并记住代码在可用之前必须是不可用的。 - Liam Sperry
谢谢提供信息,但控制台没有显示任何错误。 - A Rogue Otaku
3个回答

3
问题在于 setInterval 内的 this 指向全局的 window 对象,所以 this.width 为 undefined。最简单的解决方法是将传递给 setInterval 的函数转换为箭头函数。这里是一个示例
setInterval(() => {
    ...
},1000);

箭头函数继承它们的上下文,因此this仍然是您的画布对象。
注意:箭头函数不支持IE v11及以下版本。这里是受支持的浏览器列表。
如果无法使用箭头函数,则可以通过ctx.canvas.clientWidthctx.canvas.clientHeightctx获取画布的大小。这里是一个fiddle

使用箭头函数修复了它。但是如果有人正在使用旧版浏览器,是否有其他替代方法? - A Rogue Otaku
我在我的回答中添加了一个没有箭头函数的示例。 - Charlie Martin
太棒了。谢谢! - A Rogue Otaku

1

使用 setInterval( () => { 代替 setInterval(function(){ 可以解决这个问题。

箭头函数或lambda函数或 () => 将会把 this 指向你的类函数,而不是 window 变量。

在回调函数中使用 function() 总是会将 this 指向使用该函数的对象。
在你的情况下,setInterval 是全局变量 window 的一个函数。


是的,那就可以了。但我听说箭头函数相对较新,那么有没有适用于旧浏览器的替代方案呢? - A Rogue Otaku
你可以尝试使用.bind(this)来明确告诉函数它的this是什么。 - katsos

0
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');
}

在 setInterval 的上下文中,将 this 更改为 window。修复这个问题会解决你的问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接