SVG 滤镜创造液态滚动沾粘(Gooey)效果

1,395 阅读4分钟
原文链接: svgtrick.com

在codepen发现这样一个效果:

效果链接

从代码中可以发现,它是使用了SVG中的滤镜来实现这个效果的,主要是运用高斯模糊和颜色矩阵以及混合这三个滤镜组合来实现的。

下面就来学习下SVG中的滤镜知识,来分析下如何使用SVG的滤镜来实现这个效果。

SVG滤镜

在SVG滤镜中,任何一种效果,都至少包含一个原语。一个原语通常包含一个或两个输入(in,in2),以及一个输出(result)。原语输入包括模糊、移动、填充、结合或扭曲等等。result属性可以把一个filter操作的结果作为另一个filter操作的输入(用in指定输入)。

在使用filter的时候,可以使用一个操作的结果作为另一个滤镜的输入,以此实现无尽可能的效果。这也是滤镜的真正强大之处。

来看一个SVG滤镜的一个常见例子:

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="600" height="400">
  <defs>
    <filter id="dropshadow" x="0" y="0" width="200%" height="200%">
        <feOffset result="offsetResult" in="SourceAlpha" dx="20" dy="20" />
        <feGaussianBlur result="blurResult" in="offsetResult" stdDeviation="5" />
        <feBlend in="SourceGraphic" in2="blurResult" mode="normal" />
    </filter>
  </defs>
  <rect width="300" height="100" x="200" y="100" fill="green" filter="url(#dropshadow)" />
</svg>

效果如下:

借这个例子来说下SVG滤镜的一些知识点。

feOffset来移动滤镜的位置;

使用了feGaussianBlur这个滤镜来制作高斯模糊的效果,其中stdDeviation来指定模糊程度,值越大,模糊的效果越强。我们可以使用引用前一个result指定的属性。

在高斯模糊滤镜效果中,通过in来调用了feOffset移动输入源的效果的结果。

然后使用了feBlend是为了把原始元素放在模糊了的结果之上。使用in="SourceAlpha"可以使模糊是黑色的。如果我们使用的是in="SourceGraphic",那么“阴影”将是原始元素的颜色。

定义好滤镜后,将这个SVG滤镜对象放到HTML中,方便在元素中来使用它。

SVG颜色矩阵滤镜(feColorMatrix)

颜色矩阵滤镜,是用一个矩阵的计算,将图片的色彩的每个通道(基于RGBA)重新计算后输出,便可以达到各种不同的色彩变化效果。

我们知道每一个颜色都是有R(红)、G(绿)、B(蓝)、A(透明/Alpha)四个颜色通道组成,每一个通道颜色具有0到255色阶,通过色彩矩阵的换算,可以改变图片里每一个像素的颜色,公式如下:

最后一列不表示任何通道,用于表示颜色的偏移量用于加或者是减,即表示一个数字将添加到其通道的值乘以255。

实例分析

来看下,原效果中定义的SVG滤镜:

<svg>
  <defs>
    <filter id="goo">
      <feGaussianBlur in="SourceGraphic" result="blur" stdDeviation="5"/>
      <feColorMatrix in="blur" result="colormatrix"
        type="matrix"
        values="1 0 0 0 0
                0 1 0 0 0
                0 0 1 0 0
                0 0 0 18 -8" />
      <feBlend in="SourceGraphic" in2="colormatrix"/>
    </filter>
  </defs>
</svg>

从上面的代码中可以看到,RGB通道是正常的没有做出调整。主要是alpha通道的值调,将alpha通道的值乘以18,然后从该值减去7 * 255,增加透明通道的对比度。

拆开来分析下,第一个滤镜是做的模糊。然后是使用feColorMatrix滤镜来增加alpha的对比度,把它与模糊一起用feBlend混合起来使用,就会产生沾粘的效果。

这里粘在一起的原理具体是什么样的呢?

当对一个元素使用模糊滤镜的时候,它会使元素产生模糊的效果。而使用contrast滤镜即对比度滤镜的时候,当你把颜色的对比度提高到足够大的时候,元素会变得锐利起来。

而当同时在两个元素上应用这两个滤镜,它们就会产生粘在一起的效果,如下图所示:

源代码地址

具体详细的解释可以去看看这篇文章

滤镜定义好后,就可以在CSS中使用它,把滤镜应用到我们想沾粘到一起的元素的容器中,比如上面的这个实例是在头部应用这个滤镜来产生沾粘的效果,就可以这样写:

header {
  -webkit-filter: url("#goo");
          filter: url("#goo");
}

一个优雅的滚动沾粘效果就做好了。

参考资料:

SVG 研究之路 (11) - filter:feColorMatrix

详解feColorMatrix

带你轻松打开svg滤镜的大门


本文对你有帮助?欢迎扫码加入前端学习小组微信群: