38.SVG滤镜

SVG滤镜用于为你的SVG图像添加漂亮的效果,例如投影、模糊或高亮。

滤镜示例

下面是一个简单的SVG滤镜示例,展示了两个椭圆,左边的椭圆没有滤镜,而右侧的椭圆使用高斯模糊滤镜渲染:

<defs>
    <filter id="blurFilter" y="-5" height="40"
        <feGaussianBlur in="SourceGraphic" stdDeviation="3" y="-"/>
    </filter>
</defs>

<ellipse cx="55" cy="60" rx="25" ry="15"
          style="stroke: none; fill: #0000ff; " />

<ellipse cx="155" cy="60" rx="25" ry="15"
          style="stroke: none; fill: #0000ff; filter: url(#blurFilter);" />

最终图片如下:

注意右侧椭圆的边缘是如何模糊的。

滤镜输入和输出

SVG滤镜需要一些输入(源),并为它们应用滤镜效果。滤镜的输入可以是图形形状(意味着RGB颜色),形状的alpha通道或另一个滤镜的输出。

SVG滤镜从输入产生图形输出(结果)。此输出是正常显示的,而不是应用滤镜的形状。滤镜的输出可以用作另一个滤镜的输入,因此,滤镜可以链式添加。

下面是SVG滤镜输入和输出的图示:

SVG滤镜可以使用图形形状,alpha通道或另一个滤镜的输出作为输入。

SVG滤镜的输入通常在滤镜元素的in属性中指定。示例如下:

<feGaussianBlur stdDeviation="3" in="SourceGraphic" />

如果一个SVG滤镜的输出用作另一个滤镜的输入,则需要向滤镜元素添加一个result属性。示例如下:

<feGaussianBlur stdDeviation="3"
    in="SourceGraphic" result="blur"/>

现在,另一个SVG滤镜可以通过将值blur放入其in属性中来使用此滤镜的输出。在上面的示例中,值blur是在过滤器的result属性中指定。

滤镜尺寸

滤镜的尺寸通过xywidthheight属性设置。

xy属性被解释为相对于作为输入的形状的xy坐标。由于一些滤镜的输出通常比输入大(如在形状周围添加的模糊),你通常需要为xy使用负数,以避免截断滤镜添加的图形。

widthheight属性一样简单。同样,有时可能需要指定大于输入形状的宽度和高度,以避免截断由滤镜添加的效果。

组合滤镜

你可以使用<feMerge>元素组合滤镜。示例代码如下:

<defs>
    <filter id="blurFilter2" y="-10" height="40" x="-10" width="150">
        <feOffset in="SourceAlpha" dx="3" dy="3" result="offset2" />
        <feGaussianBlur in="offset2" stdDeviation="3"  result="blur2"/>

        <feMerge>
            <feMergeNode in="blur2" />
            <feMergeNode in="SourceGraphic" />
        </feMerge>
    </filter>
</defs>

<ellipse cx="55" cy="60" rx="25" ry="15"
         style="stroke: none; fill: #0000ff; filter: url(#blurFilter2);" />

这个例子创建了包含两个滤镜元素(<feOffset><feGaussianBlur>)的SVG滤镜。偏移滤镜效果对其应用的形状的Alpha通道起作用。高斯模糊对偏移滤镜效果的输出起作用。

<feMerge>元素将模糊滤镜的输出和原始图形相结合。输入按照它们出现在<feMerge>元素内的顺序进行组合。因此,后面的输入在之前的输入的上面。结果是一个图像,其中形状看起来有一个阴影。这是最终图片:

高斯模糊滤镜

高斯模糊SVG滤镜可以模糊SVG形状,其由<feGaussianBlur>元素表示。示例如下:

<defs>
    <filter id="blurFilter4" x="-20" y="-20" width="200" height="200">
        <feGaussianBlur in="SourceGraphic" stdDeviation="10" />
    </filter>
</defs>
<rect x="20" y="20" width="90" height="90"
      style="stroke: none; fill: #00ff00; filter: url(#blurFilter4);" />

这个例子定义了一个<filter>,其中包含一个<feGaussianBlur>。然后定义了一个通过CSS属性filter引用该滤镜的绿色矩形。最终图片如下:

模糊大小

<feGaussianBlur>元素的stdDeviation属性确定了应用滤镜的形状的模糊程度。数字越大,形状越模糊。以下是stdDeviation属性具有不同值的三个示例:

