首页 文章

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

提问于
浏览
1

我试图在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;
 }

1 回答

  • 2

    为了使破折号模式在所有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

    我们可以根据完成矩形圆周所需的不同长度的图案来制作破折号图案 . 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>
    

    Dash pattern version 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 来向左/逆时针移动模式,我们将丢失一些第一个短划线,但我们也将在该开始/结束"portal"之后的一些下一个短划线模式重复 . 这依赖于破折号模式是完全正确的长度 . 这就是我们开始时非常小心准确计算所有长度的原因 .

    Spo我们需要为 stroke-dashoffset 使用什么 Value ?破折号偏移的工作方式是它指定我们应该开始绘制的模式的距离 . 所以它需要在圆角的长度之后,或 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>
    

    您可以看到,如果您希望您的仪表板模式在正确的位置开始和停止,则可以 . 您只需准确计算短划线图案中的长度即可 .

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

相关问题