在SVG中为垂直线条添加feDropShadow会使其消失。

7

我有以下SVG文档:

  <svg preserveAspectRatio="xMinYMin meet" viewBox="0 0 21 484" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <filter id="dropShadow">
      <feDropShadow dx="4" dy="0" stdDeviation="4"></feDropShadow>
    </filter>
  </defs>
  <g id="Artboard" stroke-width="5" stroke="#FF0000" fill="#000000" stroke-linecap="round">
    <path style="filter: url(#dropShadow)" d="M7.5,8.5 L7.5,471.5" id="path-1"></path>
  </g>
</svg>

在Firefox中,当我打开SVG文档时,它只显示一个非常细的(不是5个单位宽)垂直线。在Chrome中,则没有任何显示(在codepen中也是如此:https://codepen.io/jwir3/pen/BJBqEK)。我不确定我做错了什么,但这与滤镜有关,因为如果我从

可能是重复问题:SVG:添加阴影滤镜使得直线不可见 - Michael Mullany
只是为了添加搜索关键字:这也影响到 feMorphology 中的 dilateerode - chris
3个回答

16

如果您的形状没有高度或宽度,则无法使用objectBoundingBox units

当适用元素的几何形状没有宽度或高度时,例如水平线或垂直线的情况(即使该线具有实际厚度,因为边框宽度在边界框计算中被忽略),不应使用关键字objectBoundingBox。当适用元素的几何形状没有宽度或高度并且指定了objectBoundingBox时,将忽略给定的效果(例如渐变或过滤器)。

filterUnits的默认值是objectBoundingBox单位,因此您需要将其更改为userSpaceOnUse,即:

<svg preserveAspectRatio="xMinYMin meet" viewBox="0 0 21 484" xmlns="http://www.w3.org/2000/svg">
  <title>Line Drop Shadow</title>
  <description>A red line with 5px width thickness and round caps, having a drop-shadow. This highlights the regression documented in PURP-1017.</description>
  <defs>
    <filter id="dropShadow" filterUnits="userSpaceOnUse">
      <feDropShadow dx="4" dy="0" stdDeviation="4"></feDropShadow>
    </filter>
  </defs>
  <g id="Artboard" stroke-width="5" stroke="#FF0000" fill="#000000" stroke-linecap="round">
    <path style="filter: url(#dropShadow)" d="M7.5,8.5 L7.5,471.5" id="path-1"></path>
  </g>
</svg>


3

在处理过滤器时,不同的浏览器以不同的方式处理描边
Chrome将描边视为一个零像素值,因此它不包括在过滤器区域内。
因此,为了使结果在不同的浏览器中看起来相同,最好用stroke-width="5"替换path,使用没有strokestroke="none")的5像素宽度的矩形。

此外,过滤器区域的默认值为:x="-10%"y="-10%"width="120%"height="120%" - 通常会截断大模糊尺寸。

默认情况下,filterUnits="objectBoundingBox",因此值是以百分比指定的。

为了更容易地计算过滤器区域的大小,可以指定filterUnits="userSpaceOnUse"的值,然后可以以像素为单位指定过滤器区域的所有尺寸。

<svg preserveAspectRatio="xMinYMin meet" width="100%" height="100%" viewBox="0 0 21 484" xmlns="http://www.w3.org/2000/svg" >
  <defs>
    <filter id="dropShadow" filterUnits = "userSpaceOnUse" x="4" y="0"  width="12" height="472">
      <feDropShadow dx="6" dy="4" stdDeviation="3"></feDropShadow>
    </filter>
  </defs>
  <g id="Artboard"  fill="#FF0000" filter="url(#dropShadow)" >
   <!-- <path style="filter: url(#dropShadow)" d="M7.5,8.5 L7.5,471.5" id="path-1" stroke-width="5" ></path>--> 
    <rect x="5" y="5" width="5" stroke="none" height="463"  /> 
  </g>
</svg>


0

在大多数情况下,切换到userSpaceOnUse是正确的答案,但具有以下限制:

  1. 滤镜效果区域将应用于画布的-10%至120%,而不是元素的边界框(使用更多内存和处理时间)
  2. 对于大型动态SVG(例如由d3创建),很难计算所需的过滤器x / y / width / height以确保过滤器适用于所有元素。

另一种替代方案(不太优雅)是将过滤器应用于<g>,并在其中使用一个隐藏节点来为该组提供正确的宽度或高度:

  <svg xmlns="http://www.w3.org/2000/svg">
  <defs>
    <filter id="dropShadow" width="20">
      <feDropShadow dx="4" dy="0" stdDeviation="4"></feDropShadow>
    </filter>
  </defs>
  <g id="Artboard" style="filter: url(#dropShadow)">
    <circle r="5" cx="0" cy="0" visibility="hidden"></circle>
    <path d="M10,10 L10,100" stroke-width="5" stroke="#FF0000" fill="#000000" stroke-linecap="round"></path>
  </g>
</svg>


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