实现了一个百度首页的彩蛋——CSS3 Animation简介

  在百度搜索中有这样一个彩蛋:搜索“旋转”,“跳跃”,“反转”等词语,会出现相应的动画效果(搜索“反转”后的效果)。查看源码可以发现,这些效果正是通过CSS3的animation属性实现的。

实现这个彩蛋

  简单来说可以分三步:

  1.实现一些css动画类,等待调用;

  2.设立关键字与动画匹配方法;

  3.每当页面加载完成,根据关键字为body添加指定动画类。

  查看DEMO:百度搜索彩蛋

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 DEMOanimation-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效果

  2.A pen by webzhao:花瓣的展开

  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

  (完)

上一篇:ASP.NET Web API的Controller是如何被创建的?


下一篇:C# First and FirstOrDefault 方法详解