画布使线条更粗

时间:2012-11-27 21:37:12

标签: javascript canvas

假设我有下一个使用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的情况下获得相同的结果?

3 个答案:

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

Here's a decent reference to the effect

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

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

答案 2 :(得分:1)

因为fillRectstrokeRect绘制的边框重叠。

相关问题