Skip to content

Instantly share code, notes, and snippets.

@sinedoOo
Forked from alojzije/connectHTMLelements_SVG.png
Last active March 21, 2016 08:23
Show Gist options
  • Save sinedoOo/00e4548d36c044afa71b to your computer and use it in GitHub Desktop.
Save sinedoOo/00e4548d36c044afa71b to your computer and use it in GitHub Desktop.
Connect two vertical aligned elements / draw a path between two elements with SVG path (using jQuery)

vertically connect html elements with SVG path

Gist contains a javaScript file svgDraw.js for connecting any vertically aligned html elements with an SVG path in a pipe-like fashion.

Also, index.html, and style.css are provided for demonstration purposes.

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Vertically connect divs with SVG path</title>
<link rel="stylesheet" type="text/css" href="style.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
</head>
<body>
<div id="svgContainer"></div>
<div id= "outer">
<div id="purple"></div>
<div id="teal"></div>
<div id="purple2"></div>
<div id="teal2"></div>
</div>
<script src="svgDraw.js"></script>
</body>
</html>
body {
margin: 0;
}
#svgContainer {
z-index: -1;
position: absolute;
width: 100%;
height: 100%;
opacity: 1;
}
#svgContainer > svg {
width: 100%;
height: 100%;
}
#outer {
margin: 0;
}
#teal {
width: 8em;
height:8em;
background-color:teal;
margin-left: 30%;
margin-top: 0em;
}
#purple {
width: 8em;
height: 8em;
background-color:purple;
margin-top: 0em;
}
#teal2 {
width: 8em;
height:8em;
background-color:teal;
margin-left: 30%;
margin-top: -16em;
}
#purple2 {
width: 8em;
height: 8em;
background-color:purple;
margin-top: 10em;
}
function signum(x) {
return (x < 0) ? -1 : 1;
}
function absolute(x) {
return (x < 0) ? -x : x;
}
function drawPath(svg, path, startX, startY, endX, endY) {
// how smooth corners
var deltaX = (endX - startX) * 0.07;
var delta = absolute(deltaX);
var arc1 = 0;
var arc2 = 1;
var swap = 1;
if (startY > endY) {
swap = -1;
arc1 = 1;
arc2 = 0;
delta = -1*delta;
}
if (startY === endY) {
delta = 0;
}
var space = 15;
// draw tha pipe-like path
path.attr("d", "M" + startX + " " + startY +
" H" + (endX - space - (swap*delta)) +
" A" + delta + " " + delta + " 0 0 " + arc2 + " " + (endX - space) + " " + (startY + delta) +
" V" + (endY - delta) +
" A" + delta + " " + delta + " 0 0 " + arc1 + " " + (endX - space + (swap*delta)) + " " + endY +
" H" + endX
);
}
function connectElements(svg, path, startElem, endElem) {
var svgContainer= $("#svgContainer");
// get (top, right) corner coordinates of the svg container
var svgTop = svgContainer.offset().top;
var svgLeft = svgContainer.offset().left;
// get (top, left) coordinates for the two elements
var startCoord = startElem.offset();
var endCoord = endElem.offset();
// calculate path's start (x,y) coords
var startX = startCoord.left + startElem.outerWidth() - svgLeft;
var startY = startCoord.top + 0.5*startElem.outerHeight() - svgTop;
// calculate path's end (x,y) coords
var endX = endCoord.left - svgLeft;
var endY = endCoord.top + 0.5*endElem.outerHeight() - svgTop;
// call function for drawing the path
drawPath(svg, path, startX, startY, endX, endY);
}
function $svgPath(id) {
return $(document.createElementNS('http://www.w3.org/2000/svg', 'path'))
.attr({
'id': id,
'stroke-width': '4px',
'fill' : 'none',
'stroke' : '#000',
'd' : 'M0 0'
})
.css('fill', 'none');
}
function $svg(id) {
return $(document.createElementNS('http://www.w3.org/2000/svg', 'svg')).attr('id', id);
}
function connectAll() {
// connect all the paths
$('#svgContainer').append($svg('svg1'));
$("#svg1").append($svgPath("path1"));
$("#svg1").append($svgPath("path2"));
connectElements($("#svg1"), $("#path1"), $("#purple"), $("#teal"));
connectElements($("#svg1"), $("#path2"), $("#purple2"), $("#teal2"));
}
$(document).ready(function() {
// reset svg each time
connectAll();
});
$(window).resize(function () {
// reset svg each time
connectAll();
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment