这是在作一个呼吸灯动效时遇到的问题,就是如何给SVG的图形元素加上一些阴影的效果,好比外发光,好比内发光,好比投影,以前也有困扰,可是由于没到非解决不可的程度,因此就暂时搁置了。对于发光这种效果,对于CSS3来讲,很简单的事情,一个box-shadow属性能够解决全部问题,我曾经写过一篇关于CSS3样式的文章UI设计师进阶技能——CSS3之样式篇里枚举的很是全面,包括各个参数如何去和PS一一对应,不但能设置是外阴影仍是内阴影,尺寸,X和Y的偏移,还能够多种效果去叠加,玩好了,当成是画图神器都是有可能的。css
这是直接给一个100*100的div盒子定义了外发光后的效果,为了方便修改颜色,用了hsla的色值表示方法。html
#box{
height:100px;
width:100px;
background: hsla(168,90%,45%,1);
border-radius: 50px;
box-shadow:0 0 70px hsla(168,90%,45%,1);
}
复制代码
一个完美的外发光效果,试一下将box-shadow属性定义到动画规则中,会发生什么:动画
/*定义一个透明度变化(hsla的a值改变)动画规则*/
@keyframes outLight{
0%{box-shadow:0 0 70px hsla(168,90%,45%,1)}
100%{box-shadow:0 0 70px hsla(168,90%,45%,0.1)}
}
#box {
height:100px;
width:100px;
background: hsla(168,90%,45%,1);
border-radius: 50px;
animation: outLight 1s ease infinite;
}
复制代码
能够轻松实现这种透明度变化产生的“砰砰”动效。那再试一下改颜色,为了少写一个动画规则,我先不给盒子填充任何背景颜色,仅保留box-shadow效果。之因此用hsla色值表示方法,也是为了调整颜色方便,只要改一下h值就能够了。ui
/*定义一个颜色变化(hsla的h值改变)动画规则*/
@keyframes outLight{
0%{box-shadow:0 0 70px hsla(168,90%,45%,1)}
100%{box-shadow:0 0 70px hsla(220,90%,45%,1)}
}
#box {
height:100px;
width:100px;
border-radius: 50px;
animation: outLight 0.7s linear alternate infinite;
}
复制代码
变色也很OK,其余值的改变就再也不作尝试了。url
这里我试着作了一排依次按顺序点亮的信号灯效果,任意一个时刻都是四个不一样的颜色。spa
这里,我若是想作一个圆环的外发光效果,抱歉,box-shadow属性告诉你,这是天方夜谭,由于字面意思来说,box——盒子,做为盒子模型,支持的是一个总体的外观,或者称之为边缘效果。设计
drop-shadow
确切来讲是滤镜filter
的一种,还有常见的模糊滤镜blur,黑白滤镜grayscale等等,此次先只说这个投影。语法简单:3d
.box {
height:100px;
width:100px;
border-radius:50px;
/*filter:drop-shadow 滤镜*/
filter: drop-shadow(0 0 30px hsla(168,90%,45%,1));
background-color: hsla(168,90%,45%,1);
}
复制代码
也能够获得一个完美的外发光效果,但这里有个很大的坑,就是会受元素填充颜色的影响,好比,改掉背景颜色的透明度background-color: hsla(168,90%,45%,0.2)
,会发现投影效果也会发生变化。code
drop-shadow
滤镜是不像box-shadow
属性那样支持多个设置叠加的,由于毕竟filter
才是属性,因此投影的滤镜只能设置一个。可是,滤镜由于是加给实体的,不受什么盒子模型影响,因此,当个人盒子是一个描边而非填充样式时cdn
filter: drop-shadow(0 0 8px hsla(168,90%,45%,1));
border:10px solid hsla(168,90%,45%,1);
复制代码
就能获得一个内外发光的圆环了。
这个搭配SVG可谓无往不利,好比,想给下面这种复杂的SVG图形加一个投影,直接让SVG使用定义好的滤镜就能够了。
原本就是一个普通平面的SVG图形,加了filter="drop-shadow(0 10px 5px hsla(168,0%,45%,0.4))"
的定义后,瞬间跃然纸上。并且投影的边缘彻底就是图形的边缘,这但是box-shadow
属性无能为力的事情。
来试一下对动画的支持。
/*定义一个投影效果透明度变化(hsla的a值改变)动画规则*/
@keyframes outLight{
0%{filter: drop-shadow(0 0 10px hsla(168,90%,45%,1))}
100%{filter: drop-shadow(0 0 10px hsla(168,90%,45%,0.1))}
}
复制代码
依然能够获得动效。变色就不作了,也是支持的。
如今,新的需求又来了,我要给SVG中的图形元素加投影,首先声明,单个图形元素是不支持使用drop-shadow滤镜属性的,已经踩过这个坑了,那还有救没?有。
上面的投影滤镜是CSS的filter属性,只能把SVG当成一个图片元素总体来处理,终极目标来着,SVG+CSS3的动画对不对?这须要把SVG里面的图形元素单独属性赋值。SVG强大的<def>
元素可让这一切都变成现实。咱们要作的就是,首先定义一个id为outLight滤镜,语法以下:
<defs>
<filter id="outLight">
<!-- 定义了一个水平和垂直偏移距离为0,大小为10的外发光效果 -->
<feDropShadow dx="0" dy="0" stdDeviation="10" flood-color="hsla(180,90%,40%,0.9)" />
</filter>
</defs>
复制代码
这里有一些特殊的语法,dx和dy经过字面意思容易理解,就是水平和垂直的偏移距离,steDeviation是个什么属性?来看一下MDN文档中对steDeviation的官方解释:
The stdDeviation attribute defines the standard deviation for the blur operation.
用句简单的话来解释,就是投影的尺寸。
颜色的定义,属性名为flood-color,一样,若是不hsla或者rgba这种自带透明度定义的色值表示方法,须要调节透明度的话,则经过flood-opacity属性来定义。
我使用了一个描边的圆形经过filter:url(#outLight)
语句来调用这个滤镜,效果却并不理想:
外发光效果的实现没有问题,但很明显的看出彷佛滤镜做用的区域被截取了。追本溯源来找缘由,关于<filter>
滤镜的属性值这样写道:
The position and dimensions of a filter may be specified using the following parameters: x, y, width, height. The default values are:
- x: -10%
- y: -10%
- width: 120%
- height: 120%
简而言之,就是滤镜默认做用范围为使用元素溢出10%,在上面这个案例中,由于发光的范围较大,显然10%的溢出是不够的,既然默认值不合理,那就从新定义一下
<filter id="outLight" x="-50%" y="-50%" width="200%" height="200%">
复制代码
这样的话,我给到了200%的溢出范围,这样就解决了外发光半径超出默认做用区域的问题。
获得完美的外发光圆环。
能够随随便便修改dx和dy的值,好比下面这种:
甚至让投影彻底脱离本体
filter
滤镜还能作什么在深刻了解滤镜以前,我一直把SVG定位为矢量图形,结合最多的也是平面风格的插画,但当祭出滤镜神器,忽然发现,能够用SVG来让纯色填充的图形变得有质感,好比增长纹理,好比增长浮雕效果。
下面这张图片这样看真的是平淡无奇,这是我在AI中绘制的基础图形。
燃鹅,当我按照下面图层拆分后依次加上对应的滤镜效果后
下面,就是见证奇迹的时刻:
瞧这凹凸有致浮雕效果,瞧这底部细腻的纹理,是否是很难想象,在SVG中不过是下面这两句滤镜定义来实现的:
<!-- 给底层增长噪点效果的滤镜 -->
<filter filterUnits="objectBoundingBox" id="noise">
<feTurbulence baseFrequency="0.5" id="c2" in="c1" numOctaves="10" result="c2" stitchTiles="noStitch" type="fractalNoise">
</feTurbulence>
<feComposite in="c2" in2="SourceAlpha" operator="in"></feComposite>
</filter>
<!-- 模糊滤镜 顶部高光和底部阴影均可以使用 -->
<filter id="blur">
<feGaussianBlur in="SourceGraphic" stdDeviation="5" />
</filter>
复制代码
放几个最终的效果来show一下技巧:
旋转效果
闪烁效果:
关于<filter>
深刻了解的话,应该有意思的地方还有不少,目前我能彻底弄明白只有投影和模糊,等彻底搞清楚以后,会来一篇单独介绍滤镜的专题。由于投影能够彻底follow本体的变化,好比随便来个最简单的缩放:
另外关于利用滤镜作动效的创意,还在左思右想中,这又是另一篇了。
- 经过
<defs> <filter><feDropShadow ……/> </filter> </defs>
的语法来定义一个投影效果的滤镜。- 默认
<filter>
的做用范围为10%的溢出,当投影尺寸大时,须要修改x、y、width、height的值。