Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save abhishekbhalani/b8728b84a2ca5e2c17c61a55489521cf to your computer and use it in GitHub Desktop.

Select an option

Save abhishekbhalani/b8728b84a2ca5e2c17c61a55489521cf to your computer and use it in GitHub Desktop.
Connect two elements / draw a path between two elements with SVG path (using jQuery)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" type="text/css" href="style.css">
<title>Connect divs with SVG</title>
</head>
<body>
<div id="svgContainer" style="margin: 50px 50px;">
<svg id="svg1" width="500" height="400" >
<path
id="path1"
d="M0 0"
stroke="#000"
fill="none"
stroke-width="12px";/>
<path
id="path2"
d="M0 0"
stroke="#000"
fill="none"
stroke-width="12px";/>
<path
id="path3"
d="M0 0"
stroke-width="8px"
style="stroke:#000; fill:none;"/>
<path
id="path4"
d="M0 0"
stroke-width="12px"
style="stroke:#000; fill:none; stroke-width: 12px;" />
<path
id="path5"
d="M0 0"
stroke-width="10px"
style="stroke:#000; fill:none;"/>
<path
id="path6"
d="M0 0"
stroke-width="10px"
style="stroke:#000; fill:none;"/>
</svg>
</div>
<div id= "outer">
<div id="teal"> </div>
<div id="red"> </div>
<div id="green"> </div>
<div id="purple"> </div>
<div id="orange"> </div>
<div id="aqua"> </div>
</div>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="svgDraw.js"></script>
</body>
</html>
body{ background-color:gray; }
#svgContainer {
z-index: -10;
display: none;
position:absolute;
background-color:silver;
opacity: 0.5;
}
div{ opacity: 0.6; }
#outer{
margin:0 auto;
width: 80%;
}
#teal{
width: 6em;
height: 6em;
background-color:teal;
margin-left: 10%;
}
#orange{
height: 4em;
width: 35%;
padding: 2em 8em;
margin-left: 8em;
margin-top: 6em;
background-color: orange;
}
#red{
width:6em;
height: 4em;
margin-left: 30%;
padding:4em 3em;
background-color:red;
}
#aqua{
width: 5em;
height: 5em;
margin-left:15%;
background-color:aqua;
}
#purple{
width: 15em;
height: 5em;
background-color:purple;
}
#green{
width: 5em;
height: 7em;
margin-top: 2em;
margin-left: 50%;
background-color: green;
}
function connectElements(svg, path, startElem, endElem) {
//only one svgContainer fot this demo
var svgContainer= $("#svgContainer");
// if first element is lower than the second, swap!
if(startElem.offset().top > endElem.offset().top){
var temp = startElem;
startElem = endElem;
endElem = temp;
}
// get (top, left) corner coordinates of the svg container
svgTop = svgContainer.offset().top;
svgLeft = svgContainer.offset().left
// get (top, left) coordinates for the two elements
startCoord = startElem.offset();
endCoord = endElem.offset();
// calculate path's start (x,y) coords
// we want the x coordinate to visually result in the element's mid point
startX = startCoord.left + 0.5*startElem.outerWidth() - svgLeft; // x = left offset + 0.5*width - svg's left offset
startY = startCoord.top + startElem.outerHeight() - svgTop; // y = top offset + height - svg's top offset
// calculate path's end (x,y) coords
endX = endCoord.left + 0.5*endElem.outerWidth() - svgLeft;
endY = endCoord.top - svgTop;
// call function for drawing the path
drawPath(svg, path, startX, startY, endX, endY);
}
function drawPath(svg, path, startX, startY, endX, endY){
// get the path's stroke width (if one wanted to be really precize, one could use half the stroke size)
var stroke = parseFloat(path.attr("stroke-width"));
// check if the svg is big enough to draw the path, if not, set heigh/width
if (svg.attr("height") < endY) svg.attr("height", endY);
if (svg.attr("width" ) < (startX + stroke) ) svg.attr("width", (startX + stroke));
if (svg.attr("width" ) < (endX + stroke) ) svg.attr("width", (endX + stroke));
var deltaY = (endY - startY) * 0.15;
var deltaX = (endX - startX) * 0.15;
// for further calculations which ever is the shortest distance (arbitrary choice, could have been the other way around)
var delta = deltaY < Math.abs(deltaX) ? deltaY : Math.abs(deltaX)
// set sweep-flag (counter/clock-wise)
// if start element is closer to the left edge,
// draw the first arc counter-clockwise, and the second one clock-wise
var arc1 = 0;
var arc2 = 1;
if (startX > endX) {
arc1 = 1;
arc2 = 0;
}
// draw tha pipe-like path
// 1. move a bit down, 2. arch, 3. move a bit to the right, 4.arch, 5. move down to the end
path.attr("d", "M" + startX + " " + startY +
" V" + (startY + delta) +
" A" + delta + " " + delta + " 0 0 " + arc1 + " " + (startX+delta * Math.sign(deltaX)) + " " + (startY+delta*2) +
" H" + (endX-delta* Math.sign(deltaX)) +
" A" + delta + " " + delta + " 0 0 " + arc2 + " " + endX + " " + (startY+delta*3) +
" V" + endY );
}
$(document).ready(function() {
// display the svg
$("#svgContainer").css("display", "block");
// connect all the paths you want!
connectElements($("#svg1"), $("#path1"), $("#teal"), $("#orange"));
connectElements($("#svg1"), $("#path2"), $("#red"), $("#orange"));
connectElements($("#svg1"), $("#path3"), $("#teal"), $("#aqua") );
connectElements($("#svg1"), $("#path4"), $("#red"), $("#aqua") );
connectElements($("#svg1"), $("#path5"), $("#purple"), $("#teal") );
connectElements($("#svg1"), $("#path6"), $("#orange"), $("#green") );
});
$(window).resize(function () {
connectElements($("#svg1"), $("#path1"), $("#teal"), $("#orange"));
connectElements($("#svg1"), $("#path2"), $("#red"), $("#orange"));
connectElements($("#svg1"), $("#path3"), $("#teal"), $("#aqua") );
connectElements($("#svg1"), $("#path4"), $("#red"), $("#aqua") );
connectElements($("#svg1"), $("#path5"), $("#purple"), $("#teal") );
connectElements($("#svg1"), $("#path6"), $("#orange"), $("#green") );
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment