说说 CSS 3 动画以及 steps() 函数
如今 CSS 3 动画已经非常常见,网上关于 CSS 3 动画的介绍也不少,但大多数都没提及 steps()
这个函数。最近在制作 miss.cat 的 loading 动画时,尝试了一下该函数,发现还蛮实用的。
什么是动画
当然这里要说的不是详细表述怎样称为「动画」,而是要先弄清楚一个概念:在 CSS 3 中哪部分是一个动画的过程。我们先来看一段代码:
@keyframes loading {
from { background-position-x: 0px; }
to { background-position-x: -3000px; }
}
这是一段很简单的代码,在这段代码中 from { ... }
指的是动画起始时的样式,很明显 to { ... }
就是结束时的样式。这里起始时的样式是背景偏移为 0 像素,结束时背景 X 轴偏移值为 -3000 像素。
@keyframes loading {
0% { background-position-x: 0px; }
50% { background-position-x: -1500px; }
100% { background-position-x: -3000px; }
}
这段代码实现了一个相同的动画过程,只不过它分为 3 个阶段去描述了这个动画过程的不同样式。所以简单的说 @keyframes
是定义了一个完整动画过程,在不同状态时的不同样式。弄清楚了什么是动画的过程,才能更好的去理解如何控制动画的播放方式。
动画时间的控制
有了动画的过程,就要说一下控制动画播放时间的 animation-timing-function
属性,这个属性的默认值为 ease
也就是常见的慢进慢出,除此之外还有 linear
等,每一种速度模式都有直观的贝塞尔曲线可以表达。
而其实 steps()
也是 animation-timing-function
属性的其中一种值,没错,这个属性既然叫 function 其实它是指一个函数,包括 ease
或 linear
其实都是内置函数的名称,只是 steps()
的效果有那么点与众不同。
为什么说 steps()
比较与众不同呢,因为上面说的几种动画时间的模式,都是具有连贯性的,要么平均速度、要么有快有慢,而我们这里要说的 steps()
是一种「步进式」的、不连贯播放的动画,用一个逼格高一点的词来说它叫做「阶跃函数」。
说到这里,应该能够大概清楚动画过程、与动画速度之间的关系了。比如我们第一段中的 keyframes 动画,如果使用 linear
那么背景偏移是一个平均速度的渐变过程,而如果使用 steps()
函数的话,则会变成一帧一帧的步进过程。
现在来看看 steps()
函数,这个函数有 2 个参数:
- 第一个参数为整数,必填,表示将整个动画过程划分为多少帧;
- 第二个参数为 start 或 end,选填,表示第一帧为动画开始或结束的状态,默认为 end;
使用场景
有时候遇到一个比较复杂的动画效果,比如一个小人在跑动,那么是不适合全部用 CSS 绘制出来的。往往这时候就会使用 GIF 等动态图片直接应用。但是 GIF 动态图片除了体积较大、还存在 256 色的问题。这个时候我们就可以用上 steps() 函数来代替传统的 GIF 图片了。
![997400552 1.gif](https://s2.loli.net/2022/03/10/bRwVYODozxG746e.gif)
比如上面的这张 GIF 动态图,仅仅有 10 帧却要 100 KB 大,这在网页中是相对「不划算」的。如果我们把 10 帧动画拆分出来:
![203999170 1.png](https://s2.loli.net/2022/03/10/dKNnpPbvUx4khry.png)
像这样我们把 10 帧画面排列在一张图片上,并保存为更现代化的 PNG 格式,体积缩小直接降低了 74 KB。现在我们就来看看如何把一张横排的图片,用 CSS 3 动画让它动起来:
#animation {
background: url(background.png);
width: 300px;
height: 300px;
animation: animation 1s steps(10) infinite;
}
@keyframes animation {
from { background-position-x: 0px; }
to { background-position-x: -3000px; }
}
非常简单的一段代码,我们不需要在 @keyframes
指定每一帧的画面坐标,只需要定义好起始和结束两个状态,然后用 steps(10)
去拆分为 10 帧步进,就可以实现跟 GIF 一样的效果了,并且如果要修改动画的速度也非常方便,直接改 CSS 就好。
后记
一直以来我都想写一篇关于 CSS 3 动画的博客,所以这一次顺便把动画的一些概念介绍了一下,导致篇幅较长,但理解起来更有帮助。
至于 steps()
这种步进式的动画,应用的场景远远不仅是代替 GIF 而已,如果配合 SVG 甚至可以做出矢量的动画,这将远远超越 GIF 的可用场景。而关于上面 GIF 图片体积的问题,当然也是与色彩优化等问题有关的,这里就不展开细说了。
由于目前浏览器支持的问题,可能还需要一段时间才会更加普及 steps()
这种玩法,好在移动端的浏览器目前基本没问题,做一些微信小游戏啥的,就可以用上咯。