什么是SVG滤镜
这篇文章主要介绍“什么是 SVG 滤镜”,在日常操作中,相信很多人在什么是 SVG 滤镜问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”什么是 SVG 滤镜”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
成都创新互联公司专业为企业提供沙河口网站建设、沙河口做网站、沙河口网站设计、沙河口网站制作等企业网站建设、网页设计与制作、沙河口企业网站模板建站服务,10多年沙河口做网站经验,不只是建网站,更提供有价值的思路和整体网络服务。
想写一篇关于 SVG 滤镜的文章已久,SVG 滤镜的存在,让本来就非常强大的 CSS 如虎添翼。让仅仅使用 CSS/HTML/SVG 创作的效果更上一层楼。题图为袁川老师使用 SVG 滤镜实现的云彩效果 -- CodePen Demo -- Cloud (SVG filter + CSS)[1]。
什么是 SVG 滤镜
SVG 滤镜与 CSS 滤镜类似,是 SVG 中用于创建复杂效果的一种机制。很多人看到 SVG 滤镜复杂的语法容易心生退意。本文力图使用最简洁明了的方式让大家尽量弄懂 SVG 滤镜的使用方式。
本文默认读者已经掌握了一定 SVG 的基本概念和用法。
SVG 滤镜的种类
SVG 滤镜包括了:
feBlend feColorMatrix feComponentTransfer feComposite feConvolveMatrix feDiffuseLighting feDisplacementMap feFlood feGaussianBlur feImage feMerge feMorphology feOffset feSpecularLighting feTile feTurbulence feDistantLight fePointLight feSpotLight
看着内容很多,有点类似于 CSS 滤镜中的不同功能:blur()、contrast()、drop-shadow() 。
SVG 滤镜的语法
我们需要使用
通常所有的 SVG 滤镜元素都需要定义在
现在,基本上现代浏览器,即使不使用
包裹 ,也能够定义一个 SVG 滤镜。
这个
其次,使用
看一个简单的 DEMO:
div { width: 100px; height: 100px; background: #000; } .cssblur { filter: blur(5px); } .svgFilter{ filter: url(#blur); }
这里,我们在 defs 的 filter 标签内,运用了 SVG 的 feGaussianBlur 滤镜,也就是模糊滤镜, 该滤镜有两个属性 in 和 stdDeviation。其中 in="SourceGraphic" 属性指明了模糊效果要应用于整个图片,stdDeviation 属性定义了模糊的程度。最后,在 CSS 中,使用了 filter: url(#blur) 去调用 HTML 中定义的 id 为 blur 的滤镜。
为了方便理解,也使用 CSS 滤镜 filter: blur(5px) 实现了一个类似的滤镜,方便比较,结果图如下:
CodePen Demo - SVG 滤镜[2]
嘿,可以看到,使用 SVG 的模糊滤镜,实现了一个和 CSS 模糊滤镜一样的效果。
CSS filter 的 url 模式
上文的例子中使用了 filter: url(#blur) 这种模式引入了一个 SVG 滤镜效果,url 是 CSS 滤镜属性的关键字之一,url 模式是 CSS 滤镜提供的能力之一,允许我们引入特定的 SVG 过滤器,这极大的增强 CSS 中滤镜的能力。
相当于所有通过 SVG 实现的滤镜效果,都可以快速的通过 CSS 滤镜 URL 模式一键引入。
多个滤镜搭配工作
和 CSS 滤镜一样,SVG 滤镜也是支持多个滤镜搭配混合使用的。
所以我们经常能看到一个
再来看个简单的例子:
div { width: 200px; height: 200px; background: url(xxx); filter: url(#MyFilter); }
我们先来看看整个滤镜的最终结果,结果长这样:
CSS 可能一行代码就能实现的事情,SVG 居然用了这么多代码。(当然,这里 CSS 也不好实现,不是简单容器的阴影,而是 PNG 图片图形的轮廓阴影)
分解步骤
首先看这一段:
首先
紧接着,
这里就有一个非常重要的知识点:在不同滤镜中利用 result 和 in 属性,可以实现在前一个基本变换操作上建立另一个操作,比如我们的例子中就是添加模糊后又添加位移效果。
结合两个滤镜,产生的图形效果,其实是这样的:
实际效果中还出现了原图,所以这里我们还使用了
feMerge 滤镜允许同时应用滤镜效果而不是按顺序应用滤镜效果。利用 result 存储别的滤镜的输出可以实现这一点,然后在一个
表示了上述两个滤镜的最终输出结果 offsetBlur,也就是阴影的部分 中的 in="SourceGraphic" 关键词表示图形元素自身将作为 原语的原始输入
整体再遵循后输入的层级越高的原则,最终得到上述结果。示意流程图如下:
至此,基本就掌握了 SVG 滤镜的工作原理,及多个滤镜如何搭配使用。接下来,只需要搞懂不同的滤镜能产生什么样的效果,有什么不同的属性,就能大致对 SVG 滤镜有个基本的掌握!
关于 SVG 滤镜还需要知道的
上面大致过了一下 SVG 滤镜的使用流程,过程中提到了一些属性,可能也漏掉了一些属性的讲解,本章节将补充说明一下。
滤镜标签通用属性
有一些属性是每一个滤镜标签都有,都可以进行设置的。
in 属性的 6 个取值
SVG filter 中的 in 属性,指定滤镜效果的输入源,可以是某个滤镜导出的 result,也可以是下面 6 个值:
后 4 个基本用不上~
后面 4 个不太常用。
更多 SVG 滤镜介绍讲解
上面已经提到了几个滤镜,我们简单回顾下:
- 模糊滤镜 - 位移滤镜 - 多滤镜叠加滤镜
接下来再介绍一些比较常见,有意思的 SVG 滤镜。
feBlend 滤镜
在 CSS 中,我们有混合模式 mix-blend-mode 和 background-blend-mode 。我有过非常多篇关于 CSS 混合模式相关的一些应用。如果你还不太了解 CSS 中的混合模式,可以先看看这几篇文章:
不可思议的混合模式 mix-blend-mode[3]
不可思议的混合模式 background-blend-mode[4]
CSS奇思妙想 -- 使用 background 创造各种美妙的背景[5]
SVG 中的混合模式种类比 CSS 中的要少一些,只有 5 个,其作用与 CSS 混合模式完全一致:
normal — 正常
multiply — 正片叠底
screen — 滤色
darken — 变暗
lighten— 变亮
简单一个 Demo,我们有两张图,利用不同的混合模式,可以得到不一样的混合结果 :
.container { width: 200px; height: 250px; filter: url(#lighten); }
这里还用到了一个
上述运用了 feBlend 滤镜中的 mode="lighten" 后的结果,两个图像叠加作用了 lighten 混合模式:
看看全部 5 种混合模式的效果:
CodePen Demo -- SVG Filter feBlend Demo[6]
feColorMatrix
这个滤镜稍微有点复杂,我们一步一步来看。
在这里,我做了一个简单的关于
saturate、hueRotate 滤镜和 CSS 中的 filter 中的 saturate、hue-rotate 的作用是一模一样的。
feColorMatrix 中的 type=matrix
feColorMatrix 中的 type=matrix 理解起来要稍微更复杂点,它的 values 需要传入一个 4x5 的矩阵。
像是这样:
要理解如何运用这些填写矩阵,就不得不直面另外一个问题 -- 图像的表示。
数字图像的本质是一个多维矩阵。在图像显示时,我们把图像的 R 分量放进红色通道里,B 分量放进蓝色通道里,G 分量放进绿色通道里。经过一系列处理,显示在屏幕上的就是我们所看到的彩色图像了。
而 feColorMatrix 中的 matrix 矩阵,就是用来表示不同通道的值每一个分量的值,最终通过计算得到我们熟知的 rgba() 值。
计算逻辑为:
/* R G B A 1 */ 1 0 0 0 0 // R = 1*R + 0*G + 0*B + 0*A + 0 0 1 0 0 0 // G = 0*R + 1*G + 0*B + 0*A + 0 0 0 1 0 0 // B = 0*R + 0*G + 1*B + 0*A + 0 0 0 0 1 0 // A = 0*R + 0*G + 0*B + 1*A + 0
中文的文章,对 feColorMatrix 的 matrix 讲解最好的应该就是大漠老师的这篇 -- 详解feColorMatrix[8],对具体的表示法感兴趣的可以看看。
仅仅是使用的话,这里还有一个可视化的 DEMO -- CodePen - feColorMatrix Demo[9],帮助大家理解记忆:
到目前为止,大部分 SVG 滤镜的展示讲解都是 CSS 现有能力能够实现的,那 SVG 滤镜的独特与魅力到底在哪呢?有什么是 CSS 能力无法做到的么?下面来看看另外几个有意思的 SVG 滤镜。
feSpecularLighting/feDiffuseLighting 光照滤镜
feSpecularLighting 与 feDiffuseLighting 都意为光照滤镜,使用它们可以照亮一个源图形,不同的是,feSpecularLighting 为镜面照明,而 feDiffuseLighting 为散射光照明。
feDiffuseLighting:来自外部光源,适合模拟太阳光或者灯光照明
feSpecularLighting:指定从反射面反射的二次光
简单看其中一个 Demo,代码看着有点多,但是一步一步也很好理解:
div { background: url(avator.png); } .svg-filter { filter: url(#filter); }
左边是原图,右边是应用了光照滤镜之后的效果。
CodePen - feSpotLight SVG Light Source[10]
feMorphology 滤镜
feMorphology 为形态滤镜,它的输入源通常是图形的 alpha 通道,用来它的两个操作可以使源图形腐蚀(变薄)或扩张(加粗)。
使用属性 operator 确定是要腐蚀效果还是扩张效果。使用属性 radius 表示效果的程度,可以理解为笔触的大小。
operator:erode 腐蚀模式,dilate 为扩张模式,默认为 erode
radius:笔触的大小,接受一个数字,表示该模式下的效果程度,默认为 0
我们将这个滤镜简单的应用到文字上看看效果:
Normal Text
Normal Text
Normal Text
p { font-size: 64px; } .dilate { filter: url(#dilate); } .erode { filter: url(#erode); }
效果如下:最左边的是正常文字,中间的是扩张的模式,右边的是腐蚀模式,看看效果,非常好理解:
当然,我们还可以将其运用在图片之上,这时,并非是简单的让图像的笔触变粗或者变细,
对于 erode 模式,会将图片的每一个像素向更暗更透明的方向变化,
而 dilate 模式,则是将每个向像素周围附近更亮更不透明的方向变化
简单看个示例动画 DEMO,我们有两张图,分别作用 operator="erode" 和 operator="dilate",并且动态的去改变它们的 radius,其中一个的代码示意如下:
上图左边是扩张模式,右边是腐蚀模式:
CodePen Demo -- SVG feMorphology Animation[11]
feTurbulence 滤镜
turbulence 意为湍流,不稳定气流,而 SVG
有了 feTurbulence,我们可以自使用 SVG 创建纹理图形作为置换图,而不需要借助外部图形的纹理效果,即可创建复杂的图形效果。
这个滤镜,我个人认为是 SVG 滤镜中最有意思的一个,因为它允许我们自己去创造出一些纹理,并且叠加在其他效果之上,生成出非常有意思的动效。
feTurbulence 有三个属性是我们特别需要注意的:type、baseFrequency、numOctaves:
1.type:实现的滤镜的类型,可选fractalNoise 分形噪声,或者是 turbulence 湍流噪声。
fractalNoise:分形噪声更加的平滑,它产生的噪声质感更接近云雾
turbulence:湍流噪声
2.baseFrequency:表示噪声函数的基本频率的参数,频率越小,产生的图形越大,频率越大,产生的噪声越复杂其图形也越小越精细,通常的取值范围在 0.02 ~ 0.2
3.numOctaves:表示噪声函数的精细度,数值越高,产生的噪声更详细。默认值为1
这里有一个非常好的网站,用于示意 feTurbulence 所产生的两种噪声的效果:http://apike.ca/ - feTurbulence[12]
两种噪声的代码基本一致,只是 type 类型不同:
同时,baseFrequency 允许我们传入两个值,我们可以只改变某一方向上的频率,具体的你可以戳这个 Demo 看看:CodePen -- feTurbulence baseFrequency & numOctaves[13]
单单一个
使用 feTurbulence 滤镜实现文字流动的效果
首先,尝试将 feTurbulence 所产生的纹理和文字相结合。
简单的代码如下:
CocoCoco
.turbulence { filter: url(#fractal); }
左边是正常的效果,后边是应用了
CodePen Demo -- feTurbulence text demo[14]
feDisplacementMap 映射置换滤镜
上面的 Demo 还用到了 feDisplacementMap 滤镜,也需要简单的讲解下。
feDisplacementMap 为映射置换滤镜,想要用好这个滤镜不太容易,需要掌握非常多的关于 PhotoShop 纹理创建或者是图形色彩相关的知识。该滤镜用来自图像中从 in2 的输入值到空间的像素值置换图像从 in 输入值到空间的像素值。
说人话就是 feDisplacementMap 实际上是用于改变元素和图形的像素位置的。该滤镜通过遍历原图形的所有像素点,使用 feDisplacementMap 重新映射到一个新的位置,形成一个新的图形。
在上述的 feTurbulence 滤镜与文字的结合使用中,我们通过 feTurbulence 噪声得到了噪声图形,然后通过 feDisplacementMap 滤镜根据 feTurbulence 所产生的噪声图形进行形变,扭曲,液化,得到最终的效果。
在 MDN[15]上有这个滤镜转化的一个公式(感兴趣的可以研究下,我啃不动了):
P'(x,y) ← P( x + scale * (XC(x,y) - 0.5), y + scale * (YC(x,y) - 0.5))
使用 feTurbulence 滤镜实现褶皱纸张的纹理
好,我们继续 feTurbulence ,使用这个滤镜,我们可以生成各种不同的纹理,我们可以尝试使用 feTurbulence 滤镜搭配光照滤镜实现褶皱的纸张纹理效果,代码也非常少:
div { width: 650px; height: 500px; filter: url(#roughpaper); }
效果如下:
CodePen Demo -- Rough Paper Texture with SVG Filters[16]
你可以在 Sara Soueidan[17]的一次关于 SVG Filter 的分享上,找到制作它的教程:Youtube -- SVG Filters Crash Course[18]
使用 feTurbulence 滤镜实现按钮hover效果
使用 feTurbulence 滤镜搭配 feDisplacementMap 滤镜,还可以制作一些非常有意思的按钮效果。
尝试实现一些故障风格的按钮,其中一个按钮的代码如下:
ButtonButton
.fe1 { width: 200px; height: 64px; outline: 200px solid transparent; } .fe1:hover { filter: url(#fe1); }
通过 hover 按钮的时候,给按钮添加滤镜效果,并且滤镜本身带有一个无限循环的动画:
完整的代码你可以戳这里:CodePen Demo - SVG Filter Button Effects[19]
使用 feTurbulence 滤镜实现云彩效果
最后,我们回到题图上的云彩效果,使用 feTurbulence 滤镜,我们可以非常逼真的使用 SVG 模拟出真实的云彩效果。
首先,通过随机生成的多重 box-shadow,实现这一一个图形:
div { width: 1px; height: 1px; box-shadow: rgb(240 255 243) 80vw 11vh 34vmin 16vmin, rgb(17 203 215) 33vw 71vh 23vmin 1vmin, rgb(250 70 89) 4vw 85vh 21vmin 9vmin, rgb(198 241 231) 8vw 4vh 22vmin 12vmin, rgb(198 241 231) 89vw 11vh 31vmin 19vmin, rgb(240 255 243) 5vw 22vh 38vmin 19vmin, rgb(250 70 89) 97vw 35vh 33vmin 16vmin, rgb(250 70 89) 51vw 8vh 35vmin 14vmin, rgb(17 203 215) 75vw 57vh 40vmin 4vmin, rgb(250 70 89) 28vw 18vh 31vmin 11vmin, rgb(250 70 89) 8vw 89vh 31vmin 2vmin, rgb(17 203 215) 13vw 8vh 26vmin 19vmin, rgb(240 255 243) 98vw 12vh 35vmin 5vmin, rgb(17 203 215) 35vw 29vh 27vmin 18vmin, rgb(17 203 215) 67vw 58vh 22vmin 15vmin, rgb(198 241 231) 67vw 24vh 25vmin 7vmin, rgb(17 203 215) 76vw 52vh 22vmin 7vmin, rgb(250 70 89) 46vw 86vh 26vmin 20vmin, rgb(240 255 243) 50vw 20vh 25vmin 1vmin, rgb(250 70 89) 74vw 14vh 25vmin 16vmin, rgb(240 255 243) 31vw 100vh 29vmin 20vmin }
这个工作,你可以交给 SASS、LESS 或者 JavaScript 这些能够有循环函数能力的语言去生成,它的效果大概是这样:
紧接着,通过 feTurbulence 产生分形噪声图形,使用 feDisplacementMap 进行映射置换,最后给图形叠加上这个滤镜效果。
div { filter: url(#filter); }
即可得到这样的云彩效果:
完整的代码,你可以戳这里到袁川老师的 CodePen 观看:Cloud (SVG filter + CSS)[20]
总结一下
关于 SVG 滤镜入门的第一篇总算差不多了,本文简单的介绍了一下 SVG 滤镜的使用方式以及一些常见的 SVG 滤镜并给出了最简单的一些使用效果,希望大家看完能对 SVG 滤镜有一个简单的认识。
本文罗列的滤镜效果更多的是单个效果或者很少几个组合在一起的效果,实际的使用或者应用到应用场景下其实会是更多滤镜的的组合产生出的一个效果。
后面的文章将会更加细致的去探讨分析多个 SVG 滤镜组合效果,探讨更复杂的排列组合。
文章的题目叫SVG 滤镜从入门到放弃因为 SVG 滤镜学起来确实太繁琐太累了,它不像 CSS 滤镜或者混合模式那么容易上手那么简单。当然也由于 SVG 滤镜的功能非常强大,定制化能力强以及它已经存在了非常之久有关。SVG 滤镜的兼容性也很好,它们其实是早于 CSS3 一些特殊效果之前就已经存在的。
CSS 其实一直在向 SVG 的一些特殊能力靠拢,用更简单的语法让人更易上手,不过 SVG 滤镜还是有其独特的魅力所在。后续将会有更多关于 SVG 滤镜的文章。也希望读到这里的同学不要放弃!
到此,关于“什么是 SVG 滤镜”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注创新互联网站,小编会继续努力为大家带来更多实用的文章!
新闻标题:什么是SVG滤镜
文章地址:http://myzitong.com/article/pcihde.html