使用for循环绘制画布线条

时间:2014-05-26 21:31:02

标签: javascript canvas

我正在尝试使用画布绘制线条,我正在使用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/

2 个答案:

答案 0 :(得分:3)

请参阅:https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Canvas_tutorial/Applying_styles_and_colors#A_lineWidth_example

  

由于画布坐标不直接引用像素,因此必须特别注意获得清晰的水平和垂直线条。

基本上,因为您试图绘制一条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();
}

Demo

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