SVG路径带有边框

15

如何创建填充和轮廓类似于enter image description here的路径?

目前我找到了几种方法,但没有一种特别简洁的。

其中一种方法是使用paint-order,但这在移动端和IE中不起作用。

另一种方法是复制路径,但这会创建大量不必要的数据。

是否有一种不同的方式使用CSS简单地为SVG路径创建轮廓或边框?

<svg height="50" width="300">
    <path d="M5 20 1215 20" />
</svg>

path {
  fill: red;
  stroke: #646464;
  stroke-width:10px;
  stroke-linejoin: round;
}

这里是一个CodePen示例


2
我不知道你所说的“复制路径”是否是这个意思,但为什么不只是将线从起点到终点作为单一路径进行跟踪,然后使用stroke呢? - Harry
这就是我尝试做的,但路径总是被完全填充了...我会创建一个fiddle。 - Astronaut
1个回答

15

你需要将路径绘制为轮廓,如下所示:

<svg xmlns="http://www.w3.org/2000/svg" width="220" height="220" viewBox="0 0 220 220">
    <path fill="#ddd" stroke="#3f4141" d="M0 0h220v220H0z"/>
    <path fill="#fff" stroke="#00b400" stroke-width="4" 
     d="M 159.8 30.3
        h -110
        v 120
        h-20
        l 30 40 
          30 -40
        h-20
        v-100
        h90"/>
</svg>

在Inkscape中草绘,使用SVGOMG进行了优化,然后手动调整。

编辑

我有一个使用标记的工作解决方案,如下所示:

  • 创建线条(任何线条)作为符号
  • 通过叠加两个线条实例来创建仿 - 笔画,具有不同的线宽
  • 添加预定义笔画箭头作为标记
  • 始端处有时会透出发际线... 使用另一个使用背景颜色进行蒙版的标记来解决此问题。
    • 这种技术只适用于纯色背景。

<svg style="display: inline-block; margin-left: 2em;" width="220" height="220" viewBox="0 0 220 220" xmlns:xlink="http://www.w3.org/1999/xlink">
  <defs>
    <style>
      .arrow-stroke {
        stroke: #00b400;
        stroke-width: 28;
        /* marker-end etc should be supported but unsure of browser support */
      }
      .arrow-fill {
        stroke: white;
        stroke-width: 20
      }
    </style>
    <marker id="arrow" markerWidth="45" markerHeight="70" refX="5" refY="35" orient="auto" markerUnits="userSpaceOnUse">
      <path fill="#fff" stroke="#00b400" stroke-width="4" d="M 2 25  v-20  l 40,30 -40,30 v-20"/>
    </marker>

    <!-- Used to hide hairline that shows through, fill color must match background color -->
    <marker id="startMask" markerWidth="2" markerHeight="30" refX="1" refY="15" orient="auto" markerUnits="userSpaceOnUse">
      <path fill="#ddd" d="M0 0 v30 h2 v-30 z" />
    </marker>
    
    <symbol id="line">
      <path d="M 159.8 30.3  h -110 v 120"/>
    </symbol>

    <symbol id="line2">
      <path d="M 140 60 l 20 30"/>
    </symbol>
    <symbol id="line3">
      <path d="M 100 80 q 0 40 20 70"/>
    </symbol>
  </defs>
  
  <path id="grey-box" fill="#ddd" stroke="#3f4141" d="M0 0h220v220H0z"/>
  
  <g fill="none">
    <use xlink:href="#line" class="arrow-stroke" />
    <use xlink:href="#line" class="arrow-fill" marker-end="url(#arrow)" marker-start="url(#startMask)" />
  
    <use xlink:href="#line2" class="arrow-stroke" />
    <use xlink:href="#line2" class="arrow-fill" marker-end="url(#arrow)" marker-start="url(#startMask)" />
  
    <use xlink:href="#line3" class="arrow-stroke" />
    <use xlink:href="#line3" class="arrow-fill" marker-end="url(#arrow)" marker-start="url(#startMask)" />
  </g>
</svg>

希望这可以帮到你。


为避免路径被完全关闭,请勿在末尾加上 z。为避免填充,请设置 fill="transparent" - Ruskin
嗨Ruskin,感谢您的回复,但那不是我想要的。我想要样式化路径而不是画一个箭头形状的路径。现在我已经通过将图案应用于路径来实现了这一点。例如:http://resources.jointjs.com/tutorial/links-patterns - Astronaut
1
啊...在这种情况下,请查看https://developer.mozilla.org/en/docs/Web/SVG/Element/marker...我会尝试更新答案。 - Ruskin
2
为了避免填充,请使用fill="none"而不是fill="transparent",fill="none"速度更快。 - Robert Longson
相关 - 我对这个SO问题的回答 https://stackoverflow.com/a/68355699/581414 使用了滤镜来创建边框。请谨慎使用,因为它会消耗更多的处理器资源。 - undefined
类似的讨论选项(虽然没有完美的解决方案)可以在https://css-tricks.com/how-to-add-a-double-border-to-svg-shapes/找到。 - undefined

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