如何使用 svg 过滤器应用渐变

Posted

技术标签:

【中文标题】如何使用 svg 过滤器应用渐变【英文标题】:How to apply gradient using svg filter 【发布时间】:2017-04-02 20:03:59 【问题描述】:

我想创建一个过滤器,当应用于 html 元素时,会为整个元素应用渐变。 css渐变只适用于背景,所以不是我想要的。 我想要说我的元素包含一个三角形和一个圆形,我想对我的元素应用一个过滤器,三角形和圆形将应用渐变。

这是我目前得到的:

.my-element
    filter: url(svg.svg#filter);
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
      <defs>
        <linearGradient id="lightGradient" gradientTransform="rotate(-5)">
            <stop stop-color="white" stop-opacity="0.4" offset="0%"/>
            <stop stop-color="white" stop-opacity="0.5" offset="5%"/>
            <stop stop-color="black" stop-opacity="0.2" offset="6%"/>
            <stop stop-color="black" stop-opacity="0.3" offset="19%"/>
            <stop stop-color="black" stop-opacity="0.2" offset="12%"/>
            <stop stop-color="white" stop-opacity="0.8" offset="13%"/>
            <stop stop-color="white" stop-opacity="0.9" offset="15%"/>
            <stop stop-color="white" stop-opacity="0" offset="15%"/>
            <stop stop-color="white" stop-opacity="0" offset="16%"/>
            <stop stop-color="white" stop-opacity="0.8" offset="16%"/>
            <stop stop-color="white" stop-opacity="0.9" offset="18%"/>
            <stop stop-color="white" stop-opacity="0" offset="18%"/>
            <stop stop-color="white" stop-opacity="0" offset="20%"/>
            <stop stop-color="white" stop-opacity="1" offset="20%"/>
            <stop stop-color="white" stop-opacity="1" offset="25%"/>
        </linearGradient>

        <rect id="recGradient" x="0" y="0"   fill="url(#lightGradient)"/>

        <filter id="filter" primitiveUnits="objectBoundingBox">
            <feImage x="0" y="0"   preserveAspectRatio="none" xlink:href="#recGradient"/>

            <feComposite operator="in" in="SourceGraphic"/>
        </filter>
      </defs>
    </svg>

编辑:使用上面的代码,该元素在 Firefox 中变得不可见,在 chrome 中它似乎可以工作。

所以,显然我做错了。我不知道如何创建 svg 过滤器,因此我们将不胜感激。

【问题讨论】:

尝试使用渐变创建一个矩形,然后将一个 feImage 滤镜指向该矩形。 @robert 嗨,你能给我看一个示例代码吗?我尝试添加&lt;feImage xlink:href="#recGradient"/&gt;,但它给出了解析错误:前缀未绑定到命名空间 @RobertLongson 好的,我添加了 xmlns:xlink="w3.org/1999/xlink",现在它解析了,但我没有得到我想要的结果。我将编辑帖子以显示我所做的。 矩形元素应该在过滤器之外。 @RobertLongson 好的,我把它放在&lt;filter&gt; 之外,但它仍然是不可见的。 【参考方案1】:

这就是您构建跨浏览器过滤器的方式,该过滤器可以在此处执行您想要的操作。尺寸调整很棘手,因为您要在 DataURI 中定义一个具有应用渐变的矩形,然后使用 feImage 将其拉入过滤器,然后使用 CSS 过滤器中的 SVG 过滤器陷门将其应用于 HTML 内容。但它确实有效。

(顺便说一句 - 目前尚不清楚您是要保留原始文本的颜色并仅应用不透明度渐变,还是希望黑/白渐变覆盖原始颜色。您可以通过更改来切换它feComposite 中的“in2”到“in”。这决定了您是否将源图形的不透明度应用于渐变,反之亦然。)

div 
  filter: url(#myGradient);
<svg>
  <defs>
<filter id="myGradient" primitiveUnits="objectBoundingBox">
       <feImage x="0%" y="0%"   preserveAspectRatio="none" xlink:href="data:image/svg+xml;charset=utf8,%3Csvg%20width%3D%22200px%22%20height%3D%22200px%22%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20xmlns%3Axlink%3D'http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink'%3E%3Cdefs%3E%3ClinearGradient%20id%3D'lightGradient'%20gradientTransform%3D'rotate(-5)'%3E%3Cstop%20stop-color%3D'white'%20stop-opacity%3D'0.4'%20offset%3D'0%25'%2F%3E%3Cstop%20stop-color%3D'white'%20stop-opacity%3D'0.5'%20offset%3D'5%25'%2F%3E%3Cstop%20stop-color%3D'black'%20stop-opacity%3D'0.2'%20offset%3D'6%25'%2F%3E%3Cstop%20stop-color%3D'black'%20stop-opacity%3D'0.3'%20offset%3D'19%25'%2F%3E%3Cstop%20stop-color%3D'black'%20stop-opacity%3D'0.2'%20offset%3D'12%25'%2F%3E%3Cstop%20stop-color%3D'white'%20stop-opacity%3D'0.8'%20offset%3D'13%25'%2F%3E%3Cstop%20stop-color%3D'white'%20stop-opacity%3D'0.9'%20offset%3D'15%25'%2F%3E%3Cstop%20stop-color%3D'white'%20stop-opacity%3D'0'%20offset%3D'15%25'%2F%3E%3Cstop%20stop-color%3D'white'%20stop-opacity%3D'0'%20offset%3D'16%25'%2F%3E%3Cstop%20stop-color%3D'white'%20stop-opacity%3D'0.8'%20offset%3D'16%25'%2F%3E%3Cstop%20stop-color%3D'white'%20stop-opacity%3D'0.9'%20offset%3D'18%25'%2F%3E%3Cstop%20stop-color%3D'white'%20stop-opacity%3D'0'%20offset%3D'18%25'%2F%3E%3Cstop%20stop-color%3D'white'%20stop-opacity%3D'0'%20offset%3D'20%25'%2F%3E%3Cstop%20stop-color%3D'white'%20stop-opacity%3D'1'%20offset%3D'20%25'%2F%3E%3Cstop%20stop-color%3D'white'%20stop-opacity%3D'1'%20offset%3D'25%25'%2F%3E%3C%2FlinearGradient%3E%3C%2Fdefs%3E%0A%20%20%3Crect%20id%3D'recGradient'%20x%3D'0%25'%20y%3D'0%25'%20width%3D'100%25'%20height%3D'100%25'%20fill%3D'url(%23lightGradient)'%2F%3E%3C%2Fsvg%3E"/>
  <feComposite operator="in" in2="SourceGraphic"/>
 </filter>
  </defs>
</svg>




<div>
  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text   Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text    Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text    Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text    Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text    Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text    Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text  Imagine a very large piece of text   
</div>

【讨论】:

您好,我用的是firefox,运行代码sn-p时什么都看不到... 呃。我的数据 URI 出了点问题,让我调试一下 抱歉——firefox 想要 URL 编码 UTF-8——应该知道这一点。更新的示例 - 现在可以使用。 谢谢。这是工作。但似乎这个过滤器改变了文本的颜色和不透明度?我希望文本相同,只需在文本顶部绘制渐变。因此,不透明度为 40% 的红色只是上面涂有 40% 不透明度红色的纯色文本。也许我应该使用 operator="arithmetic"?我完全一无所知,很抱歉给您带来麻烦。 只需更改为 operator="over"。 (但不要批评,但这似乎是对过滤器的不好使用。为什么不直接使用定位、z-index 和 CSS 渐变填充在其他元素之上绘制一个带有渐变的形状?)

以上是关于如何使用 svg 过滤器应用渐变的主要内容,如果未能解决你的问题,请参考以下文章

如何给SVG填充和描边应用线性渐变

如何给SVG填充和描边应用线性渐变

如何给SVG填充和描边应用径向渐变

如何使用 SVG 过滤器将白色图像反转为黑色?

SVG渐变

如何减少此动画 SVG 渐变产生的延迟?