TAT.simplehuang 实例CSS3开场动画的制作与优化
In Web开发 on 2016年01月05日 by view: 4,746
7

素材

图片1

期望效果http://v.youku.com/v_show/id_XMjY2NTc1MzYw.html

一开始需要制作这个动画的时候,其实我是拒绝的,因为单凭这几个素材,即便我对动画了如指掌,也是无从下手的。后来有一天,我见到了wow军团再临的CG动画,脑海中突然灵光一闪,便出现了这样的构思:

“穿越重重的云层,伴随着白天到黑夜的转化,logo从遥远的地方出现,随后往屏幕方向快速移动,在logo快要充满整个屏幕的时候星光一闪,又消逝在远方…” 

于是我开始了开场动画的坎坷历程。

 

 

云层制作

        云层的制作耗时比较久,期间参阅了网上一些使用CSS模拟云层的博文及示例,下面列出两个比较好的示例:

        移动的云https://codepen.io/montanaflynn/pen/orxwK

        3D云https://www.clicktorelease.com/blog/how-to-make-clouds-with-css-3d

        实际上使用单图片来模拟云层会有一些体验问题,比如,当我们试图穿过一片图片生成的云时,会感觉一下就没了,对用户而言会产生一定的视觉落差,而真实的云层是一片区域,所以一片云我使用了5张图片转换方向来生成,这样在三维的场景下我们的云就有了充实感。

        下面引用一段Jaume Sanchez Elias写的3D云的生成代码:

        通过上面的方法去输出云层,我们便拥有了质感较强的云。而为了让动画的加载更快一些,我将生成的云层以固定DOM的形式写在页面中,让前期的JS消耗尽量减小,并且图片的加载会在页面加载之初进行。在有了云层DOM后,便可以开始着手穿越云层效果的制作了,穿越过程里还夹带了从白天到黑夜的背景色变化效果,这个穿越的动作我使用translateZ属性来实现,让屏幕随着时间往前推进,完成穿越云层的效果,代码实现如下(这里仅展示webkit版本代码):

 

 星光及logo:

        logo及星光的呈现过程是一个放大及放更大/缩小的过程,通过改变它的scale可以实现,实现如下:

 

性能优化:

       由于在测试中发现动画的性能是一个比较大的问题,在一些配置比较低的机器会有很多掉帧,卡顿的现象,因此需要进行性能方面的优化。

QQ图片20151205192413

        我使用chrome里面的工具Timeline进行了动画执行性能检查,从中发现,在动画执行周期内,渲染及重绘耗费的资源比较多,并且期间JS也占用了一些资源,于是我首先回头查看了我的动画加载函数

        于是它变成了这样纸:

        这里我把setTimeout函数移除掉,使用animation-delay来接替setTimeout的位置,多个DOM操作被合并成了一个,把JS的消耗影响尽量降到最低。动画的声音播放使用webkitAnimationStart事件来监听,使音乐与动画的进行同步(这里需要注意webkitAnimationEnd/webkitAnimationStart的使用,每一个子节点的动画开始结束都会触发这个事件,需要判断一下animationName 确定是否是自己需要的动画事件),接下来我再次使用Timeline进行检查:

QQ图片20151205141127

 

        可以看到,在动画执行期间,从云层开始帧数就一直不高,结合此前的渲染重绘时间占用率过高,初步定为CSS属性使用不当。于是我查阅了CSS动画中所使用的属性:

QQ图片20151205141530 QQ图片20151205150505

        根据Timeline掉帧的时间片段,结合这个时间段内产生作用的CSS属性,将一些可能影响性能的属性标记了出来,并进行了排除试验,我们发现,blur是损耗性能的主要因素,于是我对CSS做了一次排除优化,将blur,重复或不必要的属性进行剔除。

 

优化结果:

        多次优化后,通过Timeline得到了下面的结果,我们可以看到,除了页面加载之初的一些掉帧,后面基本平稳在60帧,期间的无帧数是因为动画固定在logo处停了3s左右。

QQ图片20151205192417

        在线示例:  http://huangxingbang.github.io/openSense/cloud.html

        

总结:

        1.动画尽量使用opacity/translate/rotate /scale 这些可以让GPU分担工作的属性。
        2.摈弃setTimeout在动画中的控制,动画播放时机的控制使用animation-delay来实现,如果需要精准控制,使用RequestAnimationFrame对动画进行更新。
        3.使用webkitAnimationStart/webkitAnimationEnd对动画并行的任务进行开始/结束控制。

参考资料:

       前端性能优化(CSS动画篇):https://segmentfault.com/a/1190000000490328

       高性能 CSS3 动画:https://www.qianduan.net/high-performance-css3-animations/

原创文章转载请注明:

转载自AlloyTeam:http://www.alloyteam.com/2016/01/css3995527/

  1. 那个谁 2016 年 1 月 27 日

    帅,学到了动画优化的方法

  2. 林贞恩 2016 年 1 月 25 日

    顶也~~~

  3. 韩懿莹 2016 年 1 月 23 日

    既然看了,顶一个吧,好文章

  4. xiaowie 2016 年 1 月 13 日

    帅~[嘻嘻]

  5. 流氓兔ジ 2016 年 1 月 12 日

    赞,太帅了

  6. liping 2016 年 1 月 8 日

    漂亮

  7. 实例CSS3开场动作的制作与优化 | 匠仓科技 2016 年 1 月 6 日

    […]    转自AlloyTeam:http://www.alloyteam.com/2016/01/css3995527/ […]

发表评论