为什么clearRect()不能完全清除fillRect()?

3
为什么在这个例子中,clearRect() 和 fillRect() 的值相同时,clearRect() 没有完全清除 fillRect()?

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.fillStyle = "red";

setInterval(function(){
 let rect = {x:Math.random()*c.width, y:Math.random()*c.height}
 ctx.fillRect(rect.x, rect.y, 5, 5);
 ctx.clearRect(rect.x, rect.y, 5,5);
},500)
<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>


可能由Math.random()生成的分数像素被抗锯齿处理了(在这种情况下是否是正确的术语?),但您无法对清除进行抗锯齿处理。 - Ry-
1个回答

5
由于抗锯齿,你正在绘制非整数坐标,而无法渲染半个像素,因此像素颜色会带有一些透明度,以给出比一个像素更小的像素的错觉。
然而,clearRect()也会受到这种抗锯齿的影响,因此会留下一些半透明的像素。
为避免这种情况,尽可能在像素整数上进行绘制,并且在每个帧中清除整个画布并重新绘制所需内容。

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.fillStyle = "red";

setInterval(function() {
  // clear all
  ctx.clearRect(0, 0, c.width, c.height);
  // redraw what needs to be
  let rect = {
    x: Math.random() * c.width,
    y: Math.random() * c.height
  }
  ctx.fillRect(rect.x, rect.y, 5, 5);
}, 500)
<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>


好的,非常感谢。所以看起来使用像Math.floor这样的方法将数字四舍五入为整数也会去除小数点后面的余数。 - Squirrl
1
@Squirrl 是的,但说实话,每帧清除所有并重新绘制,你会避免很多负担,并且不会失去太多性能。 - Kaiido

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