Timer动画使用缓动函数

缓动函数 通过时间的变化控制参数值变化的速率。

现实生活中,物体并不是突然启动或者停止,当然也不可能一直保持匀速移动。就像我们打开抽屉的过程那样,刚开始拉的那一下动作很快,但是当抽屉被拉出来之后我们会不自觉的放慢动作。掉落在地板上的东西,一开始下降的速度很快,后来就会在地板上来回反弹直到停止。

系统自带的缓冲函数如下:

kCAMediaTimingFunctionLinear

kCAMediaTimingFunctionEaseIn

kCAMediaTimingFunctionEaseOut

kCAMediaTimingFunctionEaseInEaseOut

kCAMediaTimingFunctionDefault

使用CAMediaTimingFunctionName中如下方法可以取出贝塞尔曲线控制点:

- (void)getControlPointAtIndex:(size_t)idx values:(float[_Nonnull 2])ptr; 

直接绘制出来是这样的曲线:

default-timing-function

当然系统也提供自定义控制点方法:

/* Creates a timing function modelled on a cubic Bezier curve. The end
 * points of the curve are at (0,0) and (1,1), the two points 'c1' and
 * 'c2' defined by the class instance are the control points. Thus the
 * points defining the Bezier curve are: '[(0,0), c1, c2, (1,1)]' */

+ (instancetype)functionWithControlPoints:(float)c1x :(float)c1y :(float)c2x :(float)c2y;

但是但是但是,

这些都是封装在框架内的方法, 如果我想用定时器自己做动画呢?

用简单函数处理下时间和动画进度关系就可以了! 想起你的数学老师了吗?

曲线是这样的:

custom-timeing-function

来源:缓动函数

下面的函数参数范围为 0.0 ~ 1.0, 表示时间进度。返回值为对应的动画进度。

函数是各语言通用的,iOS 用的话要把公式的 PI 变成 M_PI 就可以。

对比上面官方函数, 可以大概这样对应着来用:

kCAMediaTimingFunctionLinear
-> linear
-> x

kCAMediaTimingFunctionEaseIn
-> easeInSine
-> 1 - cos((x * PI) / 2)

kCAMediaTimingFunctionEaseOut
-> easeOutSine
-> sin((x * PI) / 2)

kCAMediaTimingFunctionEaseInEaseOut
-> easeInOutSine
-> -(cos(PI * x) - 1) / 2

kCAMediaTimingFunctionDefault
-> easeInOutQuad
-> x < 0.5 ? 2 * x * x : 1 - pow(-2 * x + 2, 2) / 2

这里需要个Demo, 可是我困了...

标签:timing function, 动画时间函数, 时间函数, easings, ease, 动画, animation