AEJoy —— 表达式之速度和频率控制(三)【JS】

213 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

效果图

通过计算滑块控件曲线下的面积得到了很大的改进

01.gif

线性关键帧积分器

这很有趣,但现在怎么办? 我们需要一个表达式来计算过去发生的所有曲线段的面积加上当前段的面积,直到当前时间。例如(使用之前的Slider Control 动画),在两秒钟内,我们期望表达式计算第一个片段(180 度)的面积加上第二个片段(360 度)的一半面积,到那时总共是 540 度。这里有一个表达可以完成这项工作:

spd = effect("Slider Control")("Slider");
n = spd.numKeys;
if (n > 0 && spd.key(1).time < time){
  accum = spd.key(1).value*(spd.key(1).time - inPoint);
  for (i = 2; i <= n; i++){
    if (spd.key(i).time > time) break;
    k1 = spd.key(i-1);
    k2 = spd.key(i);
    accum += (k1.value + k2.value)*(k2.time - k1.time)/2;
  }
  accum += (spd.value + spd.key(i-1).value)*(time - spd.key(i-1).time)/2;
}else{
  accum = spd.value*(time - inPoint);
}
value + accum

注意,这个表达式应该适用于任何只使用线性关键帧的曲线(稍加修改可改成适用于 定格[Hold]关键帧)。(缓动关键帧需要一种更低效率的逐帧方法,我将在下一节中介绍)。在表达式的末尾,变量accum 包含曲线下的面积,在这种情况下,它将是截至当前时间的总旋转度。这是一个相当有效的表达式,因为它不需要引用之前的所有帧,只需要引用之前的关键帧。上方的动图显示了改进后的结果。

该表达式利用了一个事实,即您可以使用相同的公式计算线性关键帧(即三角形、矩形和梯形形状)所限制的任何分段的面积。这个公式就是段的持续时间乘以平均值。(要获得平均值,只需将第一个关键帧的值与第二个关键帧的值相加,然后将结果除以 2 )。

同样的公式也可以用来计算任何梯形(如图所示)、矩形或三角形线段的面积。面积是平均值乘以段持续时间

image.png

下图是 Slider Control (粉色)和 Rotation 表达式的结果(青色)的图形。请注意,当 Slider Control 大于 0 时,表达式值会继续增加,实际上达到了所需的 1080 总角度。

通过集成 Slider Control (粉色)生成的曲线(青色)。请注意,即使是线性关键帧,积分也会生成一个平滑(缓动)的曲线 image.png

这是一个奖励。注意在上图中,表达式的结果是一个平滑的曲线,有很好的进入和退出坡道。尽管 Slider Control 的线性关键帧产生了尖锐的边缘曲线,但积分的结果是平滑的。这使得这个表达式成为许多速度控制应用程序的一个很好的选择。