2

假设我有下一个使用画布绘制网格的代码:

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);
       }
   }
}

你可以在这里查看结果

我的问题是,如果我评论这条线,为什么网格会显得更厚ctx.fillRect(i * size, j * size, size, size);

编辑

我怎样才能在不使用的情况下获得相同的结果fillRect

​</p>

4

3 回答 3

3

您的笔画在半像素上渲染,这会导致它们在两个像素上模糊。您的填充覆盖了其中的一部分,使它们再次看起来像半像素。

简单的解决方案是将绘图偏移0.5, 0.5以绘制整个像素。有关这方面的更多信息,请参阅http://diveintohtml5.info/canvas.html的开头部分:

问:为什么 x 和 y 从 0.5 开始?为什么不是0?


无论如何,你不应该使用矩形来制作网格,你应该只使用线条,并且你应该只需要在网格完成后在最后描边一次。这样做可确保您的半透明网格在网格线的交点处没有较粗的点。

这是一个例子:

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();
}

​</p>

小提琴:http: //jsfiddle.net/tZqZv/4/

于 2012-11-28T03:00:22.420 回答
2

渲染的笔画跨越像素边界。这在看起来像抗锯齿效果的外观中很明显,因此当不应用填充并且不与像素边界重叠时,线条看起来更粗。如果我们平移 0.5,那么我们不会跨越像素边界,并且无论是否应用填充,都不会观察到线条粗细的差异。这是一个例子。

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);
        }
    }
}

这是对效果的一个不错的参考

于 2012-11-27T21:58:05.500 回答
1

因为您fillRect与 . 绘制的边框重叠strokeRect

于 2012-11-27T21:46:32.583 回答