CSS实现带重力的掉落动画_模拟物体下落反弹的物理效果

3次阅读

用单个@keyframes配合分段cubic-bezier缓动模拟重力下落与三次衰减弹跳,手动设置translatey像素值、触底压缩scaley及偏转rotate提升真实感。

CSS实现带重力的掉落动画_模拟物体下落反弹的物理效果

transform + animation 模拟重力下落,但别真写牛顿公式

css 做不出真实物理引擎,但能靠关键帧和缓动函数骗过眼睛。核心是用 cubic-bezier() 拟合加速下落 + 弹跳衰减——不是靠多段动画拼接,而是单个 @keyframes 里控制速度曲线。

  • 下落阶段用 cubic-bezier(0.2, 0.7, 0.4, 1)(先慢后快,模拟重力加速度)
  • 触底反弹用 cubic-bezier(0.1, 0.9, 0.2, 1)(快速回弹但幅度递减)
  • 别用 ease-in-out:它对称,而真实反弹是不对称的——下落快、回弹慢且短

animation-timing-function 必须分段写,不能只设一个全局值

一个动画里不同阶段需要不同缓动,CSS 不支持单 keyframe 内切缓动,所以得把整个过程拆成多个 animation 层叠,或用 @keyframes 手动定义每段的速度变化点。

  • 推荐方案:单个 @keyframes,在 0%60% 用下落缓动,60%85% 用第一次反弹,85%100% 用二次微弹
  • 错误写法:animation: fall 1.2s ease-in; —— 这只会匀速加速,没反弹感
  • 注意 animation-fill-mode: forwards,否则动画结束会跳回初始位置

反弹高度要逐次衰减,用 transform: translateY() 硬调数值

视觉上“弹三次”不等于时间上均分,而是位移幅度按约 60%→30%→10% 衰减。别指望 CSS 自动算衰减,得手动写死每段的 translateY 值。

  • 假设容器高 400px,下落终点是 translateY(380px)(留 20px 视觉缓冲)
  • 第一次反弹到 translateY(280px)(≈ 70% 高度),第二次到 translateY(340px)(小幅回弹),第三次到 translateY(370px)
  • 别用百分比单位做反弹:父容器尺寸变化时,反弹比例会错乱,固定像素更可控

真实感陷阱:忽略惯性延迟和旋转晃动,动画就假

刚体落地瞬间会有微小压缩+回弹,以及轻微偏转。纯垂直位移看着像PPT,加一点 scaleY(0.95)rotate(1deg) 能立刻提升可信度。

立即学习前端免费学习笔记(深入)”;

  • 在触底帧(比如 60%)加 transform: translateY(380px) scaleY(0.95) rotate(-1deg);
  • 反弹起始帧(61%)立刻恢复 scaleY(1) rotate(0),制造“弹起来”的干脆感
  • 慎用 will-change: transform:低端安卓机上可能引发闪烁,只在必要时加

物理细节越多,越容易在 safari 里掉帧。真正难的不是写出五次反弹,而是让第三次之后的微动不被用户察觉又不被浏览器优化掉。

text=ZqhQzanResources