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