使用 linear() 加/减速函数在 CSS 中制作复杂的动画曲线

介绍 linear(),这是一个 CSS 中的缓动函数,可在其点之间进行线性插值,让您能够重新创建弹跳和弹簧效果。

CSS 中的缓动效果

在 CSS 中为元素添加动画或过渡效果时,您可以使用 animation-timing-functiontransition-timing-function 属性通过缓动函数来控制值的变化速率。

CSS 中提供了多个可用作预设的关键字,即 lineareaseease-inease-outease-in-out。如需创建自己的缓动曲线,请使用 cubic-bezier() 函数,或使用 steps() 缓动函数采用基于步骤的方法。

适当使用缓动效果可让动画元素在看似积蓄动量时给人以重量感。

在 CSS 中无法创建弹跳或弹簧效果等复杂曲线,但得益于 linear(),您现在可以非常精确地近似创建这些效果。

linear() 简介

浏览器支持

  • Chrome:113.
  • Edge:113.
  • Firefox:112.
  • Safari:17.2。

在 CSS 中定义缓动效果的新方法是使用 linear()。此函数接受以英文逗号分隔的多个经停点。每个停止点都是一个介于 0 到 1 之间的数字。在每个停止点之间,系统会以线性方式进行插值,这也解释了该函数的名称。

animation-timing-function: linear(0, 0.25, 1);

这些经停点默认分布均匀。在上面的代码段中,这意味着在 50% 时刻将使用 0.25 的输出值。

直观地看,linear(0, 0.25, 1) 的图表如下所示:

线性函数(0, 0.25, 1) 的图表可视化结果。

如果您不希望相应经停点均匀分布,可以选择传入经停点长度。将一个值作为停止时长传入时,您需要定义其起始点:

animation-timing-function: linear(0, 0.25 75%, 1);

在这里,0.25 的输出值将不会在 50% 标记处使用,而是在 75% 处使用。

线性函数(0, 0.25 75%, 1) 的图表可视化结果。

将两个值指定为停止时长时,您需要同时定义其起点和终点:

animation-timing-function: linear(0, 0.25 25% 75%, 1);

在 25% 到 75% 的时间段内,输出值为 0.25。

线性函数(0, 0.25 25% 75%, 1)的图表可视化结果。

使用 linear() 创建复杂曲线

虽然上述示例非常简单,但您可以使用 linear() 以非常简单的方式重新创建复杂的缓动函数,但代价是会丢失一些精度。

以此弹跳缓动曲线为例,这种缓动类型无法直接用 CSS 表达,而是使用 JavaScript 定义的:

function easing(pos) {
  const t = 7.5625;
  const e = 2.75;
  return pos < 1 / e
    ? t * pos * pos
    : pos < 2 / e
    ? t * (pos -= 1.5 / e) * pos + 0.75
    : pos < 2.5 / e
    ? t * (pos -= 2.25 / e) * pos + 0.9375
    : t * (pos -= 2.625 / e) * pos + 0.984375;
}

虽然代码可能无法提供太多信息,但可视化图表可能会有所帮助。以下是输出结果,以蓝色曲线表示:

以蓝色绘制的平滑弹跳曲线。

您可以通过在曲线上添加多个停止点来简化曲线。其中,每个绿点都表示一个经停点:

蓝色的平滑弹跳曲线,上面有绿色圆点。

传入 linear() 后,结果是一个看起来有点像原始曲线的曲线,但边缘略粗糙。

绿色的简化曲线叠加在蓝色的原始平滑曲线上。

将绿色动画框与蓝色动画框进行比较,您可以发现它不太流畅。

不过,如果您添加了足够多的停止点,就可以很好地近似原始曲线。更新后的版本如下:

更新后的曲线,经停点数量翻了一番。

只需将停靠点数量翻倍,您就可以获得平滑的结果。

用于实现动画的代码如下所示:

animation-timing-function: linear(
  /* Start to 1st bounce */
  0, 0.004, 0.016, 0.035, 0.063 9.1%, 0.141, 0.25, 0.391, 0.563, 0.765, 1,
  /* 1st to 2nd bounce */
  0.891, 0.813 45.5%, 0.785, 0.766, 0.754, 0.75, 0.754, 0.766, 0.785, 0.813 63.6%, 0.891, 1 72.7%,
  /* 2nd to 3rd bounce */
  0.973, 0.953, 0.941, 0.938, 0.941, 0.953, 0.973, 1,
  /* 3rd bounce to end */
  0.988, 0.984, 0.988, 1
);

一款实用工具

手动创建此经停点列表非常麻烦。幸运的是,JakeAdam 创建了一款工具,可帮助您将缓动曲线转换为 linear() 对应曲线

线性缓动生成器工具的屏幕截图。
https://linear-easing-generator.netlify.app/ 在使用中的屏幕截图。

该工具将 JavaScript 缓动函数或 SVG 曲线作为输入,并使用 linear() 输出简化后的曲线。使用滑块控制所需的停靠点数量及其精度。

您还可以在右上角选择以下任一预设:弹簧、弹跳、简单弹性或 Material Design 强调缓动。

开发者工具支持

开发者工具支持可视化和修改 linear() 的结果。点击该图标可显示一个互动式提示,让您可以拖动相应经停点。

Chrome 开发者工具的 `linear()` 编辑器的屏幕截图。
Chrome DevTools 的 `linear()` 编辑器的屏幕截图。

此开发者工具功能在 Chrome 114 中随附的开发者工具中提供。

照片由 Howie Mapson 拍摄,选自 Unsplash