换向缓动:reverse 时别把 ease 也倒过来
播放控制里的 reverse 只是给 speed 取负,游标从此递减、
纯函数原样重采样。代价是:缓动曲线也被一起时间反演了。一条 expoOut (慢收尾) 正向播放是
「先快后慢」,倒放就成了 expoIn 的「先慢后快」——回退段因此显得生硬。easeReverse
(对齐 gsap 3.15 同名特性) 换一种做法:换向的那一刻记下当前位置作锚点,对剩余距离重新施加一条
正向缓动,于是回退段仍保有 ease-out 的减速收尾,而非把原曲线倒放。
naive reverse — 正向曲线时间反演 (回退段缓动方向被翻转)
end
easeReverse — 从换向点对剩余距离重施正向缓动
end
naive reverse
easeReverse
纵轴 = 值 (0→1),横轴 = 真实流逝时间 → 前半段两者重合,反向后分岔。
naive 0.00
easeReverse 0.00
progress 0.00
状态 idle
duration 一半 (线性时间进度 0.5) 时翻向回退——
注意 expoOut「先快后慢」,此刻值已 ≈ 0.97,球看着已近终点,可见时间的一半 ≠ 运动的一半。
看两条曲线在反向点后如何分岔——灰蓝的 naive 把上升曲线镜像着倒回来 (上升快的区段回落也陡);
主色的 easeReverse 从锚点起另画一段减速收尾的新曲线,平滑落回 0。关掉自动、手动点立即反向
可在任意时刻打断,锚点即时重置,回退依旧平滑。
@vega/anim — 一个
easeReverse 开关
实现要点:换向瞬间冻结锚点 (anchorRatio, anchorQ),之后每帧按
ratio = anchorRatio + scale · ease(τ) 重算,其中 τ 是「换向后经过的进度 / 剩余进度」,
恒为 0→1。τ=0 时 ratio=anchorRatio 保证换向连续不跳变,τ=1 时精确落到端点。
与 时序里 repeatType:reverse 的往返不同:那是每次迭代整体的时间反演,
这里是单次播放中途换向、且对剩余距离重施正向缓动。因输出依赖换向历史,sampleAt(t) 仍返回
anchor-off 的正向曲线 (保持纯函数),live 播放值才体现锚点。