box-shadow/drop-shadow/feDropShadow 投影的前世今生

栏目: 后端 · 前端 · 发布时间: 4年前

内容简介:这是在做一个呼吸灯动效时遇到的问题,就是如何给SVG的图形元素加上一些阴影的效果,比如外发光,比如内发光,比如投影,之前也有困扰,但是因为没到非解决不可的程度,所以就暂时搁置了。对于发光这种效果,对于CSS3来说,很简单的事情,一个这是直接给一个100*100的div盒子定义了外发光后的效果,为了方便修改颜色,用了hsla的色值表示方法。一个完美的外发光效果,试一下将box-shadow属性定义到动画规则中,会发生什么:

这是在做一个呼吸灯动效时遇到的问题,就是如何给SVG的图形元素加上一些阴影的效果,比如外发光,比如内发光,比如投影,之前也有困扰,但是因为没到非解决不可的程度,所以就暂时搁置了。对于发光这种效果,对于CSS3来说,很简单的事情,一个 box-shadow属性 可以解决所有问题,我曾经写过一篇关于CSS3样式的文章 UI设计师进阶技能——CSS3之样式篇 里枚举的非常全面,包括各个参数如何去和PS一一对应,不但能设置是外阴影还是内阴影,尺寸,X和Y的偏移,还可以多种效果去叠加,玩好了,当成是画图神器都是有可能的。

box-shadow的局限性

这是直接给一个100*100的div盒子定义了外发光后的效果,为了方便修改颜色,用了hsla的色值表示方法。

#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/drop-shadow/feDropShadow 投影的前世今生

一个完美的外发光效果,试一下将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/drop-shadow/feDropShadow 投影的前世今生

可以轻松实现这种透明度变化产生的“砰砰”动效。那再试一下改颜色,为了少写一个动画规则,我先不给盒子填充任何背景颜色,仅保留box-shadow效果。之所以用 hsla 色值表示方法,也是为了调整颜色方便,只要改一下h值就可以了。

/*定义一个颜色变化(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;
}
复制代码
box-shadow/drop-shadow/feDropShadow 投影的前世今生

变色也很OK,其他值的改变就不再做尝试了。

这里我试着做了一排依次按顺序点亮的信号灯效果,任意一个时刻都是四个不同的颜色。

box-shadow/drop-shadow/feDropShadow 投影的前世今生

这里,我如果想做一个圆环的外发光效果,抱歉,box-shadow属性告诉你,这是天方夜谭,因为字面意思来讲, box——盒子 ,作为盒子模型,支持的是一个整体的外观,或者称之为边缘效果。

drop-shadow滤镜的补充

drop-shadow 确切来说是滤镜 filter 的一种,还有常见的模糊滤镜blur,黑白滤镜grayscale等等,这次先只说这个投影。语法简单:

.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) ,会发现投影效果也会发生变化。

box-shadow/drop-shadow/feDropShadow 投影的前世今生

drop-shadow 滤镜是不像 box-shadow 属性那样支持多个设置叠加的,因为毕竟 filter 才是属性,所以投影的滤镜只能设置一个。但是,滤镜因为是加给实体的,不受什么盒子模型影响,所以,当我的盒子是一个描边而非填充样式时

filter: drop-shadow(0 0 8px hsla(168,90%,45%,1));
border:10px solid hsla(168,90%,45%,1);
复制代码

就能得到一个内外发光的圆环了。

box-shadow/drop-shadow/feDropShadow 投影的前世今生

这个搭配SVG可谓无往不利,比如,想给下面这种复杂的SVG图形加一个投影,直接让SVG使用定义好的滤镜就可以了。

box-shadow/drop-shadow/feDropShadow 投影的前世今生

本来就是一个普通平面的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))}
}
复制代码
box-shadow/drop-shadow/feDropShadow 投影的前世今生

依然可以得到动效。变色就不做了,也是支持的。

现在,新的需求又来了,我要给SVG中的图形元素加投影,首先声明,单个图形元素是不支持使用drop-shadow滤镜属性的,已经踩过这个坑了,那还有救没?有。

SVG量身定制的feDropShadow投影滤镜

上面的投影滤镜是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>
复制代码

这里有一些特殊的语法, dxdy 通过字面意思容易理解,就是水平和垂直的偏移距离, steDeviation 是个什么属性?来看一下MDN文档中对steDeviation的官方解释:

The stdDeviation attribute defines the standard deviation for the blur operation.

用句简单的话来解释,就是投影的尺寸。

颜色的定义,属性名为 flood-color ,同样,如果不hsla或者rgba这种自带透明度定义的色值表示方法,需要调节透明度的话,则通过 flood-opacity 属性来定义。

我使用了一个描边的圆形通过 filter:url(#outLight) 语句来调用这个滤镜,效果却并不理想:

box-shadow/drop-shadow/feDropShadow 投影的前世今生

外发光效果的实现没有问题,但很明显的看出似乎滤镜作用的区域被截取了。追本溯源来找原因,关于 <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%的溢出范围,这样就解决了外发光半径超出默认作用区域的问题。

box-shadow/drop-shadow/feDropShadow 投影的前世今生

得到完美的外发光圆环。

可以随随便便修改dx和dy的值,比如下面这种:

box-shadow/drop-shadow/feDropShadow 投影的前世今生

甚至让投影完全脱离本体

box-shadow/drop-shadow/feDropShadow 投影的前世今生

引申: filter 滤镜还能做什么

在深入了解滤镜之前,我一直把SVG定位为矢量图形,结合最多的也是平面风格的插画,但当祭出滤镜神器,突然发现,可以用SVG来让纯色填充的图形变得有质感,比如增加纹理,比如增加浮雕效果。

下面这张图片这样看真的是平淡无奇,这是我在AI中绘制的基础图形。

box-shadow/drop-shadow/feDropShadow 投影的前世今生

燃鹅,当我按照下面图层拆分后依次加上对应的滤镜效果后

box-shadow/drop-shadow/feDropShadow 投影的前世今生

)

下面,就是见证奇迹的时刻:

box-shadow/drop-shadow/feDropShadow 投影的前世今生

瞧这凹凸有致浮雕效果,瞧这底部细腻的纹理,是不是很难想象,在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一下技巧:

旋转效果

box-shadow/drop-shadow/feDropShadow 投影的前世今生

闪烁效果:

box-shadow/drop-shadow/feDropShadow 投影的前世今生

关于 <filter> 深入了解的话,应该有意思的地方还有很多,目前我能完全弄明白只有投影和模糊,等完全搞清楚之后,会来一篇单独介绍滤镜的专题。因为投影可以完全follow本体的变化,比如随便来个最简单的缩放:

box-shadow/drop-shadow/feDropShadow 投影的前世今生

另外关于利用滤镜做动效的创意,还在冥思苦想中,这又是另外一篇了。


以上所述就是小编给大家介绍的《box-shadow/drop-shadow/feDropShadow 投影的前世今生》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Windows高级调试

Windows高级调试

Mario Hewardt、Daniel Pravat / 聂雪军 / 机械工业出版社 / 2009-5 / 79.00元

本书主要讲解Windows高级调试思想和工具,并涉及一些高级调试主题。本书内容主要包括:工具简介、调试器简介、调试器揭密、符号文件与源文件的管理、栈内存破坏、堆内存破坏、安全、进程间通信、资源泄漏、同步、编写定制的调试扩展、64位调试、事后调试、Windows Vista基础以及应用程序验证器的测试设置等。本书内容详实、条理清楚。 本书适合Windows开发人员、Windows测试人员和Windo......一起来看看 《Windows高级调试》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器