Tommy
Tommy

Reputation: 2453

Canvas drawing dashed line with arrow

I use the following code to draw a line with a arrow. My problem is that i want to have the line dashed but not the arrow top:

function canvas_arrow_alternate2(context, fromx, fromy, tox, toy){
    var headlen = 12;   // length of head in pixels
    var angle = Math.atan2(toy-fromy,tox-fromx);

    context.setLineDash([10]);
    context.moveTo(fromx, fromy);
    context.lineTo(tox, toy);
    context.setLineDash([0]);
    context.lineTo(tox-headlen*Math.cos(angle-Math.PI/6),toy-headlen*Math.sin(angle-Math.PI/6));
    context.moveTo(tox, toy);
    context.lineTo(tox-headlen*Math.cos(angle+Math.PI/6),toy-headlen*Math.sin(angle+Math.PI/6));
}

The output now is a arrow which is not dashed. The problem is the change of the "setLineDash". How can i said that

context.moveTo(fromx, fromy);
context.lineTo(tox, toy);

use

context.setLineDash([10]);

and the code later not?

Thanks

Upvotes: 0

Views: 1917

Answers (1)

GameAlchemist
GameAlchemist

Reputation: 19294

You cannot define a path with that level of accuracy : when you either fill or stroke, the current settings (strokeStyle, fillStyle, font for fillText/strokeText immediate functions, lineDash, globalAlpha...) will be used to draw all the sub-path you built since last beginPath().
So for instance you couldn't build a yellow-red-blue-... line, with several lineTo and change in strokeStyle, then stroke() it at once : it would be drawn with the last color you set.

So in you case, you have to draw your arrow in two passes : the (untested) code below will hopefully help you find a way :

function canvas_arrow_alternate2(context, fromx, fromy, tox, toy, strokeStyle){
    var headlen = 12;   // length of head in pixels
    var angle = Math.atan2(toy-fromy,tox-fromx);
    context.save();    
    context.strokeStyle=strokeStyle || '#000'; // defaults to black
    // dashed part
    context.beginPath();
    context.setLineDash([10]);
    context.moveTo(fromx, fromy);
    context.lineTo(tox, toy);
    context.stroke();
    // second part -non dashed-
    context.beginPath();
    context.setLineDash([0]);
    context.moveTo(tox, toy);
    context.lineTo(tox-headlen*Math.cos(angle-Math.PI/6),toy-headlen*Math.sin(angle-Math.PI/6));
    context.moveTo(tox, toy);
    context.lineTo(tox-headlen*Math.cos(angle+Math.PI/6),toy-headlen*Math.sin(angle+Math.PI/6));
    context.stroke();
    // 
    context.restore();          // this will, in fact, restore strokeStyle
}
// notice you can get rid of save/restore if all your drawing methods sets the color before drawing.

Be sure (maybe you do) to use beginPath() to begin... well... each new Path, otherwise all draw commands will pile-up and all get executed on each stroke() or fill(), leading to a slow down.

Upvotes: 3

Related Questions