I am attempting to have a line go between the two dots on my page. The images are draggable and placeable into the DIVs so their position can change yet the line still needs to connect them.
So far I have tried this with only a custom line to start there.
var s = document.getElementById("Red1X");
var x = 200, y = 200;
s.style.x2 = x + "px";
s.style.y2 = y + "px";
function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
ev.dataTransfer.setData("text", ev.target.id);
}
function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
ev.target.appendChild(document.getElementById(data));
}
#div1 {
width: 17px;
height: 17px;
padding: 0px;
border: 1px solid #aaaaff;
float: left
}
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<img id="RED1" src="http://i.imgur.com/By4xvE5.png" draggable="true" ondragstart="drag(event)" align="left">
<img id="RED2" src="http://i.imgur.com/By4xvE5.png" draggable="true" ondragstart="drag(event)" align="left">
<svg height="500" width="500">
<line id="Red1X" x1="0" y1="0" x2="100" y2="200" style="stroke:rgb(255,0,0);stroke-width:3" />
</svg>
There are two ways to add a horizontal line between two divs. First, put a <hr> tag between the two divs, and the second is to place any block-level element such as a div, p, etc, between the two divs and apply a bottom or top border on it. Either way, you can achieve the same task.
To get all elements to appear on one line the easiest way is to: Set white-space property to nowrap on a parent element; Have display: inline-block set on all child elements.
Ok, as mentioned in comments, it is relatively easy when dots are in same line.
Things get more complicated if you have one above another - then you basically need: angle, to apply it to CSS transform:rotate property, and length between two dots/elements, to recalculate width, since it is not straight line anymore. I hate math :), so i used knowledge from good people from internet: http://jsfiddle.net/codepo8/bAwUf/light/ (credits to codepo8)
Two most important lines:
var angle= Math.atan2(red2.offsetTop - red1.offsetTop, red2.offsetLeft - red1.offsetLeft) * 180 / Math.PI;
var length = Math.sqrt((red2.offsetLeft-red1.offsetLeft) * (red2.offsetLeft-red1.offsetLeft) + (red2.offsetTop-red1.offsetTop) * (red2.offsetTop-red1.offsetTop));
And now, your script should be like this:
var s = document.querySelector(".line");
red1=document.getElementById('RED1');
red2=document.getElementById('RED2');
function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
ev.dataTransfer.setData("text", ev.target.id);
}
function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
ev.target.appendChild(document.getElementById(data));
s.style.left=red1.offsetLeft+5+'px';
s.style.top=red1.offsetTop+5+'px';
s.style.visibility='visible';
var angle= Math.atan2(red2.offsetTop - red1.offsetTop, red2.offsetLeft - red1.offsetLeft) * 180 / Math.PI;
var length = Math.sqrt((red2.offsetLeft-red1.offsetLeft) * (red2.offsetLeft-red1.offsetLeft) + (red2.offsetTop-red1.offsetTop) * (red2.offsetTop-red1.offsetTop));
s.style.width=Math.abs(length)+'px';
s.style.transform="rotate("+Math.round(angle)+"deg)";
s.style.transformOrigin ="0 0";
}
.div1 {
width: 150px;
height: 150px;
padding: 0px;
border: 1px solid #aaaaff;
float: left;
}
.line {
position:absolute;
height:3px;
background:red;
width:100px;
z-index:999;
visibility:hidden;
}
<div class="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div class="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div class="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div class="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div class="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div class="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div class="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div class="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div class="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div class="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div class="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div class="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div class="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div class="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div class="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<img id="RED1" src="http://i.imgur.com/By4xvE5.png" draggable="true" ondragstart="drag(event)" align="left">
<img id="RED2" src="http://i.imgur.com/By4xvE5.png" draggable="true" ondragstart="drag(event)" align="left">
<div class="line">
</div>
This is good starting point, i guess (few things are left to make it perfect), but i think i you will get it...
DEMO (better to see it here, snippets are not great, for this kind of demos): https://jsfiddle.net/dxre19o6/
Here is one example that uses jQuery and the jQuery UI positioning plugin.
Adjust the SVG so that it becomes your background. That way, it won't get in the way of trying to click on the dots.
<svg style="position:absolute;top:0;left:0;height:100%;bottom:100%;z-index:-1">
<line id="Red1X" x1="0" y1="0" x2="100" y2="200" style="stroke:rgb(255,0,0);stroke-width:3" />
</svg>
<div class="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div class="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div class="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<img id="RED1" src="http://i.imgur.com/By4xvE5.png" draggable="true" ondragstart="drag(event)" align="left">
<img id="RED2" src="http://i.imgur.com/By4xvE5.png" draggable="true" ondragstart="drag(event)" align="left">
On drop, you need to reposition the line by grabbing the position of the dots and modifying the x1,y1,x2,y2
coordinates of the SVG.
function positionLine(){
d1.data('position', d1.position());
d2.data('position', d2.position());
line.attr('x1', d1.data('position').left + (d1.width() / 2));
line.attr('y1', d1.data('position').top + (d1.height() / 2));
line.attr('x2', d2.data('position').left + (d2.width() / 2));
line.attr('y2', d2.data('position').top + (d2.height() / 2));
}
Here is a working Plunker: https://plnkr.co/edit/1fVBcqRsxc7r6gFZx0bR?p=preview
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With