JSFiddle - React, Tailwind, and code Playground
by Alexandru Gatea
HTML
<div class="form-container" id="form">
<div id="test1"> <span class="anchor anchor-right"></span></div>
<div id="test2"> <span class="anchor anchor-right"></span></div>
<div id="test3"> <span class="anchor anchor-right"></span></div>
<div id="test4"> <span class="anchor anchor-right"></span></div>
<div id="test5"> <span class="anchor anchor-right"></span></div>
<div id="test6"> <span class="anchor anchor-left"></span></div>
</div>
SCSS
.form-container {
display: grid;
grid-template-columns: 250px 100px;
grid-row-gap: 10px;
grid-column-gap: 150px;
grid-template-areas:
"test1 test6"
"test2 test6"
"test3 test6"
"test4 test6"
"test5 test6";
width: 500px;
align-items: center;
div {
width: 100%;
padding: 2rem;
box-shadow: inset 0 0 0 2px #ccc;
background: #fff;
position: relative;
z-index: 1;
border-radius: 100px;
.anchor {
display: block;
width: 25px;
height: 25px;
border-radius: 25px;
top: 50%;
background: transparent;
position: absolute;
&.anchor-right {
right: 0;
transform: translate(50%, -50%);
}
&.anchor-left {
left: 0;
transform: translate(-50%, -50%);
}
}
}
}
svg path {
stroke-width: 2px;
stroke: #ccc;
fill: transparent;
}
#test1 {
grid-area: test1
}
#test2 {
grid-area: test2
}
#test3 {
grid-area: test3
}
#test4 {
grid-area: test4
}
#test5 {
grid-area: test5
}
#test6 {
grid-area: test6;
}
JavaScript
let test1 = document.querySelector("#test1 .anchor");
let test2 = document.querySelector("#test2 .anchor");
let test3 = document.querySelector("#test3 .anchor");
let test4 = document.querySelector("#test4 .anchor");
let test5 = document.querySelector("#test5 .anchor");
let test6 = document.querySelector("#test6 .anchor");
const formContainer = document.getElementById("form");
const gap = parseInt(window
.getComputedStyle(formContainer)
.getPropertyValue("grid-column-gap")
);
const gapControlOffset = 3.5;
createCurve(test1, test6);
createCurve(test2, test6);
createCurve(test3, test6);
createCurve(test4, test6);
createCurve(test5, test6);
function createCurve(startElement, endElement) {
// Get the positions of the start and end elements
const startRect = startElement.getBoundingClientRect();
const endRect = endElement.getBoundingClientRect();
// Calculate the control points for the Bezier curve
const startX = startRect.left + startRect.width / 2;
const startY = startRect.top + startRect.height / 2;
const endX = endRect.left + endRect.width / 2;
const endY = endRect.top + endRect.height / 2;
const control1X = startX + gap / gapControlOffset;
const control1Y = startY;
const control2X = endX - gap / gapControlOffset;
const control2Y = endY;
// Create the SVG path element
const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
path.setAttribute("d", `M${startX},${startY} C${control1X},${control1Y} ${control2X},${control2Y} ${endX},${endY}`);
// Add the path to the SVG element on the DOM
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
svg.setAttribute("width", "100%");
svg.setAttribute("height", "100%");
svg.style.position = "absolute";
svg.style.top = "0";
svg.style.left = "0";
svg.appendChild(path);
formContainer.appendChild(svg);
}