CSS - 缓动函数



CSS 缓动函数用于控制元素的两种状态之间的过渡或动画的速度。它定义了属性随时间的变化率,影响动画期间的加速和减速。

以下是一些值得注意的要点:

  • 两个值之间的过渡可以在各种上下文(包括动画)中应用,以控制值更改的速率。
  • 这允许在整个持续时间内动态调整动画速度。
  • 可以使用松动函数自定义 CSS <transitions><animations> 属性以指定此行为。

缓动函数的类型

CSS 中可以使用三种主要类型的缓动函数,如下所示:

  • 线性函数(linear),
  • 三次贝塞尔函数(包括缓动、缓入、缓和缓入)、
  • 楼梯功能(台阶)。

线性(Linear)函数

使用线性计时功能,动画以恒定速度通过关键帧。可以传递以下关键字:

  • linear - 动画以恒定速度进行。
  • linear-easing-function - 这描述了 linear() 函数,用于管理动画或过渡的进度。它使用一个停止列表,即 linear-stop-list,其中每个点都被指定为 0 到 1 之间的数字。这可以具有 <number><percentage> 值。

三次贝塞尔(Cubic Bezier)函数

CSS 中的此功能定义了影响动画或过渡进程的贝塞尔曲线,该曲线具有四个控制点:一个起点、一个结束点和两个控制点。

它有助于创建自定义缓动效果。三次贝塞尔函数由四个控制点定义,它允许对动画的加速和减速进行精确控制。预定义的关键字值包括:

  • ease - 这个术语代表逐渐的初始插值,然后是快速加速和接近结束时的逐渐减速。该项对应于弛豫函数 cubic-bezier(0.25, 0.1, 0.25, 1.0)。
  • ease-in - 这个术语意味着插值逐渐开始,然后变得越来越快,直到最后突然停止。此关键字对应于缓动函数 cubic-bezier(0.42, 0.0, 1.0, 1.0)。
  • ease-out - 此术语表示插值突然开始,然后在接近结束时逐渐减慢。此关键字对应于缓动函数 cubic-bezier(0.0, 0.0, 0.58, 1.0)。
  • ease-in-out - 此关键字表示开始缓慢、加速,然后在接近结束时减慢的插值。它使用松弛函数 cubic-bezier(0.42, 0.0, 0.58, 1.0),其行为类似于开始时的缓入和结束时的缓和出。

<cubic-bezier()> - 此函数使用四个 <number> 值来定义曲线的形状。立方-贝塞尔(x1, y1, x2, y2)

X 坐标(x1 和 x2)表示时间比率,并且限制为 0 和 1 之间的值(动画不能早于指定时间开始或持续时间不能超过指定时间),而 Y 坐标(y1 和 y2)表示动画输出及其值。

步进(Step)函数

Steps 函数使动画能够以非连续方式在特定数量的帧之间跳转。你可以把它看作是一个“滴答作响”的动画。它接受以下关键字:

step-start - 此关键字表示缓动函数 steps(1, jump-start) 或 steps(1, start)。它表示突然跳转到插值的最终状态,并保持此状态直到完成。

step-end - 此关键字表示缓动函数 steps(1, jump-end) 或 steps(1, end)。这意味着插值会保持其初始状态,直到最后,然后迅速变为最终状态。

steps() - 此函数采用正<integer>和可选的<step-position>。

  • <integer> - 表示均匀间隔或步长的数量。它应该是大于 0 的正整数,除非第二个参数是 jump-none,在这种情况下,它必须是大于 1 的正整数。
  • <step-position> - 指定跳转发生的时间 — 在开始时、在结束时、在开始和结束时,或者两者都不发生。可用的关键字值包括:
    • jump-start - 这意味着初始跳跃发生在开始时,基本上在点 0,没有在 0% 标记处花费任何时间。
    • jump-end - 这意味着最后一次跳跃恰好发生在最后,基本上是在第 1 点,没有在 100% 标记处花费任何时间。如果未指定 <step-positionion>,则这是默认值。
    • jump-none - 这将消除开始和结束时的跳跃,并省略持续时间中的一个步骤。在 0% 和 100% 标记处,进度保持稳定,持续时间是通过将总持续时间除以步骤数 (1/n) 来确定的。
    • jump-both - 这涉及在开始和结束时的跳跃,分别发生在 0 和 1 点。这实际上在两端都增加了一个步骤,没有在 0% 和 100% 标记处花费时间。
    • start - 是 jump-start 的等效术语。
    • end - 是 jump-end 的等效术语

语法


/* linear function and keyword */
/* linear(<point-list>) */
linear(1, -0.5, 0)
linear

