上周看到有一篇关于CSS滤镜效果函数的文章,其中的效果函数相对来说比较容易理解,而且上手难度低。但是,这种方式仅仅是添加CSS滤镜效果众多方式中最弱的一种。今天让我们来看一看滤镜基元,这是为图片和元素添加滤镜效果另外一种更加强大的方法。
相较于效果函数,滤镜基元为我们提供了更多的东西。一方面原因是滤镜基元有更多的效果。另一方面是在两者相似的地方,滤镜基元为我们提供了更多的使用方式。
滤镜基元其实比较复杂,很难在一篇文章中展现它的全貌,在这里需要说一声抱歉。
我发现官方文档的描述比较模糊,而且缺乏一些帮助我们理解的例子。我也查过一些资料,但是大多数都是在讨论SVG滤镜本身。不过,高兴的是,我可以轻松地让例子跑起来了,这个例子会在下面给出。有一点不太满意的地方是,它不是在所有的浏览器中都能运行。但是我相信,未来这些浏览器都会支持。
什么是CSS滤镜基元?
滤镜基元和效果函数并没有多么不同。在许多方面,他们只是用不同方式做着同样的事情。基元最初是被作为SVG滤镜开发的,之后被扩展到不仅仅支持SVG图片。
像效果函数一样,滤镜基元是一种不需要图片编辑器就可以添加滤镜效果的一种方法。这使得它更加灵活,并且不具破坏性。它被写在SVG标记中,然后可以通过CSS filter属性的url
值应用到图片或者元素上。
.filtered {
filter: url(path-to-filter-primitives);
}
滤镜基元的概念不再像以前那样复杂。它只是与效果函数的书写方式不一样,它还提供了更多的选项,然后以不同的方式将滤镜应用于目标元素。例子或许是帮你弄清它是什么及其工作方式的最佳方法。
使用SVG滤镜基元
hue-rotate
是一个效果函数,你可以像下面这样使用它:
filter: hue-rotate(60deg);
等价的滤镜基元会是下面这样:
<feColorMatrix type="hueRotate" values="60"/>
这是一个标记,而不是CSS,它有一个新名字,你可以看到type
属性有一个和效果函数的函数名相似的值,我们还需要更多的代码来让上面的基元工作,但是我想你已经知道了基元和效果函数的关联。
让我们来看一个例子。我会将滤镜应用在下面这张图片:
HTML结构很简单:
<div class="filtered">
<img src="images/strawberry-fields.jpg" />
</div>
CSS同样很简单:
filter: url(filters.svg#filter-primitives);
我使用了filter
属性的url
值,并且将url
指向filters.svg
文件。在这个文件中,我通过id
名为filter-primitives
调用了具体的滤镜。
到目前为止,步骤都很简单,现在我们需要定义相应的滤镜。这里是完整的filters.svg
文件
<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg">
<defs>
<filter id="filter-primitives">
<feGaussianBlur stdDeviation="3" />
<feColorMatrix type="hueRotate" values="270"/>
<feColorMatrix type="saturate" values="0.75"/>
<feBlend mode="multiply"/>
</filter>
</defs>
</svg>
这个文件首先定义了自己是用xml语言书写的SVG文档。接下来是SVG对象。滤镜定义在defs
元素中。它的id
就是我们刚才在CSS中引用的那个。这里我应用了4
个滤镜基元。我希望各自都可以最大化发挥各自的作用。
还有一些需要注意的事情,就是同时使用了hue-rotate
和saturate
,每一个都是独一无二的滤镜,但是不仅仅局限于hue
和 saturation
,它还有一个luminanceToAlpha
值,你也可以直接将一个矩阵赋值给它。
我知道你已经习惯使用ps或者其它图片编辑器,同样需要注意的是,这里虽然没有所有的混合滤镜,但是我们有 normal
、 multiply
、 mutiply
、 screen
、 darken
和 lighten
。
应用上面的滤镜会得到下面这张图片:
上面的例子能完美地在Firefox运行,但是在Chrome Canary和Safari中就悲剧了。为了让上面的例子也能在这两个浏览器中正常运行,于是,我将所有的代码都写在了index.html
中。
<svg>
<image x="0" y="0" width="800" height="600" xlink:href="images/strawberry-fields.jpg" filter="url(#filter-primitives)"></image>
</svg>
<svg>
<defs>
<filter id="filter-primitives">
<feGaussianBlur stdDeviation="0" />
<feColorMatrix type="hueRotate" values="270"/>
<feColorMatrix type="saturate" values="0.75"/>
<feBlend mode="multiply"/>
</filter>
</defs>
</svg>
所有的东西都在同一个文件中,而不是通过CSS链接外部文件。滤镜没有变。图片元素由原始的HTML图片变为SVG图片。
有趣的是,这个例子在Firefox里居然是。。。。滤镜确实应用在了图片上,但是Firefox只会显示裁切过的图片,就像下面这样:
图片和div
容器已经被全尺寸渲染,但是图片会被裁切成宽高为300px
和150px
的区域。我现在还不知道这是为什么。。
如果有人知道,可以在这里分享一下。
其它例子
这里有一些我查阅资料时候碰到的其它例子。
可以从每一个的标题看出来,它们可以汇总成三方面,SVG滤镜,CSS和SVG运用相同滤镜时使用上的细微差别,和不同浏览器对不同方式的支持程度。
滤镜基元清单
有许多我没有在上面使用到的滤镜基元都和效果函数很相似,或者说相似到能够让我们很容易理解它们到底是做什么的。还有不少的更加复杂一些的滤镜基元,但是我已经没有机会再去研究他们了
混合和合并效果
-
feBlend
-
feComposite
-
feMerge
色彩效果
-
feColorMatrix
-
feComponentTransfer
-
feFlood (flood-color and flood-opacity)
光照和光源效果
-
feDiffuseLighting
-
feSpecularLighting
-
feDistantLight
-
fePointLight
-
feSpotLight
其它特殊效果
-
feConvolveMatrix
-
feDisplacementMap
-
feTurbulence
-
feGaussianBlur
-
feImage
-
feMorphology
-
feTile
-
feOffset
-
feDropShadow
自定义效果
- feCustom
总结
在这里我向可能引起的困惑道歉。由于官方文档缺少相关的例子,对我来说确实不是那么清晰,除此之外查阅到的资料都是讨论SVG滤镜的。这和我想要的确实有很密切的联系,但是不是同一件事情。
如果我们坚持这个滤镜效果规范,那么滤镜基元就是储存在单独文件中的SVG标记,使用filter: url()
,他们可以应用在所有图片或者HTML文档中的其它元素。当SVG滤镜被储存在HTML中时,它只能应用在SVG元素上。
当我努力让它们工作,而且它们确实那样做的时候,很容易看到效果是有多么的强大。希望在不久的将来,我能够清除现在的所有困惑,然后对它们有更加深刻的理解。