使用for循环在画布上绘制线条

问题描述:

我试图用画布绘制线条,并使用for循环更改坐标。

I am trying to draw lines with canvas and I am changing the coordinates with a for loop.

这是我的画布元素:

<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的空格。但是线条的粗细和颜色(或不确定性,我不确定)从上到下都在变化。

As you can see I am trying to draw these lines with 18px spaces between them. But the thickness of the lines and the color(or opacity, I am not sure) are changing from top to bottom.

这里是一个小提琴: http://jsfiddle.net/J6zzD/1/

那怎么了,我找不到我的错误。为什么颜色和厚度不同?

So what is wrong with that I can't find my mistake. Why are the color and the thicknesses are different?

UPDATE:

I刚刚将这些线写出了函数,现在所有的线都变淡了,但是粗细却是相同的。太奇怪了:

I just wrote these lines out of the function and now all the lines becomes faded but thicknesses are same. So strange :

 ci.strokeStyle = 'red'; 
 ci.lineWidth = 0.2; ci.stroke();

这是演示: http://jsfiddle.net/J6zzD/4/

忘记调用beginPath的永恒问题。

每次调用moveTo然后lineTo时,都会创建一个新的* sub * path,它将添加到当前Path中。

然后每次您调用stroke()(当前路径),以便在第一次绘制最后一条添加的路径时重新绘制所有当前子路径。

由于不透明度会累加,因此顶行将达到如果底线绘制一次,则100%不透明度(alpha = 255)将具有20%不透明度(lineWidth = 0.2)。

That's again the eternal issue of forgetting to call beginPath.
Each time you call moveTo then lineTo, you create a new *sub*path, which adds to the current Path.
Then each time you call stroke(), the current path, so all the current subpaths get re-drawn, when the last added path is drawn for the first time.
Since opacities will add-up, top lines will reach 100% opacity (alpha=255) when the bottom line, drawn once, will have a 20% opacity (lineWidth=0.2) .

在第二个小提琴中,您仅笔触一次,因此所有行的不透明度为20%,这对于0.2 lineWidth是正确的。

In your second fiddle, you stroke only once, so all lines have 20% opacity, which is correct for the 0.2 lineWidth.

因此:在绘制新图形之前使用beginPath。

在这种情况下,您有两种选择:

•逐行绘制


•绘制一次以所有行作为子路径的路径。

So : use beginPath before drawing a new figure.
In this case you have two choices :
• draw line by line OR
• draw once a path with all lines as subpath.

(请参见下面的代码)。

(see code below).

提示:要获得清晰的线条,请记住像素的中心在每个像素的(+0.5,+0.5)坐标上,因此
a'trick'将在0.5、0.5应用程序开始,然后仅使用舍入坐标和lineWidth

TIP : To get clean lines remember that pixels's center is at the (+0.5, +0.5) coordinates of each pixels, so a 'trick' is to translate by 0.5, 0.5 on app start, then only use rounded coordinates and 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)绘制多个子路径:
(您只能有一个一招的颜色())

2) draw multiple subPath : (you can have only one color for one stroke() )

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