先来看一下平时我们html页面上的标签实现1px像素是怎么样的:
<p style="border-bottom: 1px solid #000000;"></p>
现在我们放一个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>
真的好诡异啊,竟然不是1像素的宽度,颜色也有问题....
然后就想着是不是canvas不支持1px像素?再试着画一个宽度为1像素的矩形
ctx.fillRect(0, 20, 300, 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();
}
恩,总算是正常了...那么以后,画奇数宽度的线条时就需要注意了:要不就是选点偏移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();
}