动画引擎原理 总览待审核
rubber-band · over-scroll · 阻尼

橡皮筋:越界阻尼与回弹

iOS 列表拖到顶 / 底还能再拽一段,但越拽越沉,松手「啪」地弹回——这就是橡皮筋 over-scroll。它由两段拼成:边界之内内容 1:1 跟手;越界之后,真实位移按一个 阻尼函数对跟手位移做压缩,渐近饱和,怎么拽都到不了无穷。松手时若已越界,用 createSpring 把内容弹回边界;若在界内甩动,则用 createDecay 带着初速度滑行,滑出界再被橡皮筋拉住。下面这块可上下拖动,虚框是「跟手位移」、实色块是「实际位移」。

在框内按住上下拖,拽过橙色边界看阻尼;松手看回弹。蓝虚框=跟手位移

跟手
Item 01
Item 02
Item 03
Item 04
Item 05
状态 静止 跟手位移 0 实际位移 0 越界量 0
阻尼函数 offset = limit + d·(1 − 1 / (x/d + 1)):其中 x 是跟手位移、limit 是边界、d 是阻尼系数 (px)。 它有三个关键性质。其一 渐近饱和:x→∞ 时 offset → limit + d,越界量被压在 d 以内,所以怎么拽都拽不穿。 其二 单调且 C¹ 连续:在边界处 (x=limit) 斜率恰为 1,与界内的 1:1 跟手无缝衔接,不会有突变的「卡顿感」。 其三 可逆:函数严格递增,每个实际位移唯一对应一个跟手位移,松手回弹与继续拖拽之间能平滑切换。 这也是它和普通拖拽的根本区别——普通拖拽全程 1:1,橡皮筋只在越界段引入这条压缩曲线。
@vega/anim — 越界阻尼公式 + 松手弹回边界的 spring

  

回弹用的是弹簧:松手即以当前越界量和速度建一条 createSpring, 目标 to 设为边界值,它能接住甩动速度自然收敛。界内甩动的惯性滑行交给 惯性衰减 (createDecay),滑出界后再切回橡皮筋拉力。 把橡皮筋接到真实 pointer 手势上、做成可复用的拖拽行为,见手势