物理手感
手指抬起后会发生什么?后续的一切运动,都由物理系统接管 — 动量、摩擦、弹簧、弹性边界。正是这些看不见的力, 让手势驱动的界面显得自然而鲜活。
Part A · 抬手后阶段
抬手之后
手指离开屏幕的瞬间,速度不会凭空消失 — 它传递给了内容。 理解动量、摩擦与衰减预测,是打造"物理上可信"的交互手感的基础。
Momentum(动量)
你甩动手机里的列表时,列表不会在抬手瞬间戛然而止, 而是继续滑行,仿佛带着惯性。这就是 momentum scrolling — 释放瞬间采样到的速度,被完整地带入了后续运动。
没有动量,每次滚动都像在泥里拖行。加入动量后, 一次轻快的 flick 就能把内容送到更符合预期的位置。
Friction(摩擦)
动量不会无限持续。摩擦让内容逐步减速,直至停下。 摩擦系数,是滚动手感中最重要的调参旋钮之一。
iOS 和 Android 的摩擦参数并不相同 — 这也是同样的甩动动作 在不同平台手感迥异的原因之一。摩擦太小会"打滑",太大则"发粘"。
用下面这个滑块直接感受差异:
Decay(衰减)
动量给出了初始速度,接下来呢?速度不会瞬间归零, 而是沿着指数曲线衰减:前段减速猛烈,后段渐趋平缓。
这种形状正是"自然减速感"的来源。线性减速像匀速刹车,显得机械; 指数衰减更像真实摩擦 — 速度越低,阻力的效果越微弱。
试着甩动下方圆点,观察 ghost 标记:它们在时间上等间隔, 在空间上却不等间隔。起始处间距大、末尾处间距密 — 这正是衰减曲线的可视化写照。
fig-201 · exponential decayPart B · 弹簧阶段
弹簧
弹簧是响应式动画的根基。与固定时长的动画不同, 弹簧可以在任意时刻被打断并平滑续接 — 界面因此显得流动,而非僵硬。
为什么用弹簧?
你下拉一个面板然后松手,它弹了回去。这个"弹回"不是预设的定时动画, 而是实时模拟出来的弹簧过程。这一区别至关重要。
“用时长和缓动曲线参数化的动画 API,
在底层上与连续、流体的交互是冲突的。”
— Andy Matuschak,前 Apple UIKit 团队
传统 CSS 动画由 时长 + 缓动曲线定义
(例如 transition: 0.3s ease-in-out)。
这种方式有一个硬伤:动画难以优雅地被中断。若用户在动画途中再次触摸,
系统通常只能"跳到终点"或"从头重来" — 两者都不自然。
弹簧之所以更适合交互,因为它基于状态,而非基于时间。 弹簧随时知道自己的位置和速度;任意时刻都能改变目标,它会在保留动量的前提下 平滑转向。弹簧没有固定"总时长" — 何时稳定,由物理状态决定。
弹簧性格
一条弹簧的“性格”主要由 stiffness(刚度) 和 damping(阻尼)决定:
| 手感 | 参数特征 | 适用场景 |
|---|---|---|
| 弹跳 | 高刚度、低阻尼 | 趣味交互、开关、徽章 |
| 利落 | 中等刚度、接近临界阻尼 | 抽屉关闭、导航过渡、主流 UI |
| 厚重 | 较低刚度、过阻尼 | 模态层、重要状态切换 |
Elastic(弹性)
Elastic 可以理解为"过冲更加夸张的弹簧"。普通弹簧会相对平稳地靠近目标; Elastic 则故意越过目标,并做可见的振荡,像橡皮筋回弹。
这种效果一般通过降低阻尼(让振荡持续更久)、同时保持较高刚度来获得。 结果是更跳跃、更抓眼球的动态表现。
Elastic 适合少量、点睛式使用,典型场景包括:
- 庆祝时刻 — 徽章、成就、成功确认
- 吸引注意 — 需立即处理的通知或错误
- 玩味 UI — 开关、反应、表情交互
切忌将 Elastic 用在高频动作上 — 过度弹跳在高重复场景中会迅速造成视觉疲劳。
fig-202b · elastic springFling & Snap(甩动与吸附)
很多界面在抬手后,需要将位置量化到离散值。 轮播吸附到整页、抽屉吸附到开/关状态、选择器吸附到离散选项 — 都是典型场景。
常见模式是:释放时先用指数衰减预测内容的自然停点
— target = pos + v / (1 − decayRate),
然后将预测结果四舍五入到最近合法吸附点,再用
临界阻尼弹簧(ζ = 1.0)驱动到目标。
fling 速度注入弹簧初速度,确保过渡连续 —
不跳变、不停顿。甩得快则预测更远,可能跨项;甩得慢则倾向就近吸附。
Part C · 边界阶段
边界行为
到达边缘时该怎么办?硬停像撞墙。弹性边界则能在表达"已到极限"的同时, 维持连续物理世界的错觉。
Rubber Band / Overscroll(橡皮筋 / 超滚动)
当你把内容拖过可滚动区域的边界,该发生什么? 直接停死会像撞墙。多数平台采用 rubber band 效果: 内容继续跟手,但阻力越来越大,像在拉伸一根弹性带。
关键在于:越界后"手指位移 → 视觉位移"的映射变成了 非线性。你越往外拖,每像素手指移动所带来的内容位移就越小。
这本质上是一种信息传达机制:递增的阻力在告诉用户 "你已经到边界了" — 比硬停更温和,也更合乎直觉。
Bounce-Back(回弹)
Bounce-back 是 rubber band 的收尾机制。Rubber band 管的是越界拖动过程中的行为; Bounce-back 管的是越界状态在释放之后如何收敛。
手指抬起时,若内容仍在越界区间,弹簧会将它拉回最近合法边界。 这个衔接必须连续:弹簧的起点应取 rubber-banded 后的显示位置,而非原始手指位置 — 否则拖动结束到回弹开始的瞬间会出现视觉跳变。
Rubber band + bounce-back,共同构成了你在 iOS 滚动末端常感受到的"弹性吸附"。 它像物理,而不像写死的逻辑 — 这正是好的边界行为该有的样子。
fig-205 · overscroll bounce综合起来看
本章的这些机制会协同运作,形成流畅而即时的交互体验:
- Momentum — 释放时继承速度
- Friction — 持续减速
- Decay — 指数减速与目标预测
- Springs — 可中断、状态驱动动画
- Fling & snap — 基于衰减预测,再用临界阻尼弹簧吸附到最近目标
- Rubber band — 边界处的弹性阻力
- Bounce-back — 越界后的弹簧回归
下一章,我们将看到这些原语如何组合成 交互模式 — 下拉刷新、轮播、可重排网格、橡皮筋滑杆。