CSS逐帧动画

前言

逐帧动画就有点像gif图,就是将动画的所有帧都提取出来,然后按顺序进行播放;

利用CSS3中的steps()函数以及background-position即可轻易的实现!

基本步骤

  1. 将所有的帧图片按顺序打包成一个雪碧图(一排或一列,这样便于位置偏移);

  2. 设置背景样式和相关的动画样式;举个例子:

    假设每帧图片大小为40x60,总共10帧,打包成一排,那么得到的雪碧图大小就为400x60

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    @keyframes frame {
    from {
    background-position-x: 0px;
    }
    to {
    background-position-x: -360px; /* 对应最后一帧图片的偏移量 */
    }
    }

    .demo {
    background-image: url('xxx.png');
    background-size: 400px 60px;
    animation: frame 1.2s steps(9) infinite;
    }

    steps()函数的第二个参数默认为end。为何是steps(9)而不是steps(10)?因为第一帧的背景位置对应的是第一张图,而最后一帧的背景位置对应的是最后一张图(即第10张图),这两者位置之间实际只差了9张图的宽度而已!所以只需要进行9次位移即可,步数不对则会使每帧得到图片位置发生偏差!

注意事项

  1. 如果使用了rem布局,@keyframesbackground-size的尺寸单位换成rem后,在移动端可能会出现抖动的情况;因为换成rem后基本上都带小数,由于各种浏览器对精度的取舍有所不同,所以导致得到背景位置并不是准确的,且每帧精度丢失后偏移的位置量并不是相同,最终每帧图片图片尺寸不一致,出现抖动。

    解决办法可以参考:CSS技巧:逐帧动画抖动解决方案 | Aotu.io「凹凸实验室」

  2. 若动画图片使用的是二倍图,那么在background-size处应该使用的是一倍图的尺寸,而background-position则仍然使用二倍图的尺寸!因为background-size指定的是背景图呈现的大小(相当于<img>元素的宽高),而background-position的位置针对得是原始背景图

相关知识

  • background-position是相对于background-origin指定的区域而言的;

  • background-origin指定了元素背景图的区域(盒模型),而background-position则设置了背景图的初始位置。

相关文档

  1. 大厂 H5 开发实战手册 - 凹凸实验室 - 掘金小册