Drawing curved lines of SVG arrows from div to div

I want to draw two curved arrow lines using SVG to connect two elements to indicate that they are going back and forth, for example:

enter image description here

I read a little about SVG, but I'm not quite sure how to create a vertical line.

Secondly, if the SVG takes the coordinates, do I need to find the coordinate position of the elements before creating the SVG drawing? Do I need to redraw it if the window size is adjusted?

+8
source share
2 answers

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); /* The setTimeout delay here is only required to prevent * the initial appearance of the arrows from being * incorrect due to the animated expansion of the * Stack Overflow code snippet results after clicking * "Run Code Snippet." If this was a simpler website, * a simple command, ie 'drawConnector();' would suffice. */ 
 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> 
+40
source

I found Andrew Willems answer very helpful. I changed it to make the draw_arrow.js library that exports the draw_arrow( sel1, locs1, sel2, locs2, arr ) function draw_arrow( sel1, locs1, sel2, locs2, arr ) . This draws an arrow from the element identified by the CSS selector sel1 to sel1 identified by sel2 . locs1 and locs2 indicate where the arrow should begin or end on the element. arr defines the SVG path to hold the arrow.

You can download this and see two demos from the links at the end of http://www.chromophilia.uk/blog/dress-reform-architecture-and-modernism/ . I need arrows to depict the relationship between the various topics related to modernism, as part of the animation. This is what made me find and adapt the Andrew code.

An improvement is proposed here. Initially, I wrote this as a new, additional answer, but several commentators completed it, so I will have to put it here and hope that they will notice it. I pursue this because modularity is important. A routine such as draw_arrow should require its user to do as little as possible with the code around it. But at the moment the user needs to create one <path> element inside the <svg> for each arrow drawn and come up with identifiers for the paths. I suggest that it is better to do draw_arrow by updating the DOM tree. Comments for or against?

+2
source

All Articles