使用JavaScript实现正弦波参数平滑过渡无突变效果
正弦波参数平滑过渡(无突变)实现方案
问题简述
在After Effects里用JavaScript做蝴蝶翅膀摆动动画,用公式 amplitude * Math.sin(time*speed)+bias 控制翅膀Y轴角度,但修改幅度、速度或偏移参数时,动画会出现跳变或闪烁,需要实现参数切换时波形平滑无突变。
核心解决思路
问题根源在于两点:一是直接用time*speed作为正弦函数的输入,修改速度时这个值会突变,导致正弦输出跳变;二是直接切换幅度、偏移参数会让角度瞬间跳变。解决要点:
- 维护连续相位值:放弃
time*speed的方式,改用累加的相位变量,每次按当前速度计算相位增量,修改速度只会改变相位增长的快慢,不会让相位跳变。 - 参数渐变过渡:修改幅度、速度、偏移时,不要直接赋值,而是在一段过渡时间内从旧值平滑过渡到新值,保证角度和变化率连续。
AE表达式代码实现
先给图层添加以下滑块控件(可设置为隐藏):目标幅度、目标速度、目标偏移、过渡时长、参数修改时间、相位、当前幅度、当前速度、当前偏移。然后将下面的表达式粘贴到翅膀的Y轴角度属性上:
// 读取控件参数 targetAmp = effect("目标幅度")("滑块"); targetSpeed = effect("目标速度")("滑块"); targetBias = effect("目标偏移")("滑块"); transDur = effect("过渡时长")("滑块"); // 建议设0.3-0.5秒 changeTime = effect("参数修改时间")("滑块"); // 初始化状态 if (time < changeTime - transDur || numKeys == 0) { prevPhase = 0; currAmp = targetAmp; currSpeed = targetSpeed; currBias = targetBias; } else { // 读取上一帧的状态值 prevPhase = effect("相位")("滑块").valueAtTime(time - thisComp.frameDuration); currAmp = effect("当前幅度")("滑块").valueAtTime(time - thisComp.frameDuration); currSpeed = effect("当前速度")("滑块").valueAtTime(time - thisComp.frameDuration); currBias = effect("当前偏移")("滑块").valueAtTime(time - thisComp.frameDuration); } // 处理参数平滑过渡 timeElapsed = time - changeTime; if (timeElapsed > 0 && timeElapsed < transDur) { t = timeElapsed / transDur; // 用linear做线性过渡,换成ease(t,0,1,...)可实现缓入缓出效果 currAmp = linear(t, 0, 1, currAmp, targetAmp); currSpeed = linear(t, 0, 1, currSpeed, targetSpeed); currBias = linear(t, 0, 1, currBias, targetBias); } else if (timeElapsed >= transDur) { currAmp = targetAmp; currSpeed = targetSpeed; currBias = targetBias; } // 更新相位(逐帧累加,保证连续) phaseStep = currSpeed * thisComp.frameDuration; currPhase = prevPhase + phaseStep; // 计算当前翅膀角度 angle = currAmp * Math.sin(currPhase) + currBias; // 将当前状态写入隐藏控件,供下一帧读取 effect("相位")("滑块").setValue(currPhase); effect("当前幅度")("滑块").setValue(currAmp); effect("当前速度")("滑块").setValue(currSpeed); effect("当前偏移")("滑块").setValue(currBias); // 返回最终角度值 [angle, 0, 0]
效果说明
- 相位逐帧累加,修改速度时只会改变相位增长的速率,不会让正弦函数的输入突然跳变,从根源避免波形突变。
- 幅度、速度、偏移参数通过线性(或缓动)过渡,角度值会从旧参数的输出自然过渡到新参数的输出,不会出现瞬间跳变。
波形对比
- 参数突变时的问题波形:


- 平滑过渡后的目标波形:

内容的提问来源于stack exchange,提问作者Meeesta
相关产品推荐
相关产品推荐

