小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
效果图
表达式代码与详细注释
/// @note 弹性分段函数【实际上就是分段的二次抛物线】
function outBounce(t, b, c, d) {
if ((t /= d) < (1 / 2.75)) {
return c * (7.5625 * t * t) + b;
} else if (t < (2 / 2.75)) {
return c * (7.5625 * (t -= (1.5 / 2.75)) * t + .75) + b;
} else if (t < (2.5 / 2.75)) {
return c * (7.5625 * (t -= (2.25 / 2.75)) * t + .9375) + b;
} else {
return c * (7.5625 * (t -= (2.625 / 2.75)) * t + .984375) + b;
}
}
/// @note 实际调用弹跳函数的缓动函数
function easeAndWizz() {
var n = 0;
/// @note 确保关键帧帧数是大于 0 的
if (numKeys > 0) {
n = nearestKey(time).index; ///< 获取最近的关键帧索引
if (key(n).time > time) { ///< 如果最近的关键帧所处时间在当前时间之后(即时间还没到)
n--; ///< 则取前一个关键帧的索引
}
}
try {
/// @note 前后两个关键帧
var key1 = key(n);
var key2 = key(n + 1);
} catch (e) {
return null;
}
/// @note 确定关键帧需要的数据维度
var dim = 1; ///< 该属性至少是一维的
try {
key(1)[1];
dim = 2; ///< 数据有第二维度
key(1)[2];
dim = 3; ///< 数据有第三维度
} catch (e) { }
t = time - key1.time; ///< 当前时间和前一个关键帧的时间差
d = key2.time - key1.time; ///< 前后俩关键帧的时间差
/// @note 计算关键帧上的属性,用于后期的弹跳计算
/// 一维
sX = key1[0];
eX = key2[0] - key1[0];
/// @note 二维
if (dim >= 2) {
sY = key1[1];
eY = key2[1] - key1[1];
/// @note 三维
if (dim >= 3) {
sZ = key1[2];
eZ = key2[2] - key1[2];
}
}
if ((time < key1.time) || (time > key2.time)) {
return value;
} else {
/// @note 进行弹跳计算
val1 = outBounce(t, sX, eX, d);
/// @note 同样分为三个维度进行计算
switch (dim) {
case 1:
return val1;
break;
case 2:
val2 = outBounce(t, sY, eY, d);
return [val1, val2];
break;
case 3:
val2 = outBounce(t, sY, eY, d);
val3 = outBounce(t, sZ, eZ, departFocus);
return [val1, val2, val3];
break;
default:
return null;
}
}
}
(easeAndWizz() || value);