这次不多扯皮了,我们上一次玩了一下估值器TypeEvaluator,通过在这个东西,我们也会用了onObject方法,可以让变换的属性变成一个对象,实现对象到对象的动画过度。
这次我就还拿上次的那个小球举例了。我们现在再看一下我们小球的例子:
这个小球确实按照我们的要求,从(100,100)到(500,500)再到(500,900),但是信息的朋友有没有发现,他这个速率是不一样的:很明显我们发现他是先加速后减速的,难道他不应该是一直匀速变化吗?这个先加速后减速的效果,就是用了我们内置的一个插值器——AccelerateDecelerateInterpolator(加速减速插值器)。
没错,我们这篇要说的就是插值器(Interpolator)。下面先看一下Interpolator的注释:
我们直接看一下它的父类TimeInterpolator:
这个解释就很简单了,插值器定义了动画的变化率,我们可以通过getInterpolation方法,来实现动画的是线性还是非线性播放。getInterpolation方法有一个input参数,这个参数范围是从0.0到1.0。他的返回值可以比0.0小,比1.0大。
我们有几个常用的继承类:
我们刚才说上面的效果是使用AccelerateDecelerateInterpolator类,那我们来看一下他的实现方法:
很简单,只是一个余弦函数,我们知道余弦函数是周期为2π的函数,值域是-1~1。
我们刚才说input的范围是0~1,所以加1之后就是1~2,*π就是π~2π。
纯手绘就不要喷了-。+,现在我们定义域是π~2π,所以值域是-1~1,我们给他进行一下伸缩,除以2 + 0.5.最后范围变成0~1。这是我们想要的结果。
现在我们返回这个值,那他返回到哪里了呢?还记得TypeEvaluator的evaluate方法吗?他的第一个参数fraction其实就是我们这里的返回值,所以我们可以这么理解:
注意):只能说fraction和input相关联,不是fraction = input;
从数学的角度理解,我们在插值器中通过接收input参数,得到自变量在每一时刻的值,然后通过我们的具体的函数逻辑,返回因变量在每一时刻的值。
上述是通过cos函数实现,我们注意到从π~3/2π的这段函数,他的斜率是在增大。而从3/2π到2π,这段斜率又减小了,所以正是我们先加速后减速的效果。
从值的角度理解,相同一段时间我们interpolate方法的返回值变化率先变大,然后又变小了。所以先加速后减速。
想必说到这里大家应该已经明白一点Interpolator的作用了。
如果不太明白,我们再来看一下线性插值器的实现:
简单粗暴,直接返回了input:
正是对应了我们这张图,他的变化率为常数,所以我们相同时间得到小球的坐标值变化也是相同的。也就是说是匀速变化。
看了这两个,我们是不是也可自己写一个插值器呢,来吧,小试牛刀一下:
偷个懒,我就直接用上次小球的案例了-。+
既然他有一个先加速后减速的插值器,那我们来写一个先减速后加速的插值器吧。因为我们要先减速后加速,所以我们需要在0~0.5这段斜率减小,在0.5~1这段斜率增大,但是我们发现三角函数中没有一整段这样的,所以我们把发分成两段来看:
第一段0~0.5,我们用sin中0~π/2这段。只是进行/2操作就得到了0~0.5.
第二段0.5~1,这段我们通过将sin中π/2~π函数先后进行伸缩,关于x轴堆成,然后平移,得到了我们想要的效果。
其实这些都是数学知识,笔者这里就不多说啦。然后我们看一下效果:
为了看的明显,我把最后一段让他重新返回(100,100)点处。
很明显,我们看到他是先加速,后减速的,现在我们对插值器Interpolator应该有所了解了吧。