CSS 的filter+SVG能碰出什么样的火花哩

320 阅读3分钟

这是我参与「第五届青训营」伴学笔记创作活动的第 3 天

先看一看filter都有哪些基本的用法吧:

filter基本用法:

一些具体的参数和用法直接看这里就好了:CSS3 filter(滤镜) 属性 | 菜鸟教程 (runoob.com)

然后补充一点: drop-shadow(h-shadow v-shadow blur spread color)的前几个参数都是px,spread这个参数Webkit不支持,所以只用写三个px和一个颜色就好了。这四个可用参数里只有前两个是必须的。

但是我们实验发现,CSS的filter对img元素的效果很棒,但是对于不是img的元素,能起效的就是不很多了。

(经过测试,能用在其他元素的只有高斯模糊blur颜色反转invert透明度opacity阴影drop-shadow

image.png

(不过可以用这四个参数组成毛玻璃效果:filter: blur(5px) opacity(0.8) brightness(0.9);)

那好像就有点鸡肋了,所以也就引出来我们今天要瞅一瞅的 SVG滤镜

SVG滤镜

首先,filter提供了url这么一个属性,可以让我们指定一个xml作为滤镜。那什么是SVG呢?

概念:  SVG,即可缩放矢量图形(Scalable Vector Graphics)

特点: 1. SVG 用来定义网络的基于矢量的图形

2. SVG 使用 XML 格式定义图形

3. SVG 图像在放大或改变尺寸的情况下其图形质量不会失真

4. SVG可以更好地和HTML、CSS结合计算机的两大图形系统栅格图形(位图:JPG、PNG等)和矢量图

具体的滤镜可以看这里feBlend - SVG:可缩放矢量图形 | MDN

fe开头的属性基本上就是滤镜的属性了。我们来举几个例子吧:

<svg width="500" height="100">

<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);" /> 

</svg>

运行效果是这样的:

image.png

这里首先创建filter元素,id为"blurFilter2",feOffset用来设置偏移量,这里设置x和y都是3。

那后面的result是什么意思嘞?这里着重说一下result和in这两个属性:

result 存放该步操作的结果。指定了result以后,同一个filter元素的其他后续操作都可以用in来指定其为输入。如果省略了这个值,则只能作为紧挨着的下一步操作的隐式输入,注意如果紧挨着的下一步操作已经用 in指定了输入,则以in指定的为准。

in 表示该步操作的输入。省略in属性的话,将会默认使用前一步的结果作为本步的输入,如果省略的是第一步的in,则会使用"SourceGraphic"作为值。

in不仅仅只能用前面result的输出,还有六个默认可以的取值,SourceGraphic也是其一:

  • SourceGraphic:这个值代表使用当前的图形元素作为操作的输入。
  • SourceAlpha:这个值代表使用当前图形元素的Alpha值作为操作的输入。
  • BackgroundImage:这个值代表使用当前的背景截图作为操作的输入。
  • BackgroundAlpha:这个值代表使用当前的背景截图的Alpha值作为操作的输入。
  • FillPaint:这个值使用当前图形元素的fill属性的值作为操作的输入。
  • StrokePaint:这个值使用当前图形元素的stroke属性的值作为操作的输入。

那么,到这里一切都很好理解了。

feOffset把偏移量定义为offset2,feGaussianBlur接受这个输出并在进行模糊后输出值命名为blur2。

feMerge在MDN的定义是:

feMerge滤镜允许同时应用滤镜效果而不是按顺序应用滤镜效果。利用result存储别的滤镜的输出可以实现这一点,然后在一个feMergeNode子元素中访问它。

所以完全解释通了!

feMerge展示了两个feMergeNode,一个是刚刚计算的阴影(模糊加偏移得出的) ,另一个是SourceGraphic,也就是当前的图形元素。当前的图形元素是哪个呢?是调用这个阴影的ellipse。

最后,给大家附一个好看的波纹Svg滤镜吧: