canvas如何画出像素为1的线条

先来看一下平时我们html页面上的标签实现1px像素是怎么样的:

<p style="border-bottom: 1px solid #000000;"></p>

1px像素的线条

现在我们放一个canvas标签,画1像素宽的线条看一下:

<body>
    <p style="border-bottom: 1px solid #000000;"></p>
    <canvas id='canvas' width="300" height="100"></canvas>
</body>
<script>
    var canvas = document.getElementById("canvas");
    var ctx = canvas.getContext('2d');
    ctx.lineWidth = 1;

    writeLine(0, 10, 300, 10);

    function writeLine(x1, y1, x2, y2) {
        ctx.beginPath();
        ctx.moveTo(x1, y1);
        ctx.lineTo(x2, y2);

        ctx.stroke();
    }
</script>

canvas画出来的线条

真的好诡异啊,竟然不是1像素的宽度,颜色也有问题....

然后就想着是不是canvas不支持1px像素?再试着画一个宽度为1像素的矩形

ctx.fillRect(0, 20, 300, 1);

画一个宽度为1像素的矩形

发现又好了....太诡异了= =

不停的查资料,后来不断尝试中想到原因:
canvas画线时,是以你的坐标点为中心,左右扩散,来画线的,也就是说他实际是画了一个0,9.5;0,10.5;300,10.5;300,9.5这样一个矩形

这个情况下,因为反锯齿的处理,画布自动帮你填充为了0,9;0,11;300,11;300,9
所以看起来就像是宽了,并且颜色变淡了...

知道原因了,那么来验证一下:

    var canvas = document.getElementById("canvas");
    var ctx = canvas.getContext('2d');
    ctx.lineWidth = 1;

    writeLine(0, 10, 300, 10);

    ctx.fillRect(0, 20, 300, 1);

    writeLine(0, 30.5, 300, 30.5);

    function writeLine(x1, y1, x2, y2) {
        ctx.beginPath();
        ctx.moveTo(x1, y1);
        ctx.lineTo(x2, y2);

        ctx.stroke();
    }

线条4

恩,总算是正常了...那么以后,画奇数宽度的线条时就需要注意了:要不就是选点偏移0.5,要不就是整个画布偏移0.5
注意画水平线是x轴偏移,画垂直的时候就是y轴偏移了,保险起见的话,可以两个都偏移:

    var canvas = document.getElementById("canvas");
    var ctx = canvas.getContext('2d');
    ctx.lineWidth = 1;
    ctx.translate(0.5, 0.5);

    writeLine(0, 10, 300, 10);

    function writeLine(x1, y1, x2, y2) {
        ctx.beginPath();
        ctx.moveTo(x1, y1);
        ctx.lineTo(x2, y2);

        ctx.stroke();
    }

标签: none

添加新评论