2017-01-22 47 views
1

是否有人想知道是否可以在點之間畫一條線,同時與SVG的終點保持一定的距離?如何在SVG中繪製一部分線條?

如果行是水平的(例如,從(40,40)(100,40)),則可以很容易地得出,保持約20的距離的點如下

<line x1="40" y1="40" x2="100" y2="40" desc="directional line" /> 
<line x1="60" y1="40" x2="80" y2="40" desc="actual part of line" /> 

對於對角線的線,但是,它有點困難。要借鑑(40,40)的(容易)對角線,(100,100),你需要cos(pi/4) = sin(pi/4) = sqrt(2)規模要從終點望而卻步的距離(在這種情況下:20*sqrt(2) = 14.1

<line x1="40" y1="40" x2="100" y2="100" desc="directional line" /> 
<line x1="54.1" y1="54.1" x2="85.9" y2="85.9" desc="actual part of line" /> 

這段代碼的演示可以在此fiddle

中找到它因此似乎能夠做到這一點,計算

  1. 與水平線方向線之間的角度時
  2. 角度的正弦和餘弦
  3. 要繪製

行的實際部分的結束點這是唯一的途徑或能夠確定線的部分SVG還是有更聰明,這樣做更方便嗎?

回答

1

我不確定這是否聰明或方便,但沒有腳本這樣做的一種方法是以下。

您可以使用rect作爲標記(marker-start和marker-end),並將markerWidth和markerHeight屬性與行的筆觸寬度結合使用,您可以控制標記的大小。

markerWidth * stroke-width = real width 

<svg width="220" height="220"> 
 
    <marker id="m1" orient="auto" viewBox="0 0 20 6" markerWidth="10" markerHeight="3" refX="20" refY="3"> 
 
    <rect x="0" y="0" width="20" height="6" fill="red" opacity="0.5" /> 
 
    </marker> 
 
    <marker id="m2" orient="auto" viewBox="0 0 20 6" markerWidth="10" markerHeight="3" refX="0" refY="3"> 
 
    <rect x="0" y="0" width="20" height="6" fill="red" opacity="0.5" /> 
 
    </marker> 
 

 
    <line id="l2" x1="20" y1="20" x2="200" y2="80" marker-end="url(#m1)" marker-start="url(#m2)" stroke="black" stroke-width="2" /> 
 

 
</svg>

現在想象我們使用白色矩形,則該標記將重疊有固定寬度的線,並且我們將不得不端點的固定距離。

但這並不是我們想要的。要真正用標記「剪切」線條,可以使用一個蒙版。所以把你的線畫成一個面具,用白色筆畫,但用黑色標記。

將此遮罩應用於您的線條(不帶標記)......您去了:一條具有與端點具有固定距離的可見筆畫的線條。

優點:不需要JavaScript參與

缺點:你必須提請你行兩次

function redraw() { 
 
    var x1 = Math.random() * 200 
 
    var y1 = Math.random() * 200 
 
    var x2 = Math.random() * 200 
 
    var y2 = Math.random() * 200 
 

 
    l1.setAttribute("x1", x1) 
 
    l1.setAttribute("y1", y1) 
 
    l1.setAttribute("x2", x2) 
 
    l1.setAttribute("y2", y2) 
 

 
    l2.setAttribute("x1", x1) 
 
    l2.setAttribute("y1", y1) 
 
    l2.setAttribute("x2", x2) 
 
    l2.setAttribute("y2", y2) 
 

 
    c1.setAttribute("cx", x1) 
 
    c1.setAttribute("cy", y1) 
 
    c2.setAttribute("cx", x2) 
 
    c2.setAttribute("cy", y2) 
 
}
line { 
 
    stroke-width: 2px 
 
}
<svg width="220" height="220"> 
 
    <marker id="m1" orient="auto" viewBox="0 0 20 6" markerWidth="10" markerHeight="3" refX="20" refY="3"> 
 
    <rect x="0" y="0" width="20" height="6" fill="black" /> 
 
    </marker> 
 
    <marker id="m2" orient="auto" viewBox="0 0 20 6" markerWidth="10" markerHeight="3" refX="0" refY="3"> 
 
    <rect x="0" y="0" width="20" height="6" fill="black" /> 
 
    </marker> 
 
    <mask id="mask"> 
 
    <line id="l2" x1="20" y1="20" x2="200" y2="80" marker-end="url(#m1)" marker-start="url(#m2)" stroke="white" /> 
 
    </mask> 
 
    <circle id="c1" cx="200" cy="80" r="5" fill="blue" /> 
 
    <circle id="c2" cx="20" cy="20" r="5" fill="blue" /> 
 
    <line id="l1" x1="20" y1="20" x2="200" y2="80" mask="url(#mask)" stroke="black" /> 
 
</svg> 
 

 
<button onclick="redraw()">redraw</button>

0

一旦哈克的方式做到這一點與縮放到一個圓形圖案作弊你的線的大小。並不完美,但取決於你的使用情況:

<svg width="200" height="200" viewbox="0 0 200 200"> 
 
    <defs> 
 
    <pattern id="patt" width="1" height="1" patternContentUnits="objectBoundingBox"> 
 
     <rect x="0" y="0" width="1" height="1" fill="cyan" /> 
 
     <circle cx=".5" cy=".5" r=".4" fill="blue" /> 
 
    </pattern> 
 
    </defs> 
 
    
 
    <g id="hand-drawn"> 
 
    <line x1="40" y1="40" x2="100" y2="100" stroke="red" stroke-width="2" /> 
 
    <line x1="54.1" y1="54.1" x2="85.9" y2="85.9" stroke="green" stroke-width="2" /> 
 
    </g> 
 
    
 
    <g id="circle-pattern"> 
 
    <line x1="80" y1="60" x2="200" y2="100" stroke="url(#patt)" stroke-width="2" /> 
 
    <line x1="150" y1="10" x2="100" y2="120" stroke="url(#patt)" stroke-width="2" /> 
 
    <line x1="0" y1="100" x2="150" y2="100" stroke="url(#patt)" stroke-width="2" /> 
 
    <line x1="0" y1="100" x2="150" y2="101" stroke="url(#patt)" stroke-width="2" /> 
 
    <g> 
 
</svg>

當然,這只是給你一個方法來顯示一條線,是一個特定%來自兩端,沒有一個確切的像素值。希望這給你一些想法。

請注意,這是一個有點兒車 - 它不適用於水平或垂直線...你必須呈現爲矩形或路徑,並使用填充,而不是中風。