Drawing A Line Between Two Draggable DIVs

Drawing a line between 2 moving DIVs can be tricky sometimes. It involves a little bit of Mathematical knowledge and a few jQuery plugins.

Demo: http://kennykee.com/demo/draw-line/

Drawing A Line Between Two Draggable DIVs

screenshot

The code:

<!DOCTYPE HTML>
<html>
<head>
	<script src="jquery-1.9.1.min.js" type="text/javascript"></script>
	<script src="jquery-ui.js" type="text/javascript"></script>
	<script src="jQueryRotateCompressed.2.2.js" type="text/javascript"></script>
	<style>
		.box{
			width: 100px;
			height: 100px;
			border: solid thin black;
			position: absolute;
			cursor: pointer;
			-webkit-border-radius: 10px;
			-moz-border-radius: 10px;
			border-radius: 10px;
			-webkit-box-shadow:  3px 3px 2px 2px rgba(1, 1, 1, .3);
			box-shadow:  3px 3px 2px 2px rgba(1, 1, 1, .3);
			text-align: center;
			font-weight: bold;
			color: black;
			padding-top: 5px;
			font-family: Verdana;
		}
		.box1{
			background-color: green;
		}
		.box2{
			background-color: yellow;
		}
		#line{
			width: 100px;
			height: 10px;
			border: solid thin red;
			position: absolute;
			background-color: red;
			-webkit-border-radius: 10px;
			-moz-border-radius: 10px;
			border-radius: 10px;
		}
		.kennykee-styles{
			font-size: 20px; 
			font-family: Arial; 
			margin: 10px; 
			font-weight:bold;
		}
	</style>
	<script type="text/javascript">
		var boxCenterXOffset = 50;
		var boxCenterYOffset = 50;

		$(document).ready(function(){
			$(".box").draggable({ delay: 0, distance: 0 },{
				drag: function(event, ui){
					var x1 = $("#box1").offset().left + boxCenterXOffset;
					var x2 = $("#box2").offset().left + boxCenterXOffset;
					var y1 = $("#box1").offset().top + boxCenterYOffset;
					var y2 = $("#box2").offset().top + boxCenterYOffset;

					var hypotenuse = Math.sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));
					var angle = Math.atan2((y1-y2), (x1-x2)) *  (180/Math.PI);
					if(angle >= 90 && angle < 180){
						y1 = y1 - (y1-y2);
					}
					if(angle > 0 && angle < 90){
						x1 = x1 - (x1-x2);
						y1 = y1 - (y1-y2);
					}
					if(angle <= 0 && angle > -90){
						x1 = x1 - (x1-x2);
					}

					$("#line").queue(function(){
						$(this).offset({top: y1, left: x1});
						$(this).dequeue();
					}).queue(function(){
						$(this).width(hypotenuse);
						$(this).dequeue();
					}).queue(function(){
						$(this).rotate(angle);
						$(this).dequeue();
					});

					$("#gx").html(x1);
					$("#gy").html(y1);
					$("#yx").html(x2);
					$("#yy").html(y2);
					$("#lx").html($("#line").offset().left);
					$("#ly").html($("#line").offset().top);
					$("#degree").html(angle);
				}
			});
		});

	</script>
</head>
<body>
	<div class="kennykee-styles"><a href="http://kennykee.com">KennyKee Styles</a></div>
	<div id="box1" class="box1 box">Drag Me</div>
	<div style="margin-bottom: 100px;"> </div>
	<div id="box2" class="box2 box">Drag Me</div>
	<div style="margin-bottom: 100px;"> </div>
	<div id="line"></div>
	<div style="margin-bottom: 100px;"> </div>

	Green Box: X=<span id="gx"></span> Y=<span id="gy"></span><br />
	Yellow Box: X=<span id="yx"></span> Y=<span id="yy"></span><br />
	Line Box: X=<span id="lx"></span> Y=<span id="ly"></span><br />
	Degree = <span id="degree"></span> <br />
</body>
</html>

Some explanation:
1) First, we have 3 divs. 2 divs will be the draggable objects. The 3rd div will be the “line” connecting these 2 divs.

2) During dragging process, the line div is positioned at the center of first draggable object. Note that “center” means offset of first draggable object plus (+) half the width of draggable object.

3) Next, we have to get the distance between the draggable divs by using hypotenuse formula between 2 points. Set the width of the line div as the distance between the 2 draggable divs.

4) Finally, we have to calculate the angle between the two draggable divs. We can get the angle by using arctangent formula. In JavaScript, we can use Math.atan2(). Set the rotation degree of the line div using this angle.

Note that arctangent has a value between 180° and -180º. Hence, we use the method below to shift the line div to correct position.

if(angle >= 90 && angle < 180){
						y1 = y1 - (y1-y2);
}
if(angle > 0 && angle < 90){
						x1 = x1 - (x1-x2);
						y1 = y1 - (y1-y2);
}
if(angle <= 0 && angle > -90){
						x1 = x1 - (x1-x2);
}

And now we have one line drawn between 2 draggable divs.

Demo: http://kennykee.com/demo/draw-line/

9 thoughts on “Drawing A Line Between Two Draggable DIVs

  1. RajKut

    I have tried the same without draggable, but when ever I am changing the div position through css, the line is not aligned with divs. I need the line should start from center-right of the first div and to the center-left of the second div. Help?

    Reply
  2. Suryakant

    Hii KennyKee;
    First of all thanks lot for your demo.
    I am using same thing in my project and successfully i have created one to one relation and re-sizable also working fine, but the problem what i am facing is that when i have more then one node connecting to a particular node or when i am creating one to many relation facing problem.
    According your logic it will only connecting the line between two div.
    So i tried lot to connect but not getting any solution.
    So if you have any solution for above please reply me.
    Really brother i am stocked at a point !!!
    so if your require source code i will forward you; please give me any suggestion how to do this.
    Thanks.
    Regards;
    SK.

    Reply
  3. Suryakant

    Problem what i Faced which I forget to mention in my previous reply :-
    I have successfully creating links between one node to other node(1 to many).
    Links added but while moving it will only moving one link not other nodes link.
    Suppose i have a node A and I have connected two link from node A to B and C with link0 and Link1.
    Statically link added successfully between the node but when i am dragging Node A and moving only one link moves (link0) not other moving.
    What i required is that to move all the link what a node has.
    Hope you get a clear picture.

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *


− 6 = two