以下代码(jsFiddle)在画布上的随机点处绘制一个红色正方形,注意擦除前一个(通过在其上用ctx.fillRect()
填充一个白色正方形):
<html>
<canvas id='canvas' width=300 height=300/>
<script>
const ctx = document.getElementById('canvas').getContext('2d');
let prevRect = null;
for (let i = 0 ; i < 10; i++) {
if (prevRect != null) {
ctx.fillStyle='white';
ctx.fillRect(prevRect.x, prevRect.y, 50, 50);
}
ctx.fillStyle='red';
const newRect = {x: Math.random()*(300-50), y: Math.random()*(300-50)};
ctx.fillRect(newRect.x, newRect.y, 50, 50);
prevRect = newRect;
}
</script>
</html>
该代码无法完全擦除先前的正方形,并且工件残留在屏幕上。相反,如果执行以下操作:
const newRect = {x: Math.floor(Math.random()*(300-50)), y: Math.floor(Math.random()*(300-50))};
...然后一切都会按预期进行。
我的问题是为什么。似乎完全没有必要在将值保留在
prevRect
中时截断,以使对fillRect()
的两个调用使用完全相同的坐标(即使使用浮点数),因此两个正方形应始终完全对齐。 最佳答案
问题源于在画布上绘制事物的基本方式。绘制正方形时,形状的边缘会稍微“羽化”。因此,当您在前一个红色框上绘制白色框时,红色的残余会渗入半透明边缘。
如果您画10个白盒子而不是一个,那么问题就消失了。或者,如果使白框的尺寸可能大0.5像素,则可能会有帮助。
const ctx = document.getElementById('canvas').getContext('2d');
let prevRect = null;
for (let i = 0 ; i < 10; i++) {
if (prevRect != null) {
ctx.fillStyle='white';
ctx.fillRect(prevRect.x - 0.75, prevRect.y - 0.75, 51.5, 51.5);
}
ctx.fillStyle='red';
const newRect = {x: Math.random()*(300-50), y: Math.random()*(300-50)};
ctx.fillRect(newRect.x, newRect.y, 50, 50);
prevRect = newRect;
}
body, html { padding: 0; }
canvas { border: 1px solid black; }
<canvas id=canvas height=300 width=300></canvas>
看起来每边都大0.75,效果很好,但是可以肯定,这是画布“逻辑”大小与实际屏幕大小的函数。
关于javascript - 使用浮点数时,fillRect()不完全重叠,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58136632/