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

JS easeInOutQuad缓动函数中(--t)表达式运算逻辑与公式推导

jQuery Easing easeInOutQuad 缓动函数 else 分支逻辑拆解
// jQuery Easing 内置 easeInOutQuad 源码
easeInOutQuad: function (t, b, c, d) {
  if ((t/=d/2) < 1) return c/2*t*t + b;
  return -c/2 * ((--t)*(t-2) - 1) + b;
}

核心运算符运算顺序说明

  • 前置自减运算符--t优先级高于乘、减运算:执行时先将当前作用域内的t值减1,再用更新后的新值参与后续所有表达式计算,不存在旧值、新值混用的情况。
  • 进入else分支前,(t/=d/2)的复合赋值已经执行完毕:此时内部变量t已经被更新为「当前时间/半程时长」的值,范围为[1, 2](因为进入else意味着这个值不小于1,而原始t最大为d,除以d/2后最大值为2)。

else分支等价无简写写法推导

把前置自减、复合赋值全部替换为显式变量赋值,逻辑和原函数100%一致:

// else分支等价显式写法,无自减、无复合赋值
const tScaled = t / (d / 2); // 和if判断中的缩放逻辑完全一致
const tAdjusted = tScaled - 1; // 完全等价于原代码中--t的运算结果
return -c / 2 * (tAdjusted * (tAdjusted - 2) - 1) + b;

原代码用自减运算符只是代码简写,没有特殊逻辑,本质是将后半段缩放后范围为[1,2]的时间值偏移到[0,1]区间,和前半段的时间区间对齐,构造对称的缓动曲线。

计算逻辑验证

可以代入边界值验证正确性:

  • 动画中点(t = d/2):tScaled = 1,tAdjusted = 0,代入计算得-c/2 * (0*(0-2) -1) + b = b + c/2,和if分支在中点的计算结果完全一致,动画无断点。
  • 动画终点(t = d):tScaled = 2,tAdjusted = 1,代入计算得-c/2 * (1*(1-2) -1) + b = b + c,完全符合动画终点的预期值。

对表达式做代数化简后可以看出,后半段是和前半段对称的二次减速曲线,两段曲线在中点处值、斜率都连续,实现平滑的先加速后减速效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 10:24:16