为什么Canvas不再清除矩形?

5
我尝试在canvas中动画简单的对象,一开始可以运行,但过一段时间后就停止清除矩形,并继续填充新的矩形。至少我认为它停止了清除,也许是其他什么问题。有人能帮我吗?没有控制台错误。

var canvas = document.querySelector('canvas');

canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

var c = canvas.getContext('2d');

var x=100;
function animate() {
    requestAnimationFrame(animate);
    c.clearRect(0,0,window.innerHeight,window.innerWidth);
    c.beginPath();
    c.fillRect(x,100,100,100);
    x+=2;
}
animate();
body{
    margin: 0;
}
canvas{
    background: orange;
}
<canvas></canvas>


首先,你应该在函数末尾而不是开头运行 requestAnimationFrame - Ibu
2
@lbu 有关系吗?requestAnimationFrame将给定的函数放入堆栈中,在线程“结束”后执行,因此在哪里调用它都无所谓。 - Al.G.
2个回答

3

正如评论中@Al.G所指出的,你在clearRect()方法调用中颠倒了heightwidth参数。将它们交换 c.clearRect(0, 0, window.innerWidth, window.innerHeight); 将会解决这个问题。

通常我使用canvas.widthcanvas.height清除画布,而不是使用非画布属性如window.innerWidthwindow.innerHeight,因为canvas属性总是与其尺寸匹配,减少对外部/全局变量的依赖,并且无需超越此范围考虑。

var canvas = document.querySelector('canvas');

canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

var c = canvas.getContext('2d');
var x = 100;

function animate() {
    requestAnimationFrame(animate);
    c.clearRect(0, 0, canvas.width, canvas.height);
    c.beginPath();
    c.fillRect(x, 100, 100, 100);
    x += 2;
}

animate();
body {
    margin: 0;
}
canvas {
    background: orange;
}
<canvas></canvas>


1
实际上,OP的问题是参数window.innerHeight,window.innerWidth的顺序颠倒了。我想即使不使用画布的属性,使用它们也可以解决问题。 - Al.G.
“since the canvas properties will always match its dimensions” 只有在未经转换的矩阵中才是正确的。 - Kaiido
@Kaiido 变换发生在上下文中,而不是画布对象本身。一旦您转换了上下文,坐标对 0, 0 是不准确的部分,而不是高度和宽度。但指出这个问题也没有什么坏处。 - ggorlen
clearRect基于当前矩阵。如果您进行缩放、旋转或平移,使用0,0,w,h将无法清除您想要的内容。 - Kaiido
是的,我认为我们在这方面达成了一致。我不明白这与我帖子中的语句有什么关系,我的帖子是在谈论canvas.widthcanvas.height,而不是上下文。例如,如果用户调整屏幕大小,window.innerWidth会改变,而canvas.width保持不变,导致意外行为。我并不是说"ctx.clearRect(0, 0, canvas.width, canvas.height)总是会清除上下文",但我确实说"canvas.width将始终匹配画布宽度,而像window.innerWidth这样的全局变量则不会"。 - ggorlen

0

我在这里只是想补充一下,因为被接受的答案无意中解决了你的问题。

问题在于您颠倒了clearRect的参数;

您做了以下操作:

c.clearRect(0,0,window.innerHeight,window.innerWidth);

虽然答案是:

c.clearRect(0,0,window.innerWidth,window.innerHeight); 

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