CSS如何实现具有弹性的弹跳动效_利用cubic-bezier自定义速度曲线css

5次阅读

cubic-bezier() 是纯 css 实现真实弹跳动效的唯一可行路径,因其能通过自定义控制点使速度中途反向(y>1 或 y

CSS如何实现具有弹性的弹跳动效_利用cubic-bezier自定义速度曲线css

为什么 cubic-bezier() 是弹跳动效的唯一可行路径

css 实现真实弹跳(bouncing),不能靠 animation-timing-function: ease-out 或重复 keyframes 模拟——它只是减速,没有回弹、过冲、衰减。真正有物理感的弹跳必须用自定义贝塞尔曲线,因为只有 cubic-bezier() 能让速度在动画中途“反向”(y 值 > 1 或

浏览器原生支持的 timing function 中,只有 cubic-bezier() 允许控制点超出 [0,1] 范围(如 cubic-bezier(0.2, 0.8, 0.4, 1.4)),这是实现“冲过头再弹回”的关键。

常见错误:直接抄网上“弹跳贝塞尔值”却不验证是否符合 CSS 规范——CSS 要求 x1/x2 ∈ [0,1],但 y1/y2 可以任意(现代浏览器都支持)。若误把 y1 写成 1.8 但 x1 写成 -0.1,会直接被忽略并退化为 ease

怎么写出一个可用的弹跳 cubic-bezier() 曲线

别从头手调四个参数。用工具辅助生成,再微调。核心逻辑是:前半段快速下落 → 底部猛烈过冲 → 多次小幅回弹 → 最终静止。

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

  • 推荐起始模板:cubic-bezier(0.34, 1.56, 0.64, 1)(基础单次弹跳)
  • 要更“松软”:降低 y1(如 1.2),提高 y2(如 1.1)→ 回弹更缓
  • 要更“硬脆”:提高 y1(如 1.8),降低 y2(如 0.8)→ 首次过冲更猛,后续衰减快
  • 想加第二次小弹跳:把 y2 设为略大于 1(如 1.05),让曲线在末尾轻微上扬

实操建议:在 chrome DevTools 的 animation 面板里实时拖拽贝塞尔手柄,观察曲线形状和预览效果;不要只看数值。

transform: translateY() + cubic-bezier() 的典型用法与坑

弹跳动效几乎总是作用于 transform,而非 topmargin——前者触发合成层,性能好;后者触发布局重排,一卡就废。

常见错误现象:animation 播放一次后不重置位置,导致第二次点击从错误起点开始弹。

  • 务必在动画结束时显式归位,例如用 transform: translateY(0) 写在 @keyframesto 或 100%
  • 如果用 animation-fill-mode: forwards,确保 to 状态是最终静止态(不是弹跳中途某帧)
  • 移动端要注意:ios safari 对超范围 y 值(如 y1=2.1)兼容性略差,稳妥起见 y1 控制在 ≤1.9,y2 ≥0.7
  • 避免和 transition 混用:同时存在时,transition 会覆盖 animation 的 timing function

多段弹跳(比如三次回弹)还能用纯 CSS 吗

能,但别写三段 @keyframes 硬凑。复杂弹跳应拆解为多个连续动画,用 animation-delay 错开,并逐段调整 cubic-bezier() 参数模拟衰减。

示例思路(单次点击触发三段弹跳):

button:hover {   animation:      bounce-1 0.6s cubic-bezier(0.34, 1.56, 0.64, 1),     bounce-2 0.4s cubic-bezier(0.22, 0.8, 0.56, 1.2) 0.6s,     bounce-3 0.25s cubic-bezier(0.18, 0.7, 0.42, 1.05) 1.0s; }

关键点:

  • 每段动画的 transform 起始值必须承接上一段的结束值(靠 animation-fill-mode: forwards 保证)
  • 第二、三段的 cubic-bezier() y1 逐级降低(1.2 → 1.05),体现能量衰减
  • 总时长 = 各段时长 + 延迟之和,别漏算

真正难的不是写出来,而是让每次回弹的幅度、节奏看起来自然——这取决于你调参时有没有盯着真实弹簧或篮球录像看两分钟。

text=ZqhQzanResources