Drawing lines with continuously varying line width on HTML canvas

前端 未结 3 628
一向
一向 2021-02-02 00:13

I\'m trying to draw a line that starts as a thin line and then gadually widens until the end. I need to draw semi-smooth curves (composite out of several straight lines) and I\'

3条回答
  •  南方客
    南方客 (楼主)
    2021-02-02 00:39

    For those interested, I have come up with two solutions to my problem.

    The first idea was to actually draw each point as a corner, using canvas to draw a neat angle. A demo can be seen at:

    http://jsfiddle.net/7BkyK/2/

    var ctx = document.getElementById('canvas1').getContext('2d');
    var points = [null, null, null];
    
    for(var i=0; i<24; i++)
    {
        var width = 0.5 + i/2;
    
        var m = 200;
    
        var x = Math.cos(i/4) * 180;
        var y = Math.sin(i/4) * 140;
    
        points[0] = points[1];
        points[1] = points[2];
        points[2] = { X:x, Y:y};
    
        if(points[0] == null)
            continue;
    
        var px0 = (points[0].X + points[1].X) / 2;
        var py0 = (points[0].Y + points[1].Y) / 2;
    
        var px1 = (points[1].X + points[2].X) / 2;
        var py1 = (points[1].Y + points[2].Y) / 2;
    
        ctx.beginPath();
        ctx.lineWidth = width;
        ctx.strokeStyle = "rgba(0,0,0,0.5)";
        ctx.moveTo(m+px0,m+py0);
        ctx.lineTo(m+points[1].X,m+points[1].Y);
        ctx.lineTo(m+px1,m+py1);
        ctx.stroke();
    }
    ​
    

    The second and much prettier solution, as suggested by Shmiddty, is to use bezier curves. This proved to be a great solution:

    http://jsfiddle.net/Ssrv9/1/

    // 1.
    // Varying line width, stroking each piece of line separately
    var ctx = document.getElementById('canvas1').getContext('2d');
    var points = [null, null, null, null];
    
    for(var i=-1; i<25; i = i +1)
    {
        var width = 0.5 + i/2;
    
        var m = 200;
    
    
        var x = Math.cos(i/4) * 180;
        var y = Math.sin(i/4) * 140;
    
        points[0] = points[1];
        points[1] = points[2];
        points[2] = { X:x, Y:y};
    
        if(points[0] == null)
            continue;
    
    
        var p0 = points[0];
        var p1 = points[1];
        var p2 = points[2];
    
        var x0 = (p0.X + p1.X) / 2;
        var y0 = (p0.Y + p1.Y) / 2;
    
        var x1 = (p1.X + p2.X) / 2;
        var y1 = (p1.Y + p2.Y) / 2;
    
        ctx.beginPath();
        ctx.lineWidth = width;
        ctx.strokeStyle = "black";
    
        ctx.moveTo(m+x0, m+y0);
        ctx.quadraticCurveTo(m+p1.X, m+p1.Y, m+x1, m+y1);
        ctx.stroke();
    }
    

提交回复
热议问题