2016-09-18 38 views
5

Tôi muốn vẽ hai dòng mũi tên cong sử dụng SVG để kết nối hai yếu tố để cho biết họ đi qua lại, như thế này:Vẽ SVG cong dòng mũi tên từ div để div

enter image description here

Tôi đã đọc một chút về SVG nhưng tôi không hoàn toàn chắc chắn làm thế nào để tạo ra một dòng đó là dọc.

Thứ hai, nếu SVG có tọa độ, tôi có phải tìm vị trí tọa độ của các phần tử trước khi tạo bản vẽ SVG không? Nó có phải được vẽ lại nếu kích thước cửa sổ được điều chỉnh không?

+1

Nó không rõ ràng như thế nào nên cư xử này trong các tình huống khác nhau. Ở mức độ đơn giản nhất, bạn sẽ có hình ảnh mũi tên cong cơ bản bị kéo căng nếu chiều cao là động ... – Aziz

Trả lời

18

Tạo thành phần svg (vô hình) nhấn mạnh toàn bộ tài liệu. Điều này sẽ giữ cả hai mũi tên. Chèn hai phần tử svg path (các mũi tên) có tọa độ bắt đầu và kết thúc được tính dựa trên vị trí của div được kết nối và đường cong được tạo theo bất kỳ cách nào bạn muốn dựa trên các tọa độ bắt đầu và kết thúc đó.

Ví dụ bên dưới, nhấp vào "Chạy đoạn mã". Sau đó nhấp và kéo một trong các div để xem cách các mũi tên được tạo động, tức là chúng di chuyển với các div. jQuery và jQueryUI được sử dụng trong đoạn mã đơn giản để cho phép khả năng kéo dễ dàng của các div và không liên quan gì đến việc tạo và sử dụng các mũi tên.

Ví dụ này có hai mũi tên bắt đầu và kết thúc ở giữa các cạnh của div. Các chi tiết của đường cong, tất nhiên, tùy thuộc vào bạn. Các đường mũi tên được tạo bằng cách sử dụng thuộc tính d của svg path. Trong ví dụ này, "M" là tọa độ "moveTo" nơi đường dẫn sẽ bắt đầu và điểm "C" là điểm kiểm soát đầu tiên và thứ hai và tọa độ cuối cùng cho đường cong khối bezier. Bạn sẽ phải look those up để hiểu chúng là gì, nhưng chúng là cách tổng quát để tạo các đường cong mượt mà trong phần tử svg. Các đầu mũi tên được thêm bằng cách sử dụng phần tử svg <marker> mà bạn có thể đọc về here. Một tài liệu phức tạp hơn sẽ cần phải cẩn thận hơn để xác định tọa độ bắt đầu và kết thúc của các yếu tố svg path, tức là các mũi tên, nhưng ví dụ này ít nhất là cung cấp cho bạn một nơi để bắt đầu.

Câu trả lời cho câu hỏi cụ thể của bạn:

  • Nếu SVG có tọa độ, tôi phải tìm ra vị trí của các yếu tố phối hợp trước khi tạo bản vẽ SVG? Có, như tôi đã thực hiện trong mã của tôi.

  • Nó có phải được vẽ lại không nếu kích thước cửa sổ được điều chỉnh? Có lẽ có, tùy thuộc vào những gì sẽ xảy ra với các divs khi cửa sổ được thay đổi kích cỡ.

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(); 
 
    } 
 
}); 
 

 
drawConnector();
html, 
 
body { 
 
    width: 100%; 
 
    height: 100%; 
 
    padding: 0; 
 
    margin: 0; 
 
} 
 
#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; 
 
    bottom: 20px; 
 
}
<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>

+0

Câu trả lời là gì! Tôi sẽ đặt lời nhắc trên điện thoại của tôi để trao một khoản tiền thưởng –

+2

Tôi nghĩ rằng bạn đã quên trao phần thưởng. – bb010g

+0

@ dsp_099 Vâng, bạn chắc chắn đã quên thưởng một khoản tiền thưởng :) – Roman

Các vấn đề liên quan