实现了一个百度首页的彩蛋——CSS3 Animation简介
在百度搜索中有这样一个彩蛋:搜索“旋转”,“跳跃”,“反转”等词语,会出现相应的动画效果(搜索“反转”后的效果)。查看源码可以发现,这些效果正是通过CSS3的animation属性实现的。
实现这个彩蛋
简单来说可以分三步:
1.实现一些css动画类,等待调用;
2.设立关键字与动画匹配方法;
3.每当页面加载完成,根据关键字为body添加指定动画类。
CSS3 Animation
animation: name duration timing-function delay iteration-count direction;
上面的式子是动画声明的缩写形式。一条CSS规则中只能有一条动画声明,如果多次声明,后者会覆盖前者。一个缩写的动画声明由上述几个部分组成,含义如下表所示(摘自W3School):
值 | 描述 |
---|---|
animation-name | 规定需要绑定到选择器的 keyframe 名称。 |
animation-duration | 规定完成动画所花费的时间,以秒或毫秒计。 |
animation-timing-function | 规定动画的速度曲线。 |
animation-delay | 规定在动画开始之前的延迟。 |
animation-iteration-count | 规定动画应该播放的次数。 |
animation-direction | 规定是否应该轮流反向播放动画。 |
animation-duration设置动画的持续时间,单位可以为s或ms,不可为负值,需要注意的是其默认值为0,在创立一条动画声明时,属性值中必须设置持续时间,否则动画不会执行。
animation-timing-function表示动画的运动方式,可以使用ease-in,ease-in-out等关键字,也可以通过cubic-bezier()函数自定义运动曲线,或者使用step()函数来做一个逐帧动画。默认值为ease。
animation-delay的值可正可负,单位可以设置为s或ms,默认值为0(立即开始)。
animation: 5s ease 1000ms normal none 1 myanimate;/*延迟1s开始*/ animation: 5s ease 2s normal none 1 myanimate;/*延迟2s开始*/ /*立即开始但起始位置为原动画开始后1s处*/ animation: 5s ease -1s normal none 1 myanimate; /*开始位置大于等于动画时常,快速切换到动画结束状态*/ animation: 5s ease -5s normal none 1 myanimate;
animation-iteration-count规定动画重复次数,可以设置为一个正整数或者关键字infinite,表示此动画应该重复播放无限次。默认值为1。
animation-direction设置动画的播放方向,常用的几个属性如normal表示动画按正常播放,reverse表示动画按反向播放,alternate表示动画在奇数次(1、3、5...)正向播放,在偶数次(2、4、6...)反向播放。默认值为normal。
在书写时,上述的animation的属性顺序可以错乱,可以不写某个值,浏览器会自动识别出相应的属性值。
animation:demo 1s ease-in-out 10;
animation:10 ease-in-out demo 1s;
上面两条CSS声明都表示动画名demo以ease-in-out方式连续执行10次,每次持续1s。
此外,animation还有两个属性值,animation-fill-mode规定了动画结束时的状态:可以设置动画保持最后时的状态或还原到最初时的状态。查看DEMO:animation-fill-mode DEMO;animation-play-state规定了动画当前的状态,如果不进行设置,不管动画播放中、播放完或delay时,此属性值均为“running”。假如animation-duration的值为5s,animation-delay的值为2s,则这个动画在这7s前后及7s中的animation-play-state值均为running。在动画播放或delay时,可以使用JavaScript修改此属性为“paused”将动画暂停,这意味着假如一个动画延迟10s执行,我们在delay到第8s时将动画暂停,2s后再将动画播放,此动画仍然会继续delay2s后再开始播放。查看DEMO:CSS3动画暂停与播放。
上面提到animation有一个animation-name属性,表示动画的名称。在CSS中,所有的动画都是通过keyframes(关键帧)来定义的,我们不必定义动画每帧的效果,而是定义几个关键帧的状态即可,浏览器会根据定义的少数几个关键帧渲染出流畅的动画效果。
例如,一个keyframes可以这样来定义:
@keyframes animation-name { 0% { /*注意0%后面没有冒号*/ transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
0%和100%还可以分别使用关键字from和to来描述。如果多个关键帧的效果相同,还可以像这样将它们写在一起:
@keyframes animation-name { from,to { transform: rotate(0deg); } 50% { transform: rotate(360deg); } }
一个keyframes,可以被多条动画声明同时使用。
一条动画声明,可以同时使用多个不同的keyframes。
假如有两个keyframes的名称分别为key1和key2,这样的动画声明是合法的:
animation: key1 20s , key2 .5s ;
两个关键帧都会生效。DEMO:两个keyframes生成的文字输入动画。
总结
我们可以在keyframes中更改元素任何CSS可控的属性,也可以让多个元素动画效果串联起来,这样便可以实现非常绚丽的视觉效果。下面有两个例子,展示了CSS3动画的实用和魅力。
1.网站css4-selectors.com的loading效果。
CSS3动画的优点这么多,接下来我们将它与JavaScript动画相比,谈谈其主要缺点,以便在实际运用中和JavaScript动画各取所长,在合适的时机使用合适的方法。
1.浏览器兼容性差。有的浏览器需要加专属前缀,本文中所有的demo需要在最新版现代浏览器及IE10+下查看,而JavaScript动画大多时候没有兼容性问题。Can I Use CSS3 Animation?
2.交互性差或无交互性。CSS动画只能按照定义好的关键帧一步步进行,或者使用伪类进行鼠标悬浮等简单交互,事实上交互本来就不是CSS的范畴。
3.粗粒度的动画控制。与JavaScript毫秒级的动画控制相比,CSS3的keyframes控制无疑是相当的粗粒度的,你无法单独控制元素的尺寸、位置和旋转,这些控制被统统塞到了transfrom一个属性里。你也无法在动画运行时改变或控制一些东西,例如改变动画方向,寻找特定的时间点,或者绑定回调函数做一些其它事情。
4.声明无法复用。假如两个动画仅仅是数值不同,但是控制的对象完全相同,你仍然需要重新书写一遍keyframes。尽管现代开发中可以利用sass等手段减少代码书写,但这并不影响生成后的css文件代码重复率很高。
5.有些效果无法实现。例如复杂的缓动曲线,基于物理的动作等无法通过CSS3动画实现。
在我之前一篇博客《JavaScript动画知多少?》中,曾将CSS动画与JavaScript动画相比,文中提到CSS3动画可以启用硬件加速,事实上这种说法并不严谨。
首先,用一个3D特性的触发器(比如translate3d()
或者matrix3d()
)来让浏览器为这个元素开辟一个GPU层,就可以让JavaScript动画同样使用GPU加速;其次,不是所有的CSS属性在CSS3动画中都能够获得GPU加速,事实上大多数是不能的。
一些简单的动画效果利用CSS3来实现比JavaScript要方便很多,而一些较新的JavaScript动画库例如GSAP与CSS3的动画性能相比有过之而无不及,并且还能克服上述几个CSS3动画的缺点。
我们好像都无法免俗,经常将CSS3动画与JavaScript动画相比,试图分个孰优孰劣。事实上认清两者各自的优缺点后,根据实际需求选择合适的方案才是最重要的(听起来是废话,但真的无法反驳)。
上述的比较部分引自css-tricks上的一篇文章,虽然我认为有的缺点过于牵强,但我还是把它列举了出来。比如说交互性和动画控制,CSS本身是一个为了排版和样式而存在标记性语言,它与负责交互的编程语言JavaScript应该是相辅相成的,如果把JavaScript可以做到的事情而CSS做不到的事情当作CSS的缺陷,那么恐怕难以服众。吴双Orange翻译了这篇文章并发布在他的GitHub博客中,感兴趣的人可以继续阅读:消除疑问:CSS动画 VS JavaScript。
(完)