2021SC@SDUSC
前面两篇我们主要说了动画的主要驱动,然而,在动画过程中还有一个很重要的部分,那就是缓动引擎。 补间动画指的是做动画时,在两个关键帧中间需要做“补间动画”,才能实现图画的运动;插入补间动画后两个关键帧之间的插补帧是计算机自动运算而得到的。
首先说一下一般引擎下的tween都比较类似
有些tween有linear公式,像egret只要不填,就是线性,也就是从0~1连接的直线。其他公式简单聊一下:sine公式其实就是用到了它的1/4波形,inOut是将两个波形叠加在一起。Cubic是取三次方,其他的有取四次方,五次方的公式。每种公式都对应有In,Out,InOut,(有些引擎还包含OutIn,并不常用)。
quark renderer中的缓动引擎就是直接调用的https://github.com/sole/tween.js/blob/master/src/Tween.js这里的缓动引擎
首先是瞬间处理函数
linear: function linear(k) {
return k;
},
瞬间处理函数,用于直接将对象的值设置为制定的值,或者响应特定的函数和方法等都属于这一类。这里是将值设定为了k,后面的操作都是以这个k为基础进行的。
紧接着就是
quadraticIn: function quadraticIn(k) {
return k * k;
},
quadraticOut: function quadraticOut(k) {
return k * (2 - k);
},
quadraticInOut: function quadraticInOut(k) {
if ((k *= 2) < 1) {
return 0.5 * k * k;
}
return -0.5 * (--k * (k - 2) - 1);
},
可以很明显的看出是quadratic(平方)类型的补间函数,其中k在设计中值是处于0~2之间的。就像前面说的,每种公式都对应有In,Out,InOut,(有些引擎还包含OutIn,并不常用),这里就是使用了标准的三个类型:
其中in 越来越快,开始很缓慢,结束很突然,用k的平方来表示,out 越来越慢,开始很突然,结束很缓慢,最后的nOut 先加快后减慢,两端速度都趋近0,过程中达到最大值,我们通过画出函数图形可以看出结果
紧接着还有诸如cubic(三次方)、quartic(四次方)、quintic(五次方)、sinusoidal(正弦函数)、exponential(指数型)、circular(环形函数行)等极为类似的方法,我在这里就不一一赘述了,其实现方法也都是大同小异的。
后面的就有些不同了 。
首先说的是
backIn: function backIn(k) {
var s = 1.70158;
return k * k * ((s + 1) * k - s);
},
backOut: function backOut(k) {
var s = 1.70158;
return --k * k * ((s + 1) * k + s) + 1;
},
backInOut: function backInOut(k) {
var s = 1.70158 * 1.525;
if ((k *= 2) < 1) {
return 0.5 * (k * k * ((s + 1) * k - s));
}
return 0.5 * ((k -= 2) * k * ((s + 1) * k + s) + 2);
},
back 缓冲恢复,速度变化的趋势在过程中会有一瞬间的改变,视觉冲击力会比缓慢公式好一点,但是全局用就有点唐突。
然后是
elasticIn: function elasticIn(k) {
var s;
var a = 0.1;
var p = 0.4;
if (k === 0) {
return 0;
}
if (k === 1) {
return 1;
}
if (!a || a < 1) {
a = 1;
s = p / 4;
} else {
s = p * mathAsin(1 / a) / (2 * PI);
}
return -(a * mathPow(2, 10 * (k -= 1)) * mathSin((k - s) * (2 * PI) / p));
},
elasticOut: function elasticOut(k) {
var s;
var a = 0.1;
var p = 0.4;
if (k === 0) {
return 0;
}
if (k === 1) {
return 1;
}
if (!a || a < 1) {
a = 1;
s = p / 4;
} else {
s = p * mathAsin(1 / a) / (2 * PI);
}
return a * mathPow(2, -10 * k) * mathSin((k - s) * (2 * PI) / p) + 1;
},
elasticInOut: function elasticInOut(k) {
var s;
var a = 0.1;
var p = 0.4;
if (k === 0) {
return 0;
}
if (k === 1) {
return 1;
}
if (!a || a < 1) {
a = 1;
s = p / 4;
} else {
s = p * mathAsin(1 / a) / (2 * PI);
}
if ((k *= 2) < 1) {
return -0.5 * (a * mathPow(2, 10 * (k -= 1)) * mathSin((k - s) * (2 * PI) / p));
}
return a * mathPow(2, -10 * (k -= 1)) * mathSin((k - s) * (2 * PI) / p) * 0.5 + 1;
},
elastic 果冻效果,可以看做back的加强版,比back效果更强一些,会多抖动几次,直接上效果图
bounceIn: function bounceIn(k) {
return 1 - easing.bounceOut(1 - k);
},
bounceOut: function bounceOut(k) {
if (k < 1 / 2.75) {
return 7.5625 * k * k;
} else if (k < 2 / 2.75) {
return 7.5625 * (k -= 1.5 / 2.75) * k + 0.75;
} else if (k < 2.5 / 2.75) {
return 7.5625 * (k -= 2.25 / 2.75) * k + 0.9375;
} else {
return 7.5625 * (k -= 2.625 / 2.75) * k + 0.984375;
}
},
bounceInOut: function bounceInOut(k) {
if (k < 0.5) {
return easing.bounceIn(k * 2) * 0.5;
}
return easing.bounceOut(k * 2 - 1) * 0.5 + 0.5;
}
最后就是bounce 用于模拟小球落地,是最简单模拟东西落地的弹性效果。
综上所述
1.瞬间处理函数,用于直接将对象的值设置为制定的值,或者响应特定的函数和方法等都属于这一类。
2.匀速 linear 用于匀速运动,开始和结束都比较突然,适用于卷轴类匀速运动,颜色,透明度过渡等。(这个实际上在quark renderer中兵没有涉及到,但确实是很常见的一种缓动函数格式)
3.cubic等缓慢公式,用于慢慢展现或者慢慢靠近结束,大部分物体运动都可以用这种效果来做
4.back 缓冲恢复,视觉冲击力好于单纯的缓慢公式,但是全局用就有点唐突。
5.elastic 果冻效果,比back效果更强一些,会多抖动几次。
6.bounce 模拟小球落地,最简单模拟东西落地的弹性效果,虽然假了点,但是在简单易用方面有一定的优势。
最后要强调的是,交互性操作时尽量使用out类公式,这类公式初始速度快,会有效反馈用户操作,而特效类的则主要倾向于in公式或者in&out公式,在真实开发中自行斟酌,使用缓动是要明确当前值,要运动到的值,以及运动过程。同时,这些值可以稍加随机,但是即便随机,这些值也都是固定好的结果等待运动呈现。