我正在尝试使用画布绘制线条,我正在使用for循环更改坐标。
这是我的canvas元素:
<canvas id="c" width="300px" height="300px"></canvas>
这里是js代码:
var c = document.getElementById('c');
ci = c.getContext('2d');
for(var a = 18; a < 300; a +=18){
fnc(a, ci);
}
function fnc(x, ci){
ci.strokeStyle = 'red';
ci.moveTo(0, x);
ci.lineTo(300, x); ci.lineWidth = 0.2; ci.stroke();
}
正如您所看到的,我正在尝试在它们之间绘制18px空格。但是线条的粗细和颜色(或不透明度,我不确定)正在从上到下发生变化。
这是一个小提琴:http://jsfiddle.net/J6zzD/1/
所以有什么不对的,我找不到自己的错误。为什么颜色和厚度不同?
更新:
我刚从函数中写出这些线条,现在所有线条都变得褪色但厚度相同。太奇怪了:
ci.strokeStyle = 'red';
ci.lineWidth = 0.2; ci.stroke();
这是demo:http://jsfiddle.net/J6zzD/4/
答案 0 :(得分:3)
由于画布坐标不直接引用像素,因此必须特别注意获得清晰的水平和垂直线条。
基本上,因为您试图绘制一条0.2像素宽的线,浏览器会进行一些数学计算,将连续数字近似为离散单位,然后您就会得到#34; fading&#34;线。
现在我们可以通过将context.lineWidth
更改为1(我实际上将其删除,因为它默认为1)并将所有内容向下移动半个像素来修复代码。
var c = document.getElementById('c');
ci = c.getContext('2d');
for(var a = 18.5; a < 300.5; a +=18)
{
fnc(a, ci);
}
function fnc(x, ci)
{
ci.strokeStyle = 'red';
ci.moveTo(0, x);
ci.lineTo(300, x);
ci.stroke();
}
答案 1 :(得分:1)
这又是忘记给startPath打电话的永恒问题
每次调用moveTo然后调用lineTo时,都会创建一个新的* sub *路径,该路径将添加到当前路径
然后每次调用stroke()时,当前路径,以便在第一次绘制最后添加的路径时重新绘制所有当前子路径。
由于不透明度会增加,当绘制一次的底线将具有20%的不透明度(lineWidth = 0.2)时,顶线将达到100%不透明度(alpha = 255)。
在你的第二个小提琴中,你只画一次,所以所有的线都有20%的不透明度,这对于0.2行宽是正确的。
所以:在绘制新图之前使用beginPath
在这种情况下,您有两种选择:
•逐行绘制
OR
•绘制一条路径,将所有行作为子路径。
(见下面的代码)。
提示:为了获得干净的线条,请记住像素的中心位于每个像素的(+0.5,+ 0.5)坐标处,所以 一个&#39;技巧&#39;是应用开始时翻译0.5,0.5,然后只使用圆角坐标和lineWidth 。
1)逐行绘制
http://jsfiddle.net/gamealchemist/J6zzD/6/
var c = document.getElementById('c');
var ctx = c.getContext('2d');
ctx.translate(0.5, 0.5);
ctx.lineWidth = 1;
for (var y = 18; y < 300; y += 18) {
strokeLine(ctx, y);
}
function strokeLine(ctx, y) {
ctx.beginPath();
ctx.strokeStyle = 'red';
ctx.moveTo(0, y);
ctx.lineTo(300, y);
ctx.stroke();
}
2)绘制多个子路径: (一个笔画只能有一种颜色())
http://jsfiddle.net/gamealchemist/J6zzD/7/
var c = document.getElementById('c');
var ctx = c.getContext('2d');
ctx.translate(0.5, 0.5);
ctx.lineWidth = 1;
ctx.strokeStyle = 'red';
ctx.beginPath();
for (var y = 18; y < 300; y += 18) {
addLineSubPath(ctx, y);
}
ctx.stroke();
function addLineSubPath(ctx, y) {
ctx.moveTo(0, y);
ctx.lineTo(300, y);
}