Drawing lines with canvas by using for loop

前端 未结 2 1740
谎友^
谎友^ 2021-01-12 18:52

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

here is my canvas element:



        
相关标签:
2条回答
  • 2021-01-12 19:07

    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) .

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

    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).

    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) draw line by line

    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() )

    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);
    }
    
    0 讨论(0)
  • 2021-01-12 19:11

    See: 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.

    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.

    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

    0 讨论(0)
提交回复
热议问题