Just for context, I'm using html5, css, and jquery.
I'd like to be able to draw curved lines with arrowheads between two elements on a web page. I've nearly got it, but just can't wrap my head around the maths to draw the arrow heads. Could just be the manipulation of the canvas widget that's getting me.
Here's the javascript I'm using at the minute. It certainly feels the long way around, but it seems to get the job done except for those pesky arrowheads.
The 'influence' variable is to vary the lines a bit so that if there are multiple 开发者_如何学Pythonlines they will show one behind the other.
var start = $('#firstobject');
var last = $('#lastobject');
var stpos = start.position();
var lastpos = last.position();
var influence = Math.random*20+5;
var maxx = Math.max(stpos.left,lastpos.left);
var minx = Math.min(stpos.left,lastpos.left);
var maxy = Math.max(stpos.top,lastpos.top);
var miny = Math.min(stpos.top,lastpos.top);
var w = maxx - minx;
var h = maxy - miny;
var cname = "samplename";
var cpad = 30;
var cstr = "<canvas id='"+cname+"' class='huntgroupcanvas' style='z-index:2;position:absolute;left:"+(0+minx-cpad)+"px;top:"+(0+miny-cpad)+"px;' id='"+cname+"' width="+(2*cpad+w)+" height="+(2*cpad+h)+"></canvas>"
start.before(cstr);
var canvas = document.getElementById(cname);
var ctx = canvas.getContext("2d");
var dx = stpos.left - lastpos.left;
var dy = stpos.top - lastpos.top;
var dir = dy/dx;
var sx,sy,ex,ey;
if (dir<0) {
ex=w+cpad;
ey=cpad;
sx=cpad;
sy=h+cpad;
} else {
ex=w+cpad;
ey=h+cpad;
sx=cpad;
sy=cpad;
}
ctx.lineWidth=1;
ctx.strokeStyle = '#000';
ctx.beginPath();
ctx.moveTo(sx,sy);
ctx.quadraticCurveTo(((w/2)-(h/2))+cpad-influence,((h/2)-(w/2))+cpad,ex,ey);
ctx.stroke();
if (st==i-1) {
first=0;
ctx.beginPath();
if (dx<0) {
ctx.arc(sx,sy,6,0,Math.PI*2,0);
} else {
ctx.arc(ex,ey,6,0,Math.PI*2,0);
}
ctx.stroke();
}
/* Here's where I've been trying to draw the arrowheads.
* I know that I can get the slope of the line like so:
var m = (y2-y1)/(x2-x1);
* I know I can get the angle in radians as
var angle=Math.atan(m);
* I'm trying to use rotation to draw the arrowhead
*/
ctx.save();
ctx.beginPath();
angle = Math.atan(dir);
if (dx<0) {
sx=ex;
sy=ey;
angle = Math.atan(-dir);
}
ctx.moveTo(sx,sy);
ctx.translate(sx,sy);
ctx.rotate(angle - 0.05);
ctx.lineTo(20,0);
ctx.rotate(angle + 0.05);
ctx.lineTo(20,0);
ctx.closePath();
ctx.fill();
ctx.restore();
That is a lot of code to read, but it would seem that you are messing up your trigonometry when generating the angle of the arrowhead. Take a look at the atan2 function, it takes a 2D vector and converts it to it's angle. So you would want to use angle=Math.atan2(dy,dx)
精彩评论