/* cubic-bezier function and keywords */
/* cubic-bezier(<x1>, <y1>, <x2>, <y2>) */
cubic-bezier(0.25, 0.1, 0.25, 1)
ease
ease-in
ease-out
ease-in-out

/* steps function and keywords */
/* steps(<number-of-steps>, <direction>) */
steps(4, end)
steps(10, jump-both)
step-start
step-end 	

CSS 缓动函数 -  linear-easing

以下示例创建一个红色框,该框使用 linear-easing 函数水平移动。动画的持续时间为 4 秒,并无限重复,导致盒子连续来回移动。


<html>
<head>
<style>
	 	.box {
	 	 	 width: 100px;
	 	 	 height: 100px;
	 	 	 margin: 150px;
	 	 	 background-color: red;
	 	 	 text-align:center;
	 	 	 font-size:20px;
	 	 	 position: relative;
	 	 	 display: flex;
	 		 	 	 justify-content: center;
	 		 	 	 align-items: center;
	 	 	 animation: move 4s linear infinite;
	 	}
	 	@keyframes move {
	 	 	 0% {
	 	 	 	 	left: 5%;
	 	 	 }
	 	 	 100% {
	 	 	 	 	left: 60%;
	 	 	 }
	 	}
</style>
</head>
<body>
	 	<div class="box">Linear Easing Function</div>
</body>
</html>

CSS easeing-function - 带值的 linear-easing

以下示例演示了接受值的各种 linear-easing 函数。

动画从位置 0 开始,一直向前移动到 0.25。之后,它继续沿直线前进,直到达到 1。动画在其运行时的进展由符号 linear(0, 0.25, 75%, 1) 表示。


<html>
<head>
<style>
	 	.box {
	 	 	 width: 100px;
	 	 	 height: 100px;
	 	 	 margin: 150px;
	 	 	 background-color: red;
	 	 	 text-align:center;
	 	 	 display: flex;
	 	 	 justify-content: center;
	 	 	 align-items: center;
	 	 	 font-size:20px;
	 	 	 position: relative;
	 	 	 animation: move 4s linear infinite;
	 	}
	 	.linear-demo-1 {
	 	 	 animation-name: linear-custom;
	 	 	 animation-timing-function: linear(0, 0.25 75%, 1);
	 	}
	 	 @keyframes linear-custom {
	 	 	 from {transform: translateX(0);}
	 	 	 to {transform: translateX(350px);}
	 	}
</style>
</head>
<body>
<div class="box linear-demo-1">Linear Custom</div>
</body>
</html>

CSS 缓动函数 - cubic-bezier

以下示例演示了各种 cubic-bezier 函数。

缓入框开始慢速并加速,缓入框开始快速并减慢,缓入框开始慢速,中间加速,然后在动画结束时减慢。


<html>
<head>
<style>
	 	.box {
	 	 	 width: 100px;
	 	 	 height: 100px;
	 	 	 background-color: #0077FF;
	 	 	 margin: 20px auto;
	 	 	 animation-duration: 4s;
	 	 	 animation-iteration-count: infinite;
	 	 	 text-align: center;
	 	 	 font-size: 20px;
	 	 	 display: flex;
	 	 	 justify-content: center;
	 	 	 align-items: center;
	 	}
	 	.ease-in-demo {
	 	 	 animation-name: easeIn;
	 	 	 animation-timing-function: ease-in;
	 	}
	 	.ease-out-demo {
	 	 	 animation-name: easeOut;
	 	 	 animation-timing-function: ease-out;
	 	}
	 	.ease-in-out-demo {
	 	 	 animation-name: easeInOut;
	 	 	 animation-timing-function: ease-in-out;
	 	}
	 	@keyframes easeIn {
	 	 	 from {transform: translateX(0);}
	 	 	 to {transform: translateX(400px);}
	 	}
	 	@keyframes easeOut {
	 	 	 from {transform: translateX(0);}
	 	 	 to {transform: translateX(400px);}
	 	}
	 	@keyframes easeInOut {
	 	 	 from {transform: translateX(0);}
	 	 	 to {transform: translateX(400px);}
	 	}
</style>
</head>
<body>
	 	<div class="box ease-in-demo">Ease-in</div>
	 	<div class="box ease-out-demo">Ease-out</div> 		
	 	<div class="box ease-in-out-demo">Ease-in-out</div>
</body>
</html>

CSS easing-function - 具有值的 cubic-bezier

以下示例演示了各种具有值的三次贝塞尔函数。

使用此配置,将生成动画效果,其中每个框在使用不同的三次贝塞尔计时函数从其初始位置向右移动 300 像素时具有不同的运动行为。


