javascript - Drawing lines between 2 elements onclick -
is there way (i guess always) draw line between 2 elements? div , img tags wwith different ids. heres html
<div id="textholder"> <div class="text" id="text0"><p>masă</p></div> </div> <div id="objectholder"> <img class="obiecte" id="obj0" src="images/macara.svg"> </div>
ok,so need draw line between div inside of div id="textholder" , image inside div id="objectholder".first clicking on div inside of textholder drawing line between them when user click on image inside of objectholder.
i know must add code didnt found show.
here's fiddle: http://jsfiddle.net/4durb/
i've done little bit of work on one, because piqued interest. there jsbin (preferred jsfiddle because of console) here http://jsbin.com/guken/3/
the method create floating canvas element (shaded pink), , lay underneath rest of dom (using z-index). calculate points on borders of 2 boxes correspond line between box centres. red , blue squares divs move line ends, used annotation source, target etc.
in jsbin, can click on 1 element, , line ready click on next. detects hover chosen elements , snaps target if hover on one.
i won't paste code here, bit draw line 1 x,y position in client dom coordinates this:
var lineelem; function drawlinexy(fromxy, toxy) { if(!lineelem) { lineelem = document.createelement('canvas'); lineelem.style.position = "absolute"; lineelem.style.zindex = -100; document.body.appendchild(lineelem); } var leftpoint, rightpoint; if(fromxy.x < toxy.x) { leftpoint = fromxy; rightpoint = toxy; } else { leftpoint = toxy; rightpoint = fromxy; } var linewidthpix = 4; var gutterpix = 10; var origin = {x:leftpoint.x-gutterpix, y:math.min(fromxy.y, toxy.y)-gutterpix}; lineelem.width = math.max(rightpoint.x - leftpoint.x, linewidthpix) + 2.0*gutterpix; lineelem.height = math.abs(fromxy.y - toxy.y) + 2.0*gutterpix; lineelem.style.left = origin.x; lineelem.style.top = origin.y; var ctx = lineelem.getcontext('2d'); // use identity matrix while clearing canvas ctx.save(); ctx.settransform(1, 0, 0, 1, 0, 0); ctx.clearrect(0, 0, lineelem.width, lineelem.height); ctx.restore(); ctx.linewidth = 4; ctx.strokestyle = '#09f'; ctx.beginpath(); ctx.moveto(fromxy.x - origin.x, fromxy.y - origin.y); ctx.lineto(toxy.x - origin.x, toxy.y - origin.y); ctx.stroke(); }
as example 1 line, , can store lines have been 'finished' ready create more, uses global variable lineelem
. on first attempt draw line, creates canvas element, inserts dom , assigns lineelem. after construction, subsequently reuses canvas element, changing size , redrawing new coordinate pairs.
to prevent line being cut off edge of canvas, there gutter setting pads canvas width , height. rest getting coordinate translation right between client dom coordinates , coordinates drawing on canvas itself.
the other unstraightforward bit calculating coordinates of point on border of box along line. it's not perfect, it's reasonable start. crux calculate angle of target (to
) point perspective of source (from
) point, , see how compares known angles of box corners:
function getnearestpointoutside(from, to, boxsize) { // side hit? // angle of from. var theta = math.atan2(boxsize.y, boxsize.x); var phi = math.atan2(to.y - from.y, to.x - from.x); var nearestpoint = {}; if(math.abs(phi) < theta) { // crosses +x nearestpoint.x = from.x + boxsize.x/2.0; nearestpoint.y = from.y + ((to.x === from.x) ? from.y : ((to.y - from.y)/(to.x - from.x) * boxsize.x/2.0)); } else if(math.pi-math.abs(phi) < theta) { // crosses -x nearestpoint.x = from.x - boxsize.x/2.0; nearestpoint.y = from.y + ((to.x === from.x) ? from.y : (-(to.y - from.y)/(to.x - from.x) * boxsize.x/2.0)); } else if(to.y > from.y) { // crosses +y nearestpoint.y = from.y + boxsize.y/2.0; nearestpoint.x = from.x + ((to.y === from.y) ? 0 : ((to.x - from.x)/(to.y - from.y) * boxsize.y/2.0)); } else { // crosses -y nearestpoint.y = from.y - boxsize.y/2.0; nearestpoint.x = from.x - ((to.y === from.y) ? 0 : ((to.x - from.x)/(to.y - from.y) * boxsize.y/2.0)); } return nearestpoint; }
theta angle first box corner, , phi actual line angle.
to positions of boxes in client coordinates, need use elem.getboundingclientrect()
, yields left, top, width, height among other things, , use find centre of box:
function getcentreofelement(el) { var bounds = el.getboundingclientrect(); return {x:bounds.left + bounds.width/2.0, y:bounds.top + bounds.height/2.0}; }
putting together, can draw line 1 element another.
Comments
Post a Comment