5

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

但是,添加半径后,顶部边框不再从矩形的左上角开始。我试图通过使用 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;
 }
4

1 回答 1

8

为了使虚线图案在所有 SVG 渲染器中呈现相同的效果,SVG 规范定义了所有形状的虚线图案应从何处开始。包括矩形

对于矩形,起点位于矩形顶边水平部分的左端。所以如果有一个圆角,它是在曲线与直线相交的点。然后,虚线图案以顺时针方向围绕矩形进行。

该起点实际上是一个隧道或入口,破折号图案通过该隧道或入口出现和消失。你不能改变它的位置,你只需要仔细考虑这个起点来构建你的破折号图案。

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

在您的示例中,矩形为 150x150,角半径为 20。我们称它们为 w、h 和 r。

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

顶部和底部都是 length (w - 2 * r) = 110。让我们称之为xlen

左右两边都是长度(w - 2 * r) = 110。让我们称之为ylen.

每个圆角都是 length (PI * 2 * r) / 4 = 31.416。让我们称之为rlen

破折号模式版本 1

我们可以从完成矩形圆周所需的不同长度的图案中制作破折号图案。IE。

  • 矩形的顶部(不包括左角):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向左/逆时针移动模式,我们将丢失一些第一个破折号,但我们还将通过该开始/结束“门户”“拉”回一些破折号图案的下一次重复。这依赖于短划线图案是正确的长度。这就是为什么我们在开始时如此小心地准确计算所有长度的原因。

Spo 我们需要使用的价值是什么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>

您可以看到,如果您希望破折号图案在正确的位置开始和停止,这是可能的。您只需要准确计算破折号图案中的长度即可。

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

于 2017-01-05T06:16:44.110 回答