前端也要懂物理 —— 惯性滚动篇 (3)

很明显,这样的速度曲线过于线性平滑,减速效果不明显。我们参考 iOS 滚动回弹的效果重复测试,调整贝塞尔曲线的参数为 cubic-bezier(.17, .89, .45, 1):

调整后的贝塞尔曲线

调整曲线后的效果理想很多:

调整后的曲线效果

回弹

接下来模拟惯性滚动时触碰到容器边界触发回弹的情况。

我们基于滑块模型来模拟这样的场景:滑块左端与一根弹簧连接,弹簧另一端固定在墙体上,在滑块向右滑动的过程中,当滑块到达临界点(弹簧即将发生形变时)而速度还没有降到 0m/s 时,滑块会继续滑动并拉动弹簧使其发生形变,同时滑块会受到弹簧的反拉力作减速运动(动能转化为内能);当滑块速度降为 0m/s 时,此时弹簧的形变量最大,由于弹性特质弹簧会恢复原状(内能转化成动能),并拉动滑块反向(左)运动。

类似地,回弹过程也可以分为下面两个阶段:

滑块拉动弹簧往右做变减速运动;

回弹第一阶段模型

此阶段滑块受到摩擦力 F摩 和越来越大的弹簧拉力 F弹 共同作用,加速度越来越大,导致速度降为 0m/s 的时间会非常短。

弹簧恢复原状,拉动滑块向左做先变加速后变减速运动;

回弹第二阶段模型

此阶段滑块受到的摩擦力 F摩 和越来越小的弹簧拉力 F弹 相互抵消,刚开始 F弹 > F摩,滑块做加速度越来越小的变加速运动;随后 F弹 < F摩,滑块做加速度越来越大的变减速运动,直至最终静止。这里为了方便实际计算,我们不妨假设一个理想状态:当滑块静止时弹簧刚好恢复形变

回弹距离

根据上面的模型分析,回弹的第一阶段做加速度越来越大的变减速直线运动,不妨设此阶段的初速度为 v0,末速度为 v1,那么可以与滑块位移建立关系:

回弹第一阶段位移

其中 a 为加速度变量,这里暂不展开讨论。那么,根据物理学的弹性模型,第二阶段的回弹距离为

回弹第二阶段位移

微积分都来了,简直没法计算……

然而,我们可以根据运动模型适当简化 S回弹 值的计算。由于 回弹第二阶段的加速度 是大于 非回弹惯性滚动阶段的加速度(F弹 + F摩 > F摩)的,不妨设非回弹惯性滚动阶段的总距离为 S滑,那么

回弹距离关系

因此,我们可以设置一个较为合理的常量 B,使其满足这样的等式:

回弹距离等式

经大量实践得出,常量 B 的合理值为 10。

回弹速度曲线

触发回弹的整个惯性滚动轨迹可以拆分成三个运动阶段:

触发回弹的运动轨迹

然而,如果要把阶段 a 和阶段 b 准确描绘成 CSS 动画是有很高的复杂度的:

阶段 b 中的变减速运动难以准确描绘;

这两个阶段虽运动方向相同但动画速度曲线不连贯,很容易造成用户体验断层;

为了简化流程,我们把阶段 a 和 b 合并成一个运动阶段,那么简化后的轨迹就变成:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpjsdz.html