I want to draw two curved lines with arrows, using SVG to connect two elements to show that the lines go back and forth, like this:

enter image description here

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

Secondly, if the SVG takes coordinates, do I need to find the coordinates of the elements before creating the SVG drawing?

Should the drawing be redrawn if the window is resized?

1 answer 1

Create an SVG element that underlies the entire document.

This will hold both arrows inside the SVG. Add two SVG path elements (arrows), whose starting and ending coordinates are calculated based on the positions of the connected div elements, and the shape of the curves is created the way you want based on these starting and ending coordinates.

For the example below, click Run code . Then click and drag any of the div elements to see how the arrows change dynamically, that is, they move with the div elements. jQuery and jQueryUI are used in the code snippet simply to simplify dragging 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 .
The shape of the curve, of course, depends on you.

Arrows are built using the d path SVG attribute. In this example, M is the coordinates of the moveTo from which the path will begin, and points C are the first and second control points and the final coordinates for the cubic Bezier curve.

You will have to learn the theory to understand what they are, but this is a general way of creating smooth curves in an SVG element.

Arrows are added using the SVG <marker> element, which you can read about here .

A more complex document will require more precision to determine the starting and ending coordinates of the SVG path elements, i.e. the arrows, but this example at least gives you a place to start.

Answers to your specific questions:

  • If SVG accepts coordinates, should I find the coordinate position of the elements before creating an SVG drawing? Yes, as I did in my code.
  • Should the drawing be redrawn if the window is resized? Probably, yes, depending on what happens to the div elements themselves 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: 180px; } 
 <p id="instructions">Нажмите и перетащите любой div, чтобы увидеть непроизвольную установку стрелок.</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> 

Update 01/26/2019

Error when working in full-screen mode is fixed by using the @Bharata board. Thanks for the help.

  • some sort of crap in full-screen viewing - MaximLensky
  • one
    Thank you for the translation! I like that a lot. And everything works fine without flaws! - Bharata
  • one
    @Alexandr_TT I talked about this, but you understand that I am not Russian and I have a 90% discount .. just if I put it sharply ... - MaximLensky
  • 2
    @Alexandr_TT, fix this error simply: replace #b {bottom: 20px;} with #b {top: 180px;} and everything will work correctly. - Bharata
  • 2
    @Bharata Thank you :) :) - Alexandr_TT