JSFiddle - React, Tailwind, and code Playground
HTML
<div id="svgContainer">
<svg id="svg1" width="0" height="0">
<path id="path1"/>
<path id="path2"/>
<path id="path3"/>
<path id="path4"/>
<path id="path5"/>
<path id="path6"/>
</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>
<!-- Try to resize the screen -->
<!-- the connections should hold -->
CSS
body {
font-size: 1.5vh;
}
div {
opacity: 0.7;
}
#svgContainer {
z-index: -10;
opacity: 0.5;
margin: 2.5em 2.5em;
position: absolute;
}
path {
fill: none;
stroke: #000;
stroke-width: 0.7em;
}
#path3 {
stroke-width: 0.5em;
}
#path5 {
stroke-width: 0.8em;
}
#path6 {
stroke-width: 0.8em;
}
#outer {
width: 80%;
margin: 0 auto;
}
#teal {
width: 6em;
height: 6em;
margin-left: 10%;
background-color: teal;
}
#orange {
width: 35%;
height: 4em;
padding: 2em 8em;
margin-top: 6em;
margin-left: 8em;
background-color: orange;
}
#red {
width: 6em;
height: 4em;
padding: 4em 3em;
margin-left: 30%;
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;
}
JavaScript
//helper functions, it turned out chrome doesn't support Math.sgn()
function signum(x) {
return (x < 0) ? -1 : 1;
}
function absolute(x) {
return (x < 0) ? -x : x;
}
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 style = getComputedStyle(path)
var stroke = parseFloat(style.strokeWidth);
// check if the svg is big enough to draw the path, if not, set heigh/width
if (svg.getAttribute("height") < endY) svg.setAttribute("height", endY);
if (svg.getAttribute("width") < (startX + stroke)) svg.setAttribute("width", (startX + stroke));
if (svg.getAttribute("width") < (endX + stroke)) svg.setAttribute("width", (endX + stroke));
var deltaX = (endX - startX) * 0.15;
var deltaY = (endY - startY) * 0.15;
// for further calculations which ever is the shortest distance
var delta = deltaY < absolute(deltaX) ? deltaY : absolute(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.setAttribute("d", "M" + startX + " " + startY +
" V" + (startY + delta) +
" A" + delta + " " + delta + " 0 0 " + arc1 + " " + (startX + delta * signum(deltaX)) + " " + (startY + 2 * delta) +
" H" + (endX - delta * signum(deltaX)) +
" A" + delta + " " + delta + " 0 0 " + arc2 + " " + endX + " " + (startY + 3 * delta) +
" V" + endY);
}
function connectElements(svg, path, startElem, endElem) {
var svgContainer = document.getElementById('svgContainer');
// if first element is lower than the second, swap!
if (startElem.offsetTop > endElem.offsetTop) {
var temp = startElem;
startElem =...