<defs>
    <filter id="blurFilter5" x="-20" y="-20" width="200" height="200">
        <feGaussianBlur in="SourceGraphic" stdDeviation="2" />
    </filter>
    <filter id="blurFilter6" x="-20" y="-20" width="200" height="200">
        <feGaussianBlur in="SourceGraphic" stdDeviation="6" />
    </filter>
    <filter id="blurFilter7" x="-20" y="-20" width="200" height="200">
        <feGaussianBlur in="SourceGraphic" stdDeviation="12" />
    </filter>
</defs>

<rect x="20" y="24" width="90" height="90"
      style="stroke: none; fill: #00ff00; filter: url(#blurFilter5);" />
<rect x="150" y="24" width="90" height="90"
      style="stroke: none; fill: #00ff00; filter: url(#blurFilter6);" />
<rect x="300" y="24" width="90" height="90"
      style="stroke: none; fill: #00ff00; filter: url(#blurFilter7);" />

最终图片如下:

注意,应用到矩形上的滤镜的stdDeviation属性值越来越大,矩形也越来越模糊。

模糊Alpha通道

上面的例子中使用SourceGraphic作为输入,意味着形状的RGB颜色用作滤镜的输入。你可以通过在<feGaussianBlur>元素的in属性中设置SourceAlpha值,使用形状的alpha通道作为输入。示例如下:

<defs>
    <filter id="blurFilter8" x="-20" y="-20" width="200" height="200">
        <feGaussianBlur in="SourceAlpha" stdDeviation="10" />
    </filter>
</defs>
<rect x="20" y="20" width="90" height="90"
      style="stroke: none; fill: #00ff00; filter: url(#blurFilter8);" />

最终图片如下:

注意,即使矩形用绿色填充定义,滤镜的输出也是黑色和白色。当高斯模糊滤镜应用于alpha通道而不是图形(RGB)通道时,会发生这种情况。

偏移滤镜

偏移滤镜接受输入并移动输入作为输出。也就是说,它可以向上、向下、向左或向右移动形状。因此,除了它是一个滤镜外,它的工作方式位移变换一样。示例如下:

<defs>
    <filter id="offsetFilter1" x="-20" y="-20" width="200" height="200">
        <feOffset in="SourceGraphic" dx="80" dy="20" />
    </filter>
</defs>
<rect x="20" y="20" width="90" height="90"
      style="stroke: #000000; fill: none; filter: url(#offsetFilter1);" />
<rect x="20" y="20" width="90" height="90"
      style="stroke: #000000; fill: none; " />

这个例子在完全相同的位置定义了两个矩形。其中一个矩形应用了一个偏移滤镜,使它向右下方移动。

最终图片如下:

看起来偏移滤镜对形状也有一些其它影响(一种模糊),但我不知道为什么。我没有找到为什么会发生这种情况的解释。

彩色矩阵滤镜

彩色矩阵滤镜可以用于将矩阵变换应用于形状的颜色。示例如下:

<defs>
    <filter id="colorMatrixFilter1" x="-20" y="-20" width="200" height="200">
        <feColorMatrix in="SourceGraphic" type="matrix"
                values="0 0 0 1 0
                        0 0 0 1 0
                        0 0 0 1 0
                        0 0 0 1 0
                "/>
    </filter>
</defs>
<rect x="20" y="20" width="90" height="90"
      style="stroke: none; fill: #0000ff; filter: url(#colorMatrixFilter1);" />

矩阵的值有<feColorMatrix>元素的values属性提供。总共必须有4 x 5 = 20个值。这些值应用于原始形状的颜色,如下所示:

0 0 0 red   0
0 0 0 green 0
0 0 0 blue  0
0 0 0 1     0

最终图片如下:

注意:我在Chrome和Firefox中使用彩色矩阵滤镜得到了一些奇怪的结果。上面的矩形指定填充颜色,但是一旦使用彩色矩阵滤镜,只剩下轮廓。

混合滤镜

混合滤镜可以将来自多个滤镜的输入混合成一个。示例如下:

<svg width="500" height="100">
  <defs>
    <filter id="blurFilter3" y="-10" height="40" x="-10" width="150">
      <feOffset in="SourceAlpha" dx="3" dy="3" result="offset3" />
      <feGaussianBlur in="offset3" stdDeviation="3"  result="blur3"/>

      <feBlend  in="SourceGraphic" in2="blur3" x="-10" width="160"/>

    </filter>
  </defs>

  <ellipse cx="55" cy="60" rx="25" ry="15"
         style="stroke: none; fill: #0000ff;
                filter: url(#blurFilter3);" />

</svg>

这个例子声明了一个使用三个滤镜效果的滤镜。前两个是偏移和高斯滤镜效果,第三个是<feBlend>效果,它接受两个输入(inin2),并将它们混合成一个。

最终效果非常类似于本文前面所述的组合过滤器。

最后更新于