当提到要做一个EaseOut效果的动画的时候,很多人可能会不假思索的觉得这真的太简单了,因为UIView
本身提供了很多的这种动画效果,有现成的api可以让我们直接使用,但是如果我们要自己实现一个EaseOut
效果,或者是其他的EaseX
效果时候,该怎么做呢。
今天我们就一起学习一下该怎样自己写一个
EaseOut
效果的动画,学会了这个,那么其他的诸如EaseIn,EaseInOut
等效果,我们就有思路该怎样做了(其实做这个需要一定的数学基础,但不意味着高数要到90分。)
首先看下面的一张图,复习一下基础的数学知识(貌似只需要基础的就可以了)......
函数.png看到上面这个函数应该很熟悉吧,是一个一元二次方程
与一个一元一次方程
的相交问题。两个函数在x=0
与x=t
的时候相交,说明这个方程有两个实数解
。如果将x轴
当做是时间的话,那么每一个时间点,都可以对应这两个函数的唯一一个点。也就是说y = (h/4t)x + h/4
与y = x^2+(h/2t - t)x + h/2
这两个函数,只要我们知道了其中一个函数的y值,那么就可以知道另外一个函数的y值了。
看到这里是不是想到了什么,上面的一元一次方程
就像是在均匀变化的长度、位移、透明度、角度
等对象属性,而与它的y值在同一时间一一对应的一元二次方程
则不是均匀变化的,而是一种EaseOut
的变化效果。这就是我们实现自定义EaseOut
效果的数学基础。同理我们可以将一元二次方程
换做是其他的我们能够进行数学运算的方程,只要跟下面固定斜率的直线保持值得对应关系就可以了,由此我们就可以通过变换映射出很多其他的效果了。
那么怎样才能够得到那个一元一次方程呢,也就是首先我们怎样使得属性诸如长度、位移、透明度、角度等等随着时间均匀变化呢。
在这里要介绍一个项目,那就是CHAnimation,这是一个可以编写自己的动画引擎的项目,灵感来自于Facebook Pop,其优点是比较轻量,容易理解。这里我们并不过多的介绍CHAnimation
的原理,感兴趣的可以去下载下来阅读源码。
总之通过它我们可以获得我们想要的一元一次方程
,然后再做一层变换实现自己的EaseX效果
。
先看下使用CHAnimation
的一段代码,下面这段代码会让一个view
视图的size
随着时间均匀增大,并且该视图始终是一个圆,只是半径在慢慢变大。
CHAnimation *enlarge = [CHAnimation new];
enlarge.beginTime = CACurrentMediaTime();
enlarge.fromValue = @(self.height/4);
enlarge.toValue = @(self.height/2);
enlarge.duration = K_DefaultPopTime;
enlarge.writeBlock = ^(id obj, id value) {
CGFloat fvalue = [value floatValue];
view.size = CGSizeMake(2*fvalue, 2*fvalue);
view.layer.cornerRadius = fvalue;
}
[view ch_addAnimation:enlarge forKey:@"enlarge"];
对应一元一次方程
,可以看到 在t=0
的时候,y=self.height/4
。在t= K_DefaultPopTime(默认为1s)
的时候,y=self.height/2
,这里的y就是圆的半径。如果半径是80的话,那么就可以理解为,圆在一秒钟的时间内,半径从20扩大到40,并且这种变化是均匀变大的。因为 enlarge.writeBlock = ^(id obj, id value) {}
中的value
值是一个均匀变化的值。
这个value
值可以看做是一元一次方程
的y值,并且是已知的,由此我们可以得到此时的时间t,而根据t我们又可以得到一元二次方程的y值。得到一元二次方程的y值,那么我们就可以将这个新值当做圆的半径了,这个时候圆的半径变化就是一种EaseOut
的变化效果了。写到这里,基本就已经实现了我们想要的功能了。
是不是很简单呢,下面附上本文的demo地址。
感兴趣的可以下载(注意demo中只是针对圆的半径做了变换处理,但由于变换的时间短,变换的值得范围也比较小,所以效果可能不会太明显,并且作者数学水平有限,只是做了简单的一元二次函数的变换,读者可以按照文中的思路,实现自己的更加有趣的变化效果。)
最后附一个小广告,开通了个人的公众号,不仅仅是程序猿,旨在分享知识、技术、思绪、情怀的公众号,包括但不局限于逗比。。
个人公众号二维码.jpg
网友评论