我正在制作图表,主要是作为练习。该图尝试通过线连接值,但是如果无法连接值,则仅绘制一个像素。
在下面的示例中,我确保minY
,maxY
和pixelX
都是整数值。它们实际上来自我真实代码中的Int32Array
。
// some min max range for this X pixel coordinate
const minY = data[i].min;
const maxY = data[i].max;
// if there are multiple values on this X coordinate
if (maxY - minY > 1) {
ctx.beginPath();
ctx.moveTo(pixelX + 0.5, minY + 0.5);
ctx.lineTo(pixelX + 0.5, maxY + 0.5);
ctx.closePath();
ctx.stroke();
}
// otherwise just draw a pixel
else {
// if the value was interpolated, it's already colored for this pixel
if (!valueIsInterpolated) {
ctx.strokeRect(pixelX + 0.5, minY + 0.5, 1, 1);
}
}
其中应绘制单个像素,但应绘制各种形状的矩形,这些矩形在图形中看起来非常难看。
如果我从通话中删除+ 0.5
,它会像这样:
那更糟。如何确保strokeRect
精确绘制一个像素?没有有趣的事情,没有抗锯齿。只需标记一个像素即可。为什么会这样?
答案 0 :(得分:1)
您正在使用strokeRect()
,它会绘制一个1像素矩形的 outline ,这意味着您将在所有方向上以一个半像素的外部结尾(假设宽度为1像素行),需要对其进行抗锯齿处理。
您想使用fillRect()
代替,它会填充 1个像素区域。
const ctx = c.getContext("2d");
for(let x = 5; x < c.width; x += 10) ctx.fillRect(x, 5, 1, 1);
<canvas id=c></canvas>
与使用strokeRect()相比,它将从向量框的所有方向(您不希望的)“渗出” 0.5(线宽= 1):
const ctx = c.getContext("2d");
for(let x = 5; x < c.width; x += 10) ctx.strokeRect(x, 5, 1, 1);
<canvas id=c></canvas>