SVG矩形带有圆角、虚线数组和虚线偏移量

5

我正在尝试使用半径(rx, ry)在svg中创建一个带有顶部和底部边框/描边以及圆角的矩形。 通过使用CSS属性“dasharray: width, height”,可以仅为顶部和底部设置边框/描边。但是,如果添加了半径,则顶部边框不再从矩形的左上角开始。 我尝试使用CSS属性dash-offset来纠正此行为,但似乎会使顶部边框部分消失(虽然对于底部边框似乎有效)。

如何创建带有半径和仅具有顶部和底部边框的矩形,以及发生了什么,任何帮助都将不胜感激。

请查看以下fiddle: 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;
 }

你需要为不同的圆使用不同的 stroke-dasharray 值,因为圆的周长随半径变化而变化。如果你想要它在除了 Chrome 之外的任何地方工作,你还需要将矩形的宽度/高度值和 .round rx 和 ry 值属性设置为属性,而不是 CSS 属性。 - Robert Longson
1个回答

9
为了让所有SVG渲染器呈现相同的虚线图案,SVG规范定义了所有形状的虚线图案应该从哪里开始。包括矩形
对于一个矩形来说,起点位于矩形顶部水平部分的左端。因此,如果有圆角,它就在曲线与直线相交的点上。然后,虚线图案按顺时针方向绕着矩形进行。
这个起点实际上是一个隧道或门户,虚线图案会从中出现和消失。您无法更改其位置,只需谨慎构建虚线图案并考虑该起点即可。
您没有明确说明要包含多少圆角在顶部描边中,但我假设您想包含整个曲线。
在您的示例中,矩形大小为150x150,圆角半径为20。让我们将它们称为w、h和r。
为了正确计算虚线图案,我们需要准确地计算所有边和圆角的长度。

顶部和底部的长度都是(w - 2 * r) = 110,我们称之为xlen

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

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

虚线版本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"

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

虚线模式版本2

另一个更简单但不太明显的解决方案是利用虚线模式的重复性质。结合虚线偏移量,我们可以使虚线模式变得简单。

  • 矩形顶部(包括两个角): rlen + xlen + rlen = 172.832
  • 右侧间隙的模式: ylen = 110
  • 然后重复以形成底部和左侧。

因此,虚线模式将为"172.832 110"

“等等”,你可能会说,“这不行,因为模式将被圆角的长度顺时针移动。”你是对的。

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

然而,如果我们使用 stroke-dashoffset 将图案向左/逆时针移动,我们将会失去一些第一个短划线,但我们也将通过那个起点/终点 "门户" "拉回" 下一个重复的短划线。这取决于短划线模式的确切长度。这就是为什么我们在开始时如此小心地计算所有长度的原因。

那么我们需要使用什么值作为 stroke-dashoffset? 短划偏移的工作方式是指定我们应该从哪里开始绘制图案。因此,它需要在圆角的长度之后,即 31.416

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

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

你可以看到,如果你想让你的虚线图案在正确的位置开始和停止,这是可能的。你只需要准确计算你的虚线图案中的长度。
如果你需要在其他大小的矩形上具有相同类型的图案,你需要使用我在本答案开头列出的公式重新计算长度。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接