效果图
归位(back)
表达式代码与注释
var s = 1.70158; ///< 用于 "归位" 的超越量 /// @note 归位函数 function outBack(t, b, c, d) { if (s == null) s = 1.70158; return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + 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 = outBack(t, sX, eX, d); /// @note 同样分为三个维度进行计算 switch (dim) { case 1: return val1; break; case 2: val2 = outBack(t, sY, eY, d); return [val1, val2]; break; case 3: val2 = outBack(t, sY, eY, d); val3 = outBack(t, sZ, eZ, d); return [val1, val2, val3]; break; default: return null; } } } (easeAndWizz() || value);