You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用JavaScript实现正弦波参数平滑过渡无突变效果

正弦波参数平滑过渡(无突变)实现方案

问题简述

在After Effects里用JavaScript做蝴蝶翅膀摆动动画,用公式 amplitude * Math.sin(time*speed)+bias 控制翅膀Y轴角度,但修改幅度、速度或偏移参数时,动画会出现跳变或闪烁,需要实现参数切换时波形平滑无突变。

核心解决思路

问题根源在于两点:一是直接用time*speed作为正弦函数的输入,修改速度时这个值会突变,导致正弦输出跳变;二是直接切换幅度、偏移参数会让角度瞬间跳变。解决要点:

  1. 维护连续相位值:放弃time*speed的方式,改用累加的相位变量,每次按当前速度计算相位增量,修改速度只会改变相位增长的快慢,不会让相位跳变。
  2. 参数渐变过渡:修改幅度、速度、偏移时,不要直接赋值,而是在一段过渡时间内从旧值平滑过渡到新值,保证角度和变化率连续。

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]

效果说明

  • 相位逐帧累加,修改速度时只会改变相位增长的速率,不会让正弦函数的输入突然跳变,从根源避免波形突变。
  • 幅度、速度、偏移参数通过线性(或缓动)过渡,角度值会从旧参数的输出自然过渡到新参数的输出,不会出现瞬间跳变。

波形对比

  • 参数突变时的问题波形:
    问题波形1
    问题波形2
  • 平滑过渡后的目标波形:
    目标波形

内容的提问来源于stack exchange,提问作者Meeesta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 04:32:17