iOS开发之常用技术点

CADisplayLink 动画进阶

2019-02-17  本文已影响30人  沙琪玛dd

CADisplayLink 动画进阶

前言

正文

需求分析

如何基于 CADisplayLink 实现非线性动画效果

在介绍实现非线性动画效果之前,我们先简单复习一下线性动画效果的实现。假设动画的起始状态变量为 fromValue,最终状态的变量为 toValue,当前动画值进度为 percent,当前状态为 currentValue。那么我们可以得到计算动画当前状态的插值公式为:

currentValue = fromValue + (toValue - fromValue) * percent 

其实整体实现思路还是和 如何实现一个圆形进度条按钮 中提到的一样。不过在这里有需要勘误的一个点是,上篇博客提到 CADisplaylink "iOS 设备屏幕显示每秒刷新60次"。CADisplayLink 的刷新频率确实是60次/秒左右,但是并不固定,由于每次调用 CADisplayLink 的时间间隔都不是平均的,所以我们不能根据调用次数乘以1/60的时间间隔来得到当前经历的时间。正确计算当前经历时间的方法是通过获取当前时间再减去起始时间来得到:

@property (nonatomic, assign) NSTimeInterval beginTime;
@property (nonatomic, assign) NSTimeInterval currentTime;
//在动画开始时记录起始时间
self.beginTime = CACurrentMediaTime();

得到当前的经历时间为

self.currentTime = CACurrentMediaTime() - self.beginTime;

由于我们是线性动画,所以假设动画时间进程为 timePercent,timePercent = self.currentTime / duration,那么当前动画值进度 percent 就等于 timePercent,然后可以得到

currentValue = fromValue + (toValue - fromValue) * (self.currentTime / duration) 

其中 fromValue、toValue、duration 都是已知数,这样我们就可以拿到 currentValue,然后在 CADisplayLink 每次调用的函数中去更新 currentValue 值,就可以实现线性动画的过渡效果了。

基于此思路我们实现一个插值函数如下,percent 为动画值进度

- (CGFloat)interpolateFrom:(CGFloat)from to:(CGFloat)to percent:(CGFloat)percent {
    return from + (to - from) * percent;
}

那么,如何实现非线性的动画效果呢? 我们先了解一下一些实现非线性动画效果的函数 —— 缓动函数

缓动函数

缓动函数是动画时间进程(p)和动画值进程(s)之间的一个映射。什么是动画时间进程,就是 timePercent,而动画值进程就是 percent。两者的定义阈都为[0,1]。在线性关系中,percent = timePercent,而在非线性关系中,percent = f(timePercent)。

我们知道动画一般都有渐进(EaseIn)、渐出(EaseOut)、渐近渐出(EaseInOut)的效果,它们对应的缓动函数图大概是这样:


function.png

举例来说,对于 EaseIn 函数的图像分析,y = x * x 的坐标图是完全符合 EaseIn 的效果的,所以我们可以实现一个 y = x * x 的函数作为这种 EaseIn 效果的缓动函数:

- (double)calculate:(double) p {
    return p * p;
}

那么,在线性动画的代码中,调用 interpolateFrom:to:percent: 之前,将 percent(其实是 timePercent)作为参数传入 calculate 方法,计算得到动画值进程 percent,然后再调用 interpolateFrom:to:percent: 计算当前的动画值。这样我们就实现了非线性动画中的 QuadraticEaseIn 动画。

关于各种缓动函数的效果可以参照这个网址,对于其中所有效果的缓动函数都已经在 Demo KiraCircleButton 中的 AnimationFunction 中实现了。Demo 中提供了配置页面,可以方便的选择配置体验不同的动画效果。

既然本文是进阶篇,那么我就不贴具体的实现代码了。其中有关如何绘制,具体如何实现动画的问题,可以直接下载 Demo KiraCircleButton 看源码。
有问题欢迎指出,谢谢。

上一篇 下一篇

猜你喜欢

热点阅读