AEJoy —— 表达式之惯性模拟详解【JS】

399 阅读1分钟

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

效果图

1. 惯性表达式:位置属性

100.gif

2. 惯性表达式:旋转属性

101.gif

3. 惯性表达式:缩放属性

102.gif

表达式代码与详解

详见代码注释

n = 0; ///< 用于保存当前时间(之前)临近的关键帧索引
if (numKeys > 0) {
    /// @note 获取离当前时间最近的关键帧索引
    n = nearestKey(time).index;
    
    /// @note 如果当前时间尚未达到该关键帧的时间,
    /// 则使用前一个关键帧的索引
    if (key(n).time > time) {
        n--;
    }
}

if (n == 0) { ///< 第一个关键帧之前,则无视
    t = 0;
} else {///< 计算当前时间和该关键帧时间的差值
    t = time - key(n).time;
}

if (n > 0) {
    /// @note 首先获取第 n 个关键帧的时间,然后稍稍提前一些(一帧时间的十分之一)
    /// 然后根据计算出的时间,得到对应的速度
    v = velocityAtTime(key(n).time - thisComp.frameDuration / 10);
    amp = 3;
    freq = 2.0;
    decay = 3.0;
    
    /// @note 关键 “惯性” 模拟计算
    value + (v / 100) * amp * Math.sin(freq * t * 2 * Math.PI) / Math.exp(decay * t);
} else {
    value;
}

其中这部分计算的函数示意图如下

amp * Math.sin(freq * t * 2 * Math.PI) / Math.exp(decay * t)

image.png

可见其速度在一定的震荡周期内会逐渐趋近于 0 。

(完)