常常听到一些同学问起为什么别人的动画看起来平滑流畅 ,而自己做出来却效果平平,完全没有那种丝般润滑的感觉。

答案是动画缺少了灵魂,这个灵魂就是缓动函数。缓动函数是用来描述数值的变化速率,这些数值可以是动画对象的宽高,透明度,旋转,缩放等属性值,它们的变化率可以用函数曲线来表示。理解缓动函数可以让我们制作出更加符合直觉的UI动效,是学习css和svg动画必须掌握的知识。

想象一下我们生活中的一些现象,从被拍打弹跳的蓝球,缓缓停靠的地铁,到空中飘落的树叶,它们运动的速率都是曲线,而不是一成不变的直线,曲线变化更符合人的感官直觉,而匀速变化往往让人感到沉闷。

缓动函数的曲线表达

缓动函数在SVG中的应用

在svg中使用缓动函数,要使用keySplines属性,下面是MDN网站对该属性的解释。

keySplines属性定义了一个与keyTimes列表相关的一组贝塞尔控制点,定义了一个控制间隔速率的三次贝塞尔函数。属性值是分号分隔的控制点描述列表。每个控制点描述是一个四元组:x1 y1 x2 y2,它们描述一个时间段的贝塞尔控制点。定义关联段的keyTimes值是贝塞尔的 “锚点”,keySplines值是控制点。因此,控制点的数量必须少于一个keyTimes。

简单地说,我们需要用两个贝塞尔控制点生成前面提到的曲线。举个栗子,下面是我们在典型的图文伸长动画中的一段代码:

<animate 
  attributeName="height" 
  begin="click" 
  dur="10000s" 
  calcMode="spline" 
  keySplines="0.5 0 0.5 1; 0 0 1 1" 
  keyTimes="0;0.0001;1" 
  values="200;540;540">
</animate>

注意:这里必须将calcMode值设置成spline,keySplines属性才会起作用。

我们设置了两组keySplines值并用分号分隔,第一组是”0.5 0 0.5 1″指定了贝塞尔曲线上两个控制点x,y坐标,生成的图形是我们中学就已熟悉的正弦曲线,这里用正弦函数来设置keyTimes值在0-0.0001这个时间段的变化速率,也就是图文高度从200变化到540时的缓动函数。

贝塞尔控制点的坐标都是在0-1之间,从下图中可以清楚地看到两个控制点是如何影响曲线的走向,原理类似于photoshop中的钢笔工具。

贝塞尔控制点坐标

下面我都会用一个小球来演示不同的贝塞尔曲线的运动效果,可以点击阅读原文查看这个演示程序,通过拖拽程序中的两个控制点来生成不同的曲线。

sine
Sine曲线运动

第二组keysplines值”0 0 1 1″是一条直斜线,表示keyTimes值在0.0001-1这个时间段做线性匀速运动,由于第二段values值没变所以这里不会有动画效果。

linear
Linear匀速运动

设置控制点坐标为 1 0 0 1 将动画进入退出部分的过渡变得更加剧烈,得到Expo曲线。

Expo曲线运动

设置控制点坐标为 0 1 1 0 得到类似慢镜头的SlowMo曲线。

SlowMo曲线运动

配合keyTimes属性

在实际应用中,我们可以配合keyTimes属性,制作出多段缓动动画。

再举个伸长图文的栗子,配合keyTimes属性我们可以在伸长图文前先做一个收缩的动作,产生弹性拉伸的效果。

<animate 
  attributeName="height" 
  begin="click" 
  dur="10000s" 
  calcMode="spline" 
  keySplines="1 0 0 1;0.5 0 0.5 1; 0 0 1 1" 
  keyTimes="0;0.00005;0.0001;1" 
  values="200;150;540;540" 
  fill="freeze" 
  restart="whenNotActive">
</animate>

总结

通过这些例子,大家对缓动函数已经有了初步的了解,灵活地应用它们可以使动画更加自然平滑,提高用户体验度,赶快应用到你的动画中去吧。

关注