2017-01-22 46 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>

当然,这只是给你一个方法来显示一条线,是一个特定%来自两端,没有一个确切的像素值。希望这给你一些想法。

请注意,这是一个有点儿车 - 它不适用于水平或垂直线...你必须呈现为矩形或路径,并使用填充,而不是中风。