javascript - Draw a line with two different sized ends -


how can have line 2 different sizes canvas?

i have line drawing canvas start out width of 30 , gradually(proportionally) reduce down size of 15, reaches 15 right @ end of line.

i though perhaps if set context.linewidth in 2 places (start , end) work.

<!doctype html>  <html>    <head>      <style>        body {          margin: 0px;          padding: 0px;        }      </style>    </head>    <body>      <canvas id="mycanvas" width="578" height="200"></canvas>      <script>        var canvas = document.getelementbyid('mycanvas');        var context = canvas.getcontext('2d');          context.beginpath();        context.moveto(100, 150);        context.linewidth = 30;        context.lineto(450, 50);        context.linewidth = 15;        context.stroke();      </script>    </body>  </html>

i once wondered building such variable-width line, , ended building own solution, , wrote blog post out of it.
i'll copy first part of here, rounded version can found here : https://gamealchemist.wordpress.com/2013/08/28/variable-width-lines-in-html5-canvas/


variable width lines in html5

drawing such [variable width] line quite easy once realize need draw not line : in fact polygon.

if line segment want draw (a,b), situation looks :

enter image description here

what want draw in fact a1,a2,b2,b1 polygon.

if call n normal vector (drawn on scheme), , w1 , w2 width in , b respectively, have :
a1 = + n * w1/2
a2 = – n * w1/2
b1 = b + n * w2/2
b2 = b – n * w2/2

so how find normal vector n ?
maths says if (x,y) defines vector v , normal vector coordinates (-y, x).
n, vector normal ab hence have ( – ( yb – ya ) , ( xb – xa ) ) coordinates.
there annoying thing vector : depends on ab length, not want : need normalize vector, i.e. have standard length of 1, when later multiply vector w1/2, right length vector added.

vector normalisation done dividing x , y of vector vector length. since length found using phytagore’s theorem, makes 2 squares, 1 square root, , 2 divides find normalized vector n :

// computing normalized vector normal ab length = math.sqrt( sq (xb-xa) + sq (yb - ya) ) ; nx     =  -  (yb - ya) / length ; ny     =     (xb - xa) / length ;   

so can compute 4 points, let link them poly-line, , fill resulting shape : here comes our variable width segment !

here javascript code :

// varline : draws line a(x1,y1) b(x2,y2) // starts w1 width , ends w2 width. // relies on fillstyle color. // ctx valid canvas's context2d. function varline(ctx, x1, y1, x2, y2, w1, w2) {     var dx = (x2 - x1);     var dy = (y2 - y1);     w1 /= 2;  w2 /= 2; // use w1/2 , w2/2 computations.     // length of ab vector     var length = math.sqrt(sq(dx) + sq(dy));     if (!length) return; // exit if 0 length     dx /= length ;    dy /= length ;     var shiftx = - dy * w1   // compute aa1 vector's x     var shifty =   dx * w1   // compute aa1 vector's y     ctx.beginpath();     ctx.moveto(x1 + shiftx, y1 + shifty);     ctx.lineto(x1 - shiftx, y1 - shifty); // draw a1a2     shiftx =  - dy * w2 ;   // compute bb1 vector's x     shifty =    dx * w2 ;   // compute bb1 vector's y     ctx.lineto(x2 - shiftx, y2 - shifty); // draw a2b1     ctx.lineto(x2 + shiftx, y2 + shifty); // draw b1b2     ctx.closepath(); // draw b2a1     ctx.fill();     } 

so let see result on small example : drawing variable width segments within circle nice hsl colors :

enter image description here

(about @marke's (interesting) remark on chaining line segments, fear quite difficult goal, since there many specific cases depending on line length/ w1 /w2 / angle in between segments. quite solved using force fields , marching cubes, fear off-topic !! :-) )


Comments

Popular posts from this blog

javascript - AngularJS custom datepicker directive -

javascript - jQuery date picker - Disable dates after the selection from the first date picker -