<html>
<head>
<style>
	 	.box {
	 	 	 width: 120px;
	 	 	 height: 110px;
	 	 	 background-color: #e3bd56;
	 	 	 margin: 20px auto;
	 	 	 animation-duration: 4s;
	 	 	 animation-iteration-count: infinite;
	 	 	 text-align: center;
	 	 	 font-size: 20px;
	 	 	 left:10px;
	 	 	 display: flex;
	 	 	 justify-content: center;
	 	 	 align-items: center;
	 	}
	 	.cubic-bezier-demo-1 {
	 	 	 animation-name: cubicBezier1;
	 	 	 animation-timing-function: cubic-bezier(0.25, 0.1, 0.25, 1);
	 	}
	 	.cubic-bezier-demo-2 {
	 	 	 animation-name: cubicBezier2;
	 	 	 animation-timing-function: cubic-bezier(0.42, 0, 0.58, 1);
	 	}
	 	.cubic-bezier-demo-3 {
	 	 	 animation-name: cubicBezier3;
	 	 	 animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
	 	}
	 	.cubic-bezier-demo-4 {
	 	 	 animation-name: cubicBezier4;
	 	 	 animation-timing-function: cubic-bezier(0.95, 0.05, 0.795, 0.035);
	 	}
	 	@keyframes cubicBezier1 {
	 	 	 from {transform: translateX(0);}
	 	 	 to {transform: translateX(300px);}
	 	}
	 	@keyframes cubicBezier2 {
	 	 	 from {transform: translateX(0);}
	 	 	 to {transform: translateX(300px);}
	 	}
	 	@keyframes cubicBezier3 {
	 	 	 from {transform: translateX(0);}
	 	 	 to {transform: translateX(300px);}
	 	}
	 	@keyframes cubicBezier4 {
	 	 	 from {transform: translateX(0);}
	 	 	 to {transform: translateX(300px);}
	 	}
</style>
</head>
<body>
	 	<div class="box cubic-bezier-demo-1">Cubic Bezier (0.25, 0.1, 0.25, 1)</div>
	 	<div class="box cubic-bezier-demo-2">Cubic Bezier (0.42, 0, 0.58, 1)</div> 		
	 	<div class="box cubic-bezier-demo-3">Cubic Bezier (0.55, 0.055, 0.675, 0.19)</div>
	 	<div class="box cubic-bezier-demo-4">Cubic Bezier (0.95, 0.05, 0.795, 0.035)</div>
</body>
</html>

CSS 缓动函数 - step-easing

以下示例演示了各种 step-easing 函数。


<html>
<head>
<style>
	 	body {
	 	 	 display: flex;
	 	 	 justify-content: space-around;
	 	 	 align-items: center;
	 	 	 height: 100vh;
	 	 	 margin: 0;
	 	 	 display: flex;
	 	 	 justify-content: center;
	 	 	 align-items: center;
	 	}
	 	.box {
	 	 	 width: 100px;
	 	 	 height: 50px;
	 	 	 background-color: red;
	 	 	 display: flex;
	 	 	 justify-content: center;	
	 	 	 align-items: center;	
	 	 	 text-align: center;
	 	 	 font-size: 16px;
	 	 	 margin: 10px;
	 	 	 animation: move 6s infinite;
	 	}
	 	.jump-start {
	 	 	 animation-timing-function:steps(6, jump-start);
	 	}
	 	.jump-end {
	 	 	 animation-timing-function:steps(6, jump-end);
	 	}
	 	.jump-both {
	 	 	 animation-timing-function:steps(6, jump-both);
	 	}
	 	.jump-none {
	 	 	 animation-timing-function:steps(6, jump-none);
	 	}
	 	.step-start {
	 	 	 animation-timing-function: step-start;
	 	}
	 	.step-end {
	 	 	 animation-timing-function: step-end;
	 	}
	 	.start {
	 	 	 animation-timing-function: steps(6, start);
	 	}
	 	.end {
	 	animation-timing-function: steps(6, end);
	 	}
	 	@keyframes move {
	 	 	 0%, 100% {
	 	 	 transform: translateY(0);
	 	 	 }
	 	 	 50% {
	 	 	 transform: translateY(250px);
	 	 	 }
	 	}
</style>
</head>
<body>
<div class="box jump-start">Jump-start</div>
<div class="box jump-end">Jump-end</div>
<div class="box jump-both">Jump-both</div>
<div class="box jump-none">Jump-none</div>
<div class="box step-start">Step-start</div>
<div class="box step-end">Step-end</div>
<div class="box start">Start</div>
<div class="box end">End</div>
</body>
</html>