H5动画之补间动画

by rancui

什么是动画


动画本质上是图像按照事先设定好的顺序在一定的时间内的图像序列变化运动。

什么是补间动画


看一下百度百科的定义

补间动画指的是做flash动画时,在两个关键帧中间需要做“补间动画”,才能实现图画的运动;插入补间动画后两个关键帧之间的插补帧是由计算机自动运算而得到的。

在触屏页面中,常见的实现补间动画以下几种形式:

第一,CSS3 Animation。

通过animation(除steps()以外的时间函数)属性在每个关键帧之间插入补间动画。
animation属性结合自定义动画@keyframes的使用,改变元素的相应属性制作动画效果。

animation主要常用的属性:

  • animation-name: @keyframes 动画的名称;
  • animation-duration: 动画完成的时间;
  • animation-timing-function: 动画的速度曲线(linear,ease,ease-in,cubic-bezier(n,n,n,n));
  • animation-delay: 动画何时开始;
  • animation-iteration-count: 动画被播放的次数,默认是1(n,infinite)
  • animation-direction: 规定是否应该轮流反向播放动画。
  • animation-play-state: 动画处于播放或则暂停状态(paused,running);

第二,CSS3 Transition

  • transition-property: 指定CSS属性的name,transition效果
  • transition-duration: transition效果需要指定多少秒或毫秒才能完成
  • transition-timing-function : 指定transition效果的转速曲线
  • transition-delay: 定义transition效果开始的时候
请把鼠标指针放到黄色的 div 元素上,来查看过渡效果。

区别于animation,transition只能设定初始和结束时刻的两个关键帧状态。

第三,利用JavaScript实现动画

例如JavaScript动画库或框架,著名的有TweenJSVelocity.js

第四,SVG 动画。

基于移动端对SVG技术的友好的支持性,利用SVG技术实现动画也是一种可行的方案。

对于利用Transition实现的动画而言,是有一定局限的。

transition的优点在于简单易用,但是它有几个很大的局限。
(1)transition需要事件触发,所以没法在网页加载时自动发生。
(2)transition是一次性的,不能重复发生,除非一再触发。
(3)transition只能定义开始状态和结束状态,不能定义中间状态,也就是说只有两个状态。
(4)一条transition规则,只能定义一个属性的变化,不能涉及多个属性。

由于这样的局限,在触屏页面中很少见到Transition动画的身影,但是并不意味着没有,譬如翻页动画的实现可以利用Javascript脚本配合transition与transform属性来实现。

案例截图来源于《京东:2015JDC燃爆事件》

《京东:2015JDC燃爆事件》截图

对应的 Chrome Dev Tool 代码调试截图

《京东:2015JDC燃爆事件》Chrome Dev Tool 代码调试截图

所以,利用CSS3实现动画的重头戏都在于Animation的运用。
然而想写好CSS3 Animation动画需要花费一些力气,这是看似简单实则需要把握好细节的活儿。

动画过程要预先规划好,这可不是是敲敲脑壳就能码出来的事儿。

可以是一张把与设计师沟通的结果加之分析输出一张动画属性分解表。

动画属性分解表示例

《动画属性分解表示例》

又或者是根据沟通分析规划出来的动画时间轴。

动画时间轴

《动画时间轴示例》

动画要自然不生硬,十二法则你值得拥有

不管是在影视动画界,还是前端动画界里遵循的都是同一套配方,追求同样的味道——「迪士尼九老」总结的十二黄金动画法则(以下简称“十二法则”),一直沿用至今、备受推崇不是没有道理的。

在一些优秀的触屏页面案例里,可以追寻到它的踪迹。

案例截图来源于《腾讯:微众银行》中的摩托车demo

《腾讯:微众银行》截图
《腾讯:微众银行》截图

作者对轮子和摩托车的处理就体现出“挤压和拉伸”的法则,带出颠簸的现实感。

非常推荐大家去认真研究这个案例的,因为作者陈在真就此说明过他的这部作品就完全是遵循迪士尼动画十二原则所码出来的。

但是很可惜,案例已经下线了。

不过,你还可以欣赏到另一位对迪士尼十二法则同样有心得的大神EC的作品《拍拍小店全新上线》

案例截图来源于《拍拍小店全新上线》

《拍拍小店全新上线》截图1
《拍拍小店全新上线》截图1

盒子的打开过程就带有一个往上展开预备动作(ANTICIPATION),并且展开撒开的碎彩纸带有慢出(SLOW OUT)的效果,拍拍小店的logo弹出符合弧形(ARCS)的运动轨迹。

《拍拍小店全新上线》截图1
《拍拍小店全新上线》截图1

除此之外弧形运动轨迹最为明显的地方就是页面切换的过程。

整个案例处处都非常生动自然、利落感满满,令人赞叹。

另外,在把控十二法则时为了动画更加自然,时间函数(animation-timing-function)的设计绝对是举足轻重的一环,因为动画可以说是一种关于时间函数的运动演变过程。

码好了动画,做好了页面,以为就此结束了吗?不要太天真,移动端对性能的要求也是一道需要迈过的坎儿。

Google在有关动画性能渲染优化的文章《动画 | Web Fundamentals - Google Developers》(对不起,这里有道墙)中提出建议:

避免为开销大的属性设置动画,要让每次在设置动画时必须注意保持 60fps。

那么,哪些是开销大的属性呢?
(下面是科普环节,清楚的童鞋可以跳过)。

页面渲染的一般过程为JS > CSS > 计算样式 > 布局 > 绘制 > 渲染层合并。

《页面渲染的一般过程》

其中,Layout(重排)和Paint(重绘)是整个环节中最为耗时的两环,所以我们尽量避免着这两个环节。从性能方面考虑,最理想的渲染流水线是没有布局和绘制环节的,只需要做渲染层的合并即可。

《页面渲染的一般过程》

那怎么知道哪些CSS属性的改变是会影响这两个环节的呢?诺,下面就是各CSS属性与其影响的环节。

截图来源于CSS Triggers,更为详细地翻墙去拿吧

《各种CSS属性影响的渲染环节》

在实际的应用里,最为简单的一个注意点就是,触发动画的开始不要用diaplay:none属性值,因为它会引起Layout、Paint环节,通过切换类名就已经是一种很好的办法。

1
2
3
4
5
6
7
8
9
10
11
12
// 根据类名触发动画
.active {
&.flow_away {
.mobile,
.ground,
.platform,
.words {
-webkit-animation: flowAwayUp ease .5s forwards;
animation: flowAwayUp ease .5s forwards;
}
}
}

还有就是,translate属性值来替换top/left/right/bottom的切换,scale属性值替换width/height,opacity属性替换display/visibility等等。

总结来源于@登平登平的《H5动画60fps之路》

《H5动画60fps之路》

最后总结下要点就是

  • 事先做好规划
  • 码的时候注意十二法则
  • 谨记避免导致layout/paint的属性