当前位置: 首页 > Web前端 > CSS

CSS3动画之逐帧动画

时间:2023-03-30 19:20:06 CSS

什么是逐帧动画?要理解CSS3逐帧动画,首先要弄清楚什么是逐帧动画。看一看维基百科中的定义:定格动画,又称逐帧动画,是一种动画技术。其原理是在每一帧中不断播放不同的图像,产生动画效果。简而言之,实现逐帧动画需要两个条件:(1)关联不同的图像,即动画帧;(2)连续播放。我们童年的回忆,手翻书,他实现的是逐帧动画:逐帧动画(图片来源:知乎)前端逐帧动画实现方案在讲css3逐帧之前-逐帧动画的详细介绍,让我们大致了解一下前端实现逐帧动画的选项有哪些?其实无非就是三种技术(视频可以实现所有类型的动画,暂不包括在内):gif、JavaScript、CSS3Animation。前面提到,实现逐帧动画需要两个条件:(1)动画帧;(2)连续播放。下面我们来仔细分析一下这三种技术是如何实现以上条件的:(1)gif在触屏页面中常被用作加载动画。比如《陌陌不孤独饭局》的加载动画:gifgif可以有多个动画帧,连续播放是自己的属性,是否循环也是自己决定的。常用于实现小细节动画,成本低,使用方便。但它的缺点也很明显:在图像质量方面,gif支持的颜色少(最多256色),alpha透明度支持差,图像边缘锯齿严重;交互方面,不能直接控制播放、暂停、播放次数,灵活性差;performance另一方面,gif会造成页面周期性paint,性能较差。(2)JavaScriptJS和CSS3一般把动画帧放在背景图片中。不同的是,JS是通过脚本来控制动画的连续播放:可以直接改变元素的background-image,或者将动画帧合并成sprite图像,通过改变background-position来实现。也是《陌陌不孤独饭局》的一个例子:有一个伸手去拿饭盒的动画,一共19帧,第11帧有一个交互,将sprite图片放在背景中,通过不同的方式实现不同的background-positionsstyles,用JS改样式名:1234567.sprite-rice-1,.sprite-rice-2,....sprite-rice-19{background-image:url(http://7xnvb2.com2.z0.glb.qiniucdn.com/img/rice.jpg);background-repeat:no-repeat}1234.sprite-rice-1{background-position:-1800px0}.sprite-rice-2{background-position:-900px-489px}....sprite-rice-19{background-position:-1200px0}sprite使用JS的好处是兼容性好,交互灵活。(3)CSS3动画CSS3实际上是利用animation-timing-function的步长函数steps(number_of_steps,direction)来实现逐帧??动画的连续播放。在移动端,CSS3Animation有很好的兼容性。与JS相比,CSS3的逐帧动画更易用,效率更高,因为很多优化都是在浏览器底层做的。因此,CSS3逐帧动画在触屏页面中得到了广泛的应用,下面将对其进行详细介绍。CSS3逐帧动画的实现(一)将动画帧组合成sprite图片在触屏页面中,动画往往承担了页面样式实现的角色(即不需要替换),所以我们将图片放在元素的背景(背景图像)。逐帧动画有不同的动画帧。我们可以通过改变background-image的值来切换frame,但是多张图片会带来多次HTTP请求,不利于文件管理。更合适的做法是将所有的动画帧合并为一个精灵,通过改变background-position的值来切换动画帧。因此,逐帧动画又称为“精灵动画”。以京东到家的触屏页面《年货送到家》为例:这个动画有三帧,三个动画帧组合放在.p8.page_key:123456.p8.page_key{position:absolute;的背景中。width:572px;height:586px;background-image:url("../img/p8.png");}(2)使用steps实现动画播放steps指定一个step函数,包括两个参数:第一个参数指定函数中的区间数(必须是正整数);第二个参数是可选的,指定在每个区间的开始或结束时的阶跃变化,接受开始和结束两个值,默认为结束。(参考自W3C)通过W3C中的这张图了解steps的工作机制:steps回到上面的例子,我们在keyframes中定义每个动画帧:123456@-webkit-keyframesp8{0%{background-position:00;}33.33%{background-position:0-586px;}66.66%{background-position:0-1172px;}100%{background-position:0-1758px;}}然后给他添加动画:123.p8。page_key{-webkit-animation:p8steps(1,end)1.5sinfinite;}为什么第一个参数是1?上面提到steps是animation-timing-function的一个属性值,在W3C中是这样描述的:对于keyframed动画,'animation-timing-function'作用于关键帧之间,而不是作用于整个动画。也就是说,animation-timing-function应该在两个关键帧之间,而不是整个动画。在上面的关键帧中,我们把每一帧都写出来了,所以两个关键帧之间的间隔是1。有更简单的写法吗?既然steps的第一个参数是指函数的区间数,那么我们可以直接将关键帧的计算交给steps来完成。123456.p8.page_key{-webkit-animation:p8steps(3,end)1.5sinfinite;}@-webkit-keyframesp8{100%{background-position:0-1758px;}}以上两种写法是等价的的。CSS3逐帧动画使用技巧(一)step-start和step-end除了steps函数,animation-timing-function还有两个与逐帧动画step-start和step-end相关的属性值step-end:step-start相当于steps(1,start):动画从start端点开始;step-end相当于steps(1,end):动画从end端点开始。(2)计算动画帧数:123456$spriteWidth:140px;//精灵宽度@keyframesani{100%{background-position:-($spriteWidth*12)0;//12帧}}(3)适配方案:rem+scale我们知道rem的计算会有误差,所以不建议在使用sprite图片的时候使用rem。如果是逐帧动画,会因为计算错误而出现抖动。那么在触屏页面中,如何实现页面的适配呢?这里小编提供一个思路:非逐帧动画部分,以rem为单位;对于逐帧动画部分,以px为单位,然后结合js使用scale对动画部分进行缩放。感谢阅读,本文版权归AoMLab所有。如有转载请注明出处:傲兔实验室(https://aotu.io/notes/2016/05...)原文地址