具有radius,dash-array和dash-offset的svg矩形

时间:2017-01-04 22:03:47

标签: svg rectangles cornerradius stroke-dasharray

我试图在svg中创建一个矩形,在顶部和底部使用边框/笔划,并使用半径(rx,ry)使用圆角。 通过使用css属性" dasharray:宽度,高度"可以仅使用边框/笔划来设置顶部和底部的样式。没有半径,这可以按预期工作。

但是,添加半径时,顶部边框不再在矩形的左上角开始。 我试图通过使用css属性dash-offset来纠正这种行为,但这似乎使顶部边框部分消失(虽然它似乎适用于底部边框)。

有关如何创建一个半径且只有顶部和底部边框的矩形的任何帮助都非常感谢,以及对正在发生的事情的一些了解。

https://jsfiddle.net/Lus8ku7p/

看到小提琴
<svg>
  <rect x =10 y=10 id=a ></rect>
  <rect x = 10 y=170 id=b class=round></rect>
  <rect x=170 y=10 id=c ></rect>
  <rect x=170 y=170 id=d class=round></rect>
</svg>
svg{
    width:400px;
    height:400px
}
rect {
   width: 150px;
   height: 150px;
   stroke-width:4px;
   stroke:black;
   fill:red;
   stroke-dasharray: 150 150;
}
.round{
   rx:20px;
   ry:20px;
 }
#c, #d{
   stroke-dashoffset: 40px;
 }

1 个答案:

答案 0 :(得分:3)

为了使破折号模式在所有SVG渲染器中呈现相同,SVG规范定义了所有形状的破折号模式的开始位置。 Including rectangles

对于矩形,起点位于矩形顶部水平部分的左端。因此,如果存在圆角,则曲线与直线相交。然后,破折号图案以顺时针方向围绕矩形进行。

这个起点实际上是一个隧道或门户,破折号模式通过它出现并消失。你不能改变它的位置,你只需要仔细构建你的破折号模式,并考虑到这个起点。

你不会说出你想要在顶部笔划中包含多少圆角,但我假设你想要包含整个曲线。

在你的例子中,矩形为150x150,角半径为20.让我们称之为w,h和r。

要正确计算破折号图案,我们需要准确计算出所有边和圆角的长度。

顶部和底部各自为(w - 2 * r) = 110长度。让我们称之为xlen

左侧和右侧的长度为(w - 2 * r) = 110。我们称之为ylen

每个圆角的长度为(PI * 2 * r) / 4 = 31.416。我们称之为rlen

Dash pattern version 1

我们可以根据完成矩形圆周所需的不同长度的图案来制作破折号图案。即

  • 矩形的顶部(不包括左角):xlen + rlen = 141.416
  • 模式中的右侧差距:ylen = 110
  • 底边(包括两个角:rlen + xlen + rlen = 172.832
  • 模式中的左侧间隙:ylen = 110
  • 左上角:rlen = 31.416

因此,短划线模式为"141.416 110 172.832 110 31.416"

&#13;
&#13;
rect {
  stroke-width: 4px;
  stroke: black;
  fill:red;
  stroke-dasharray: 141.416 110 172.832 110 31.416;
}
&#13;
<svg width="400" height="400">
  <rect x="10" y="10" width="150" height="150" rx="20"/>
</svg>
&#13;
&#13;
&#13;

Dash pattern version 2

另一个更简单但不太明显的解决方案可能是利用破折号模式重复的事实。将它与短划线偏移相结合,我们可以使短划线模式更加简单。

  • rect的顶部(包括两个角):rlen + xlen + rlen = 172.832
  • 模式中的右侧差距:ylen = 110
  • 然后让它重复形成左下角。

因此,短划线模式为"172.832 110"

&#34;但等等&#34;你可能会说,因为模式将顺时针移动一个圆角的长度,所以不会发生错误。你是对的。

&#13;
&#13;
rect {
  stroke-width: 4px;
  stroke: black;
  fill:red;
  stroke-dasharray: 172.832 110;
}
&#13;
<svg width="400" height="400">
  <rect x="10" y="10" width="150" height="150" rx="20"/>
</svg>
&#13;
&#13;
&#13;

但是,如果我们使用stroke-dashoffset向左/逆时针方向移动模式,我们将丢失一些第一个短划线,但我们也会&#34;拉动&#34;一些下一个重复的破折号模式通过开始/结束&#34; portal&#34;。这依赖于破折号模式是完全正确的长度。这就是我们在开始时如此小心地准确计算所有长度的原因。

Spo我们需要为stroke-dashoffset使用什么值?虚线偏移的工作方式是它指定我们应该开始绘制的模式的距离。所以它需要在圆角的长度之后,或31.416

因此,如果我们添加,我们得到:

&#13;
&#13;
rect {
  stroke-width: 4px;
  stroke: black;
  fill:red;
  stroke-dasharray: 172.832 110;
  stroke-dashoffset: 31.416;
}
&#13;
<svg width="400" height="400">
  <rect x="10" y="10" width="150" height="150" rx="20"/>
</svg>
&#13;
&#13;
&#13;

您可以看到,如果您希望破折号模式在正确的位置开始和停止,则可以。您只需要准确计算短划线图案中的长度。

如果您需要在其他尺寸的矩形上使用相同类型的图案,则需要使用我在此答案开头列出的公式重新计算长度。