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

401 阅读2分钟

线性关键帧积分器

定格(Hold)关键帧

可能在某些情况下,你宁愿使用定格关键帧来控制速度控件滑块。线性关键帧积分器表达式几乎是可行的,但并不完全可行。这里有一个微小的变化,使其适用于定格关键帧:

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);
    v2 = spd.valueAtTime(k2.time-.001);
    accum += (k1.value + v2)*(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

在这个版本中,对于每个关键帧段,第二个关键帧检索的值是比实际的关键帧提前 0.001 秒,以获得进入关键帧的值。

逐帧的方法

线性关键帧积分器是一个很好的工具,但你可能会遇到它不适合你的情况,你将不得不诉诸暴力 —— 逐帧进行的选项。这个表达式本身是相当直接和简单的,但它可以让你的电脑运行相当长的时间。这是代码:

spd = effect("Slider Control")("Slider");
accum = 0;
for (i = timeToFrames(inPoint); i <= timeToFrames(time); i++){
  accum += spd.valueAtTime(framesToTime(i));
}
value + accum*thisComp.frameDuration

与线性关键帧积分器一样,该表达式计算速度控制波形曲线下的面积。不同之处在于,线性关键帧积分器计算的是大块(关键帧之间的整个片段)的面积,而逐帧积分器计算的是每一帧的贡献。这意味着,随着时间的推移,表达式必须在每一帧进行越来越多的计算(以计算之前所有帧的贡献)

逐帧的积分器 与我们使用了相同的滑块控件的 线性关键帧积分器 上的表现进行比较是很有用的。下图显示了逐帧积分器(青色)生成的曲线叠加在线性关键帧积分器(粉色)生成的曲线上。正如你所看到的,逐帧结果只会在帧边界处发生变化,但除此之外,它们匹配得非常好。在实践中,它们应该生成相同的动画(除非出于某种原因,你需要使用子帧分辨率)。

这显示了逐帧积分器(青色)和线性关键帧积分器(粉色)的数值结果的比较

image.png