Drawing lines between two onclick elements

Is there a way (I think its always) to draw a line between two elements? Div and img tags with different identifiers. Heres is some 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> 

So, I need to draw a line between the div inside another div with id = "textHolder" and the image inside the div with id = "objectHolder". First click on the div inside the textHolder, then draw a line between them when the user clicks on the image inside the objectHolder.

I know I have to add code, but I did not find anything good to show.

Here's the script: http://jsfiddle.net/4DURB/

0
source share
2 answers

I worked a little on this because it aroused my interest. There is jsbin (preferably jsfiddle just because of the console) here http://jsbin.com/guken/3/

example output

The method is to create a floating canvas element (shaded pink) and lay it under the rest of the DOM (using z-index). Then I calculate the points at the borders of two fields that correspond to the line between the centers of the boxes. Red and blue squares are actually divs that move with the ends of the line, which can be used for annotations, such as source, target, etc.

In this jsbin, you can click on one item and then get a line ready to click on. It detects the freezing of selected elements and target bindings if you hover over one.

I will not paste all the code here, but the bit where we draw the line from one x, y position to another in the client DOM coordinates is as follows:

 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 the identity matrix while clearing the 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(); } 

Only one line is used as an example, and we can always save the lines that are ready to be created and use the global variable lineElem . On the first attempt to draw a line, it creates a canvas element, inserts it into the DOM, and assigns it to the lineElem element. After this construction, he subsequently reuses the canvas element, resizing and redrawing new coordinate pairs.

To prevent the line from being cut off by the edge of the canvas, there is a gutter setting that fills the width and height of the canvas. The rest simply receives a coordinate translation directly between the client DOM coordinates and the coordinates for drawing on the canvas itself.

The only other fuzzy bit calculates the coordinates of a point on the field boundary along the line. This is not ideal, but it is a reasonable start. The goal is to calculate the angle of the target point ( to ) from the point of view of the source point ( from ) and see how this compares with the known angles of the box corners:

 function getNearestPointOutside(from, to, boxSize) { // which side does it hit? // get the angle of to from 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 is the angle to the first corner of the window, and phi is the actual angle of the line.

To get the cell positions in the client coordinates, you need to use elem.getBoundingClientRect() , which, among other things, gives the left, top, width and height, and I use to find the center of the field:

 function getCentreOfElement(el) { var bounds = el.getBoundingClientRect(); return {x:bounds.left + bounds.width/2.0, y:bounds.top + bounds.height/2.0}; } 

Combining all this, you can draw a line from one element to another.

+2
source

It’s best to use an HTML <canvas> . I'm not an expert in using canvas elements, but yours will probably look something like this:

 <script> var can = document.getElementById("canvasName"); var candraw = c.getContext("2d") candraw.moveTo(position of textHolder); candraw.lineTo(position of objectHolder); candraw.stroke(); </script> 

Hope this helps.

+2
source

All Articles