最近在阅读《IOS核心动画高级技巧》这本书,里面说到了完全自定义缓冲函数的方法。里面讲解并不是很详细,我在这里说一下自己的见解。具体情节,大家可以阅读这本书,这篇文章可以参考那本书的10.8的Demo。
在Core Animation中,动画是作用在CALayer上的。为了能更加模拟使动画更加能模拟现实生活,比如说,汽车在路上,汽车是经过加速,匀速,然后减速到达终点的,所以动画也应该具有这样类似的属性,有时候动画还必须具备弹簧的感觉,即汽车还有时候会驶过终点,然后再回来终点。为了实现这种效果,Core Animation定义了CAMediaTimingFunction这个属性,称之为缓冲函数,而且Core Animation还提供一系列的标准函数给我们使用,这些标准函数有:
kCAMediaTimingFunctionLinear
kCAMediaTimingFunctionEaseIn
kCAMediaTimingFunctionEaseOut
kCAMediaTimingFunctionEaseInEaseOut
kCAMediaTimingFunctionDefault
在这里,将说明自定义缓冲函数的原理,并不会对这些标准缓冲函数加以说明。这些标准函数也没有实现弹簧的感觉,即不能越过终点。
在完全自定义缓冲函数中,我们将放弃CAMediaTimingFunction属性。利用CAKeyframeAnimation可以自己做一个类似缓冲函数的动画来。
首先我们必须明白,动画其实是不断变化的数据,所以我们控制这些数据的变化,让数据按我们指定的速率和加速度来增长或者减少,我们就实现了缓冲动画。在这里引申出两个概念:动画时间数据和动画数据。动画时间数据是动画运行需要一个时间段,时间段里面每个时间点就是动画时间数据。动画数据是要改变的CALayer的属性值在每个动画时间里应该拥有的数值。说白了,动画数据y跟动画时间数据x形成的函数关系就是缓冲函数了。如果我们清楚了解到我们所需要的动画数据跟动画时间数据的关系,我们就可以利用动画时间求出动画数据,然后我们将动画数据存储在CAKeyframeAnimation的values数组里,我们便可以实现缓冲动画了。
在这里,我将讲解《IOS核心动画高级技巧》10.8的Demo。
上图方法中,我们先用变量存储我们动画数据的开始点(fromValue)和结束点(toValue)。然后存储动画运行的总时间。在for循环里面,我们利用动画数据和动画时间数据的函数关系求出所有的动画数据,并且存储在frams数组中,最后传递给CAKeyframeAnimation的values数组里面。现在我们就要看看bounceEseOut()函数和-interpolateFromValue:toValue:time:方法是怎么回事?首先来看一下-interpolateFromValue:toValue:time:方法:
-interpolateFromValue:toValue:time:方法会返回一个NSValue对象,这就是我说的动画数据了。-interpolateFromValue:toValue:time:方法使用了interpolate函数。interpolate函数是求出动画数据的关键,interpolate函数很简单,根据time,fromValue和toValue求出动画数据,这个fromValue和toValue是一直不变的,关键点就在于这个time,这个time也不是我说的动画时间数据。至此我应该说明一下哪个是动画时间数据x了:
float time =1/(float) numFrames * i;
我们可以想象,动画总的运行时间是一个时间段,里面每个时间点就是我们所要动画时间数据了,而上面提供了60个这样的时间点,这些时间点就是动画时间数据了,从上可以看出动画时间数据的范围是0到1。而在interpolate函数中的time只是包含了缓冲函数关系的数据(这些数据的范围是0到1),根据fromValue和toValue放大一下缓冲函数关系的数据就是动画数据了。
interpolate函数中的time来源于bounceEseOut()函数,而这个bounceEseOut()函数就是我们所需要定义的缓冲函数啦。我们可以简单看出,缓冲函数有4个段。根据书中10.8的Demo的动画现象,第一段是弹球掉到终点动画,第二三段是弹球在反弹的动画,第四段是弹球弹完后掉到终点的动画。
网友评论