当数学遇上动画:讲述 ValueAnimator、TypeEvaluator和TimeInterpolator之间的恩恩怨怨(3)
上一节我们得到一个重要的结论,借助TimeInterpolator
或者TypeEvaluator
“单独” 来控制动画所产生的动画效果殊途同归!
此外,上一节结尾我们还说到,项目AnimationEasingFunctions和项目EaseInterpolator本质上是差不多的,都是定义了一些动画效果对应的函数曲线。前者是将其封装成了TypeEvaluator
,后者是将其封装成了Interpolator
!
这一节我们来研究下这些函数曲线。
1 缓动函数曲线
下图显示了常见的这些函数曲线,到底这些函数曲线都是什么鬼呢?
这些函数曲线最早是由Robert Penner提出来用于实现补间动画的"Penner easing functions"
,这些曲线主要分成10类,包括"BACK", "BOUNCE", "CIRCULAR", "ELASTIC", "EXPO", "QUAD", "CUBIC", "QUART", "QUINT", "SINE"
,每一类下面都有缓动进入、缓动退出以及缓动进入和退出三种效果,所以共有30个。这些效果对照着函数曲线来看其实也挺好理解,"QUAD", "CUBIC", "QUART", "QUINT"
分别对应着二次、三次、四次以及五次曲线,"SINE"
对应正弦函数曲线,"EXPO"
对应指数函数曲线等等。其中"BACK"
和"ELASTIC"
有上冲和下冲的效果。
Robert Penner在Github上开源了jQuery的版本实现,随后也就有了很多不同语言版本的实现,例如Java版本的jesusgollonet/processing-penner-easing以及代码家的Android版本的AnimationEasingFunctions等等。
这些版本的实现都是4个参数的,分别是起始值b
、数值间隔c
(结束值-起始值)、当前时间t
、时间间隔d
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
//不带缓动,也就是前面说的“线性”估值器 function noEasing (t, b, c, d) { return c * (t / d) + b; } //带缓动效果,例如二次曲线形式 easeInQuad: function (t, b, c, d) { //缓动进入 return c*(t/=d)*t + b; }, easeOutQuad: function (t, b, c, d) {//缓动退出 return -c *(t/=d)*(t-2) + b; }, easeInOutQuad: function (t, b, c, d) {//缓动进入和退出 if ((t/=d/2) < 1) return c/2*t*t + b; return -c/2 * ((--t)*(t-2) - 1) + b; }, 那为什么与之殊途同归的EaseInterpolator是1个参数的呢? //QuadInOut Interpolator public float getInterpolation(float input) { if((input /= 0.5f) < 1) { return 0.5f * input * input; } return -0.5f * ((--input) * (input - 2) - 1); } |
这是因为当Interpolator
传入到后面的TypeEvaluator
的时候就有了起始值、结束值以及时间间隔(时间间隔定义在缓动函数内部,只有部分缓动函数需要这个参数)这3个参数,可以参考下面的代码来理解,所以说,它们在本质上还是一样的!
1 2 |
fraction = getInterpolation(input) ==> 这种1个参数形式其实也可以等效于 easingfunction(currentTime, 0, 1, totalTime) value = evaluate(fraction, startValue, endValue) = startValue + fraction * (endValue - startValue) |
2 One more thing
看到这里的话,我们就会想啦,如果我们把函数曲线抽象出来,然后再提供相应的转换方法,使其轻轻松松地转换成Interpolator
和TypeEvaluator
的话,如此,岂不善哉?
所以,我就站在众多巨人们的肩膀上,写了一个新项目Yava,项目代码非常简单,而且代码很少只有4个重要的类,它实现的功能就是将抽象的函数曲线轻松转换成立即可用的Interpolator
和TypeEvaluator
,并且提供了常见的30个缓动函数(Easing Functions)的实现,它们既可以当做Interpolator
来用,又可以当做TypeEvaluator
来用,非常方便。
这里我直接把这4个重要类的代码贴出来吧。
(1) IFunction
接口
1 2 3 4 5 6 |
/** * 函数接口:给定输入,得到输出 */ public interface IFunction { float getValue(float input); } |
(2)AbstractFunction
抽象类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
/** * 抽象函数实现,既可以当做简单函数使用,也可以当做Interpolator或者TypeEvaluator去用于制作动画 ator和TimeInterpolator之间的恩恩怨怨(3)
上一节我们得到一个重要的结论,借助 此外,上一节结尾我们还说到,项目AnimationEasingFunctions和项目EaseInterpolator本质上是差不多的,都是定义了一些动画效果对应的函数曲线。前者是将其封装成了 这一节我们来研究下这些函数曲线。 1 缓动函数曲线下图显示了常见的这些函数曲线,到底这些函数曲线都是什么鬼呢? 这些函数曲线最早是由Robert Penner提出来用于实现补间动画的 Robert Penner在Github上开源了jQuery的版本实现,随后也就有了很多不同语言版本的实现,例如Java版本的jesusgollonet/processing-penner-easing以及代码家的Android版本的AnimationEasingFunctions等等。 这些版本的实现都是4个参数的,分别是起始值
这是因为当
2 One more thing 看到这里的话,我们就会想啦,如果我们把函数曲线抽象出来,然后再提供相应的转换方法,使其轻轻松松地转换成 所以,我就站在众多巨人们的肩膀上,写了一个新项目Yava,项目代码非常简单,而且代码很少只有4个重要的类,它实现的功能就是将抽象的函数曲线轻松转换成立即可用的 这里我直接把这4个重要类的代码贴出来吧。 (1)
(2)
|