简体   繁体   English

使用for循环绘制画布线条

[英]Drawing lines with canvas by using for loop

I am trying to draw lines with canvas and I am changing the coordinates with a for loop. 我试图用画布画线,我用for循环改变坐标。

here is my canvas element: 这是我的canvas元素:

<canvas id="c" width="300px" height="300px"></canvas>

and here is the js codes: 这是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(); 
    }

As you can see I am trying to draw these lines with 18px spaces between them. 正如你所看到的,我试图在它们之间绘制18px空格。 But the thickness of the lines and the color(or opacity, I am not sure) are changing from top to bottom. 但是线条的粗细和颜色(或不透明度,我不确定)正在从顶部到底部发生变化。

Here is a fiddle : http://jsfiddle.net/J6zzD/1/ 这是一个小提琴: 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 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();

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

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

Because canvas coordinates do not directly reference pixels, special care must be taken to obtain crisp horizontal and vertical lines. 由于画布坐标不直接引用像素,因此必须特别注意获得清晰的水平和垂直线条。

Basically, because you're trying to draw a line that's 0.2 pixels wide, the browser does some math to approximate a continuous number into discrete units and you get your "fading" lines. 基本上,因为你试图绘制一个0.2像素宽的线,浏览器会进行一些数学计算,将连续数字近似为离散单位,然后得到“淡化”线。

So now we can fix up your code by changing context.lineWidth to 1 (I actually remove it because it defaults to 1) and shifting everything down by half a pixel. 所以现在我们可以通过将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 演示

That's again the eternal issue of forgetting to call beginPath. 这又是忘记调用beginPath的永恒问题。
Each time you call moveTo then lineTo, you create a new *sub*path, which adds to the current Path. 每次调用moveTo然后调用lineTo时,都会创建一个新的* sub *路径,该路径将添加到当前路径。
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. 然后每次调用stroke()时,当前路径,以便在第一次绘制最后添加的路径时重新绘制所有当前子路径。
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%的不透明度(lineWidth = 0.2)时,顶线将达到100%不透明度(alpha = 255)。

In your second fiddle, you stroke only once, so all lines have 20% opacity, which is correct for the 0.2 lineWidth. 在你的第二个小提琴中,你只画一次,所以所有的线都有20%的不透明度,这对于0.2行宽是正确的。

So : use beginPath before drawing a new figure. 所以:在绘制新图之前使用beginPath。
In this case you have two choices : 在这种情况下,您有两个选择:
• draw line by line OR •逐行绘制OR
• draw once a path with all lines as subpath. •绘制一条路径,将所有行作为子路径。

(see code below). (见下面的代码)。

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 . 提示 :要获得干净的线条,请记住像素的中心位于每个像素的(+0.5,+ 0.5)坐标处,因此“技巧”是在应用开始时平移0.5,0.5 ,然后仅使用圆角坐标和lineWidth

1) draw line by line 1)逐行绘制

http://jsfiddle.net/gamealchemist/J6zzD/6/ 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) draw multiple subPath : (you can have only one color for one stroke() ) 2)绘制多个子路径:(一个笔画只能有一种颜色())

http://jsfiddle.net/gamealchemist/J6zzD/7/ 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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM