2016-09-18 300 views
5

我想用SVG来连接两个元素来表示,他们来回走,这样得出两个弧形箭头线:绘制曲线SVG箭头线的div

enter image description here

我读过关于SVG,但我不完全确定如何创建垂直线。其次,如果SVG需要坐标,那么在创建SVG绘图之前,我是否必须找到元素的坐标位置?如果调整窗口大小,是否需要重新绘制?

+1

目前尚不清楚如何把这个的行为在不同的场景。在最简单的层面上,如果高度是动态的,你会得到一个基本的弯曲的箭头图像... – Aziz

回答

18

制作一个svg元素(无形地)在整个文档之下。这将持有两个箭头。插入两个svg path元素(箭头),其起始和结束坐标是根据要连接的div的位置计算出来的,并且根据这些起始和结束坐标以您想要的任何方式创建其曲线。

对于下面的例子,点击“运行代码片段”。然后点击并拖动其中一个div来查看箭头是如何动态创建的,即它们随div移动。 jQuery和jQueryUI被用在代码片段中,只是为了容易实现div的可拖动性,并且与创建和使用箭头无关。

这个例子有两个箭头开始和结束在divs边的中间。曲线的细节当然取决于你。箭头线是使用svg pathd属性构建的。在本例中,“M”是“moveTo”坐标,其中路径将开始,“C”点是三次贝塞尔曲线的第一个和第二个控制点以及最终坐标。您必须要知道look those up是什么,但它们是在svg元素中创建平滑曲线的一般方法。箭头添加使用svg <marker>元素,您可以阅读关于here

更复杂的文档需要更多的注意力来确定元素的开始和结束坐标,即箭头,但这个例子至少给你一个开始的地方。

回答您的具体问题:

  • 如果SVG需要坐标,我必须找到创建SVG绘图前的坐标元素的位置?是的,正如我在我的代码中所做的那样。

  • 如果调整窗口大小,是否需要重新绘制?也许是的,取决于窗口大小调整时divs自己会发生什么。

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

什么答案!我会在我的手机上设置一个提醒,以奖励赏金 –

+2

我想你忘了奖励赏金。 – bb010g

+0

@ dsp_099是的,你肯定忘了奖励赏金:) – Roman