Create an svg element that (invisibly) underlies the entire document. This will hold both arrows. Insert two path svg elements (arrows) whose start and end coordinates are calculated based on the positions of the connected div element, and whose curve is created in any way based on these start and end coordinates.
For the example below, click "Run Code Snippet". Then click and drag any div element to see how the arrows are created dynamically, i.e. they move along with div elements. jQuery and jQueryUI are used in the code snippet just to simplify the drag and drop of div elements and have nothing to do with creating and using arrows.
In this example, the two arrows begin and end in the middle of the sides of the div element. The details of the curve, of course, are up to you. Arrows are constructed using the d path svg attribute. In this example, βMβ is the βmoveToβ coordinates from which the path starts, and βCβ points are the first and second control points and the final coordinate for the cubic Bezier curve. You will have to look at them to understand what they are, but this is a common way to create smooth curves in the svg element. Arrows are added using the svg <marker> element which you can read here .
A more complex document will require more attention to determine the start and end coordinates of path svg elements, i.e. the arrow, but this example at least gives you a place to start.
Answers to your specific questions:
If the SVG takes the coordinates, should I find the coordinate position of the elements before creating the SVG drawing? Yes, as I did in my code.
Should it be redrawn if the window size is adjusted? Probably yes, depending on what happens to the div itself when the window is resized.
var divA = document.querySelector("#a"); var divB = document.querySelector("#b"); var arrowLeft = document.querySelector("#arrowLeft"); var arrowRight = document.querySelector("#arrowRight"); var drawConnector = function() { var posnALeft = { x: divA.offsetLeft - 8, y: divA.offsetTop + divA.offsetHeight / 2 }; var posnARight = { x: divA.offsetLeft + divA.offsetWidth + 8, y: divA.offsetTop + divA.offsetHeight / 2 }; var posnBLeft = { x: divB.offsetLeft - 8, y: divB.offsetTop + divA.offsetHeight / 2 }; var posnBRight = { x: divB.offsetLeft + divB.offsetWidth + 8, y: divB.offsetTop + divA.offsetHeight / 2 }; var dStrLeft = "M" + (posnALeft.x ) + "," + (posnALeft.y) + " " + "C" + (posnALeft.x - 100) + "," + (posnALeft.y) + " " + (posnBLeft.x - 100) + "," + (posnBLeft.y) + " " + (posnBLeft.x ) + "," + (posnBLeft.y); arrowLeft.setAttribute("d", dStrLeft); var dStrRight = "M" + (posnBRight.x ) + "," + (posnBRight.y) + " " + "C" + (posnBRight.x + 100) + "," + (posnBRight.y) + " " + (posnARight.x + 100) + "," + (posnARight.y) + " " + (posnARight.x ) + "," + (posnARight.y); arrowRight.setAttribute("d", dStrRight); }; $("#a, #b").draggable({ drag: function(event, ui) { drawConnector(); } }); setTimeout(drawConnector, 250);
html, body { width: 100%; height: 100%; padding: 0; margin: 0; } #instructions { position: fixed; left: 50%; } #a, #b { color: white; text-align: center; padding: 10px; position: fixed; width: 100px; height: 20px; left: 100px; } #a { background-color: blue; top: 20px; } #b { background-color: red; top: 150px; }
<p id="instructions">Click and drag either div to see automatic arrow adjustments.</p> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.0/jquery-ui.min.js"></script> <svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%"> <defs> <marker id="arrowhead" viewBox="0 0 10 10" refX="3" refY="5" markerWidth="6" markerHeight="6" orient="auto"> <path d="M 0 0 L 10 5 L 0 10 z" /> </marker> </defs> <g fill="none" stroke="black" stroke-width="2" marker-end="url(#arrowhead)"> <path id="arrowLeft"/> <path id="arrowRight"/> </g> </svg> <div id="a">Div 1</div> <div id="b">Div 2</div>
source share