SVG 滤镜与 css 滤镜类似,是 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() 。
我们需要使用 <defs> 和 <filter> 标签来定义一个 SVG 滤镜。
通常所有的 SVG 滤镜元素都需要定义在 <defs> 标记内。
现在,基本上现代浏览器,即使不使用 <defs> 包裹 <filter>,也能够定义一个 SVG 滤镜。
这个 <defs> 标记是 definitions 这个单词的缩写,可以包含很多种其它标签,包括各种滤镜。
其次,使用 <filter> 标记用来定义 SVG 滤镜。 <filter> 标签需要一个 id 属性,它是这个滤镜的标志。SVG 图形使用这个 id 来引用滤镜。
看一个简单的 DEMO:
<div class="cssFilter"></div>
<div class="svgFilter"></div>
<svg>
<defs>
<filter id="blur">
<feGaussianBlur in="SourceGraphic" stdDeviation="5" />
</filter>
</defs>
</svg>
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) 实现了一个类似的滤镜,方便比较,结果图如下:
嘿,可以看到,使用 SVG 的模糊滤镜,实现了一个和 CSS 模糊滤镜一样的效果。
上文的例子中使用了 filter: url(#blur) 这种模式引入了一个 SVG 滤镜效果,url 是 CSS 滤镜属性的关键字之一,url 模式是 CSS 滤镜提供的能力之一,允许我们引入特定的 SVG 过滤器,这极大的增强 CSS 中滤镜的能力。
相当于所有通过 SVG 实现的滤镜效果,都可以快速的通过 CSS 滤镜 URL 模式一键引入。
和 CSS 滤镜一样,SVG 滤镜也是支持多个滤镜搭配混合使用的。
所以我们经常能看到一个 <filter> 标签内有大量的代码。很容易就懵了~
再来看个简单的例子:
<div></div>
<svg>
<defs>
<!-- Filter declaration -->
<filter id="MyFilter">
<!-- offsetBlur -->
<feGaussianBlur in="SourceAlpha" stdDeviation="5" result="blur" />
<feOffset in="blur" dx="10" dy="10" result="offsetBlur" />
<!-- merge SourceGraphic + offsetBlur -->
<feMerge>
<feMergeNode in="offsetBlur" />
<feMergeNode in="SourceGraphic" />
</feMerge>
</filter>
</defs>
</svg>
div {
width: 200px;
height: 200px;
background: url(xxx);
filter: url(#MyFilter);
}
我们先来看看整个滤镜的最终结果,结果长这样:
CSS 可能一行代码就能实现的事情,SVG 居然用了这么多代码。(当然,这里 CSS 也不好实现,不是简单容器的阴影,而是 PNG 图片图形的轮廓阴影)
首先看这一段:
<!-- offsetBlur -->
<feGaussianBlur in="SourceAlpha" stdDeviation="5" result="blur" />
<feOffset in="blur" dx="10" dy="10" result="offsetBlur" />
首先 <feGaussianBlur in="SourceAlpha" stdDeviation="5" result="blur" /> 这一段,我们上面也讲到了,会生成一个模糊效果,这里多了一个新的属性 result='blur',这个就是 SVG 的一个特性,不同滤镜作用的效果可以通过 result 产出一个中间结果(也称为 primitives 图元),其他滤镜可以使用 in 属性导入不同滤镜产出的 result,继续操作。
紧接着,<feOffset> 滤镜还是很好理解的,使用 in 拿到了上一步的结果 result = 'blur',然后做了一个简单的位移。
这里就有一个非常重要的知识点:在不同滤镜中利用 result 和 in 属性,可以实现在前一个基本变换操作上建立另一个操作,比如我们的例子中就是添加模糊后又添加位移效果。
结合两个滤镜,产生的图形效果,其实是这样的:
实际效果中还出现了原图,所以这里我们还使用了 <feMerge> 标签,合并了多个效果。也就是上述这段代码:
<!-- merge SourceGraphic + offsetBlur -->
<feMerge>
<feMergeNode in="offsetBlur" />
<feMergeNode in="SourceGraphic" />
</feMerge>
feMerge 滤镜允许同时应用滤镜效果而不是按顺序应用滤镜效果。利用 result 存储别的滤镜的输出可以实现这一点,然后在一个 <feMergeNode> 子元素中访问它。
整体再遵循后输入的层级越高的原则,最终得到上述结果。示意流程图如下:
至此,基本就掌握了 SVG 滤镜的工作原理,及多个滤镜如何搭配使用。接下来,只需要搞懂不同的滤镜能产生什么样的效果,有什么不同的属性,就能大致对 SVG 滤镜有个基本的掌握!
上面大致过了一下 SVG 滤镜的使用流程,过程中提到了一些属性,可能也漏掉了一些属性的讲解,本章节将补充说明一下。
有一些属性是每一个滤镜标签都有,都可以进行设置的。
属性 | 作用 |
---|---|
x, y | 提供左上角的坐标来定义在哪里渲染滤镜效果。 (默认值:0) |
width, height | 绘制滤镜容器框的高宽(默认都为 100%) |
result | 用于定义一个滤镜效果的输出名字,以便将其用作另一个滤镜效果的输入(in) |
in | 指定滤镜效果的输入源,可以是某个滤镜导出的 result,也可以是下面 6 个值 |
SVG filter 中的 in 属性,指定滤镜效果的输入源,可以是某个滤镜导出的 result,也可以是下面 6 个值:
in 取值 | 作用 |
---|---|
SourceGraphic | 该关键词表示图形元素自身将作为 <filter> 原语的原始输入 |
SourceAlpha | 该关键词表示图形元素自身将作为 <filter> 原语的原始输入。SourceAlpha 与 SourceGraphic 具有相同的规则除了 SourceAlpha 只使用元素的非透明部分 |
BackgroundImage | 与 SourceGraphic 类似,但可在背景上使用。 需要显式设置 |
BackgroundAlpha | 与 SourceAlpha 类似,但可在背景上使用。 需要显式设置 |
FillPaint | 将其放置在无限平面上一样使用填充油漆 |
StrokePaint | 将其放在无限平面上一样使用描边绘画 |
来自:https://github.com/chokcoco/cnblogsArticle/issues/27
设备间不同的屏幕尺寸、分辨率和比例使得产品难以提供一致的体验,对于那些对产品有着像素级完美追求的人这种体验差异尤其显著! SVG(可缩放的矢量图形)完美地解决了上文中提到的部分问题。
安装svg-sprite-loader。通过vue-cli脚手架创建的项目默认情况下会使用 url-loader 对svg进行处理,在static下新建svg文件夹,用来放置当做icon使用的svg,使用include,include和img做区分。然后修改webpack.base.conf.js配置,这样svg-sprite-loader只会处理我们指定的static/svg下的文件
引入 svg-sprite-loader 插件,vue-cli项目默认情况下会使用 url-loader 对svg进行处理,会将它放在/img 目录下,所以这时候我们引入svg-sprite-loader 会引发一些冲突。使用 webpack 的 exclude和 include
一般的解决办法有:1.字体图标改变css的color属性;2.js在hover事件中切换图片;3.老一点的方案是hover切换背景?但是为了更小的开销,一般css为更好的解决方案
SVG就存在了,但仍有一些有趣的方法去用它。在本教程中,重点将放在 SVG 的过滤器上 —— 但不只是将它们应用于 SVG 图像,我将向你展示如何将它们应用于任何常规页面的内容上。实际上我们是通过告诉 CSS 过滤器所拥有的 ID,然后再把过滤器应用于 SVG 的方式来实现。
学习如何使用D3.js来创建这些图形?这里会包括前面例子中的SVG基础图形以及如何使用D3.js设置图形的属性。使用D3.js画一个SVG 的 圆 circle,可以使用如下代码创建:
在使用生成的svg图作为<img>标签是src值时,发现有部分浏览器显示异常,所以这里记录下,在<img src=\\\"Data URLs\\\">中,Data URLs格式与显示情况如下:
CSS3的clip-path,这个clip-path看起来有点眼熟,因为它原本就存在于SVG里头,利用掩码(剪裁)的方法,连接坐标绘制掩码区域,就可以做出许多不同的形状,让底色或底图显现,随着浏览器对于CSS3的支持度大幅提升
从最开始的使用img图片,到后来的使用css sprite来减少服务器请求,再到流行的图形字体化图标Iconfont。现在,一种全新的图标使用方式开始流行了起来——SVG symbols图标。
svg中可以通过foreignObject嵌入html,展示更丰富的样式。当需要给这中间的html绑定事件的时候,不管是使用委托和直接查询元素进行绑定的时候都无法生效。右键检查元素也检查不到具体的元素
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!