假设我有下一个使用canvas绘制网格的代码:
var canvas = document.getElementById('canvas'),
ctx = canvas.getContext('2d'),
rows = 10,
cols = 10,
size = canvas.getAttribute("width") / rows;
drawGrid();
function drawGrid() {
for (var i = 0; i < rows; i++) {
for (var j = 0; j < cols; j++) {
ctx.strokeStyle ='rgba(242, 198, 65, 0.1)';
ctx.strokeRect(i * size, j * size, size, size);
ctx.fillStyle = 'rgb(38,38,38)';
ctx.fillRect(i * size, j * size, size, size);
}
}
}
您可以查看结果here
我的问题是,如果我评论第ctx.fillRect(i * size, j * size, size, size);
行
修改
如何在不使用fillRect
的情况下获得相同的结果?
答案 0 :(得分:2)
渲染的笔划跨越像素边框。这表现为看起来像抗锯齿效果的外观,因此当未应用填充且不与像素边界重叠时,线条看起来更粗。如果我们平移0.5,那么我们不会跨越像素边界,并且无论是否应用填充,都不会观察到线条厚度的差异。 Here's an example.
var canvas = document.getElementById('canvas'),
ctx = canvas.getContext('2d'),
rows = 10,
cols = 10,
size = canvas.getAttribute("width") / rows - 5;
drawGrid();
function drawGrid() {
for (var i = 0; i < rows; i++) {
for (var j = 0; j < cols; j++) {
ctx.strokeStyle ='rgba(0, 0, 0, 1)';
ctx.strokeRect(i * size + 0.5, j * size + 0.5, size, size);
ctx.fillStyle = 'rgb(38,128,128)';
//ctx.fillRect(i * size + 0.5, j * size + 0.5, size, size);
}
}
}
答案 1 :(得分:2)
你的笔画是在半像素上渲染的,这会导致它们在两个像素上模糊。你的填充物覆盖了其中一部分,使它们看起来像半像素。
简单的解决方案是将绘图偏移0.5, 0.5
以便绘制整个像素。有关详细信息,请参阅开始的http://diveintohtml5.info/canvas.html部分:
问:你为什么在0.5开始x和y?为什么不是0?
无论如何,你不应该使用rects来制作一个网格,你应该只是使用线条,并且你应该只需要在网格结束时进行一次描边。这样做可确保半透明网格在网格线的交叉点处没有较粗的点。
以下是一个例子:
var canvas = document.getElementById('canvas'),
ctx = canvas.getContext('2d'),
rows = 10,
cols = 10,
size = canvas.width / rows,
width = canvas.width,
height = canvas.height;
drawGrid();
function drawGrid() {
// An odd-sized lineWidth means we should translate to draw on whole pixels
ctx.translate(0.5, 0.5);
for (var i = 1; i < rows; i++) {
ctx.moveTo(0, i * size);
ctx.lineTo(width, i * size);
}
for (var j = 1; j < cols; j++) {
ctx.moveTo(j * size, 0);
ctx.lineTo(j * size, height);
}
// translate back:
ctx.translate(-0.5, -0.5);
// setting stroke style and stroking just once
ctx.strokeStyle = 'rgba(242, 198, 65, 0.1)';
ctx.stroke();
}
答案 2 :(得分:1)
因为fillRect
与strokeRect
绘制的边框重叠。