强大的CSS3-JS-帧动画的多种实现方式与性能对比
时间:2023-03-30 18:07:30
CSS
强大的CSS3/JS:帧动画的多种实现方式及性能比较\.JS动画(操作DOM,修改CSS属性值)3\.画布动画4\.SVG动画5\.以三人为首的3D动画。就是帧动画,也叫序列帧动画、定格动画、逐帧动画等,这里统一用帧动画来表达。应用场景帧动画一般用来实现稍微复杂一点的动画效果。同时也希望动画更加细腻,设计师可以发挥的更加自如。它可以定义每个时间刻度上的显示内容。我们一般使用帧动画来做页面加载、小人物、小物体元素的简单动画。我们想象中的帧动画应该具备以下特点:可以自由控制播放、暂停和停止,可以控制播放次数,可以在播放速度上添加交互,可以在播放完成后添加事件。先由设计师在PS中的时间轴上进行设计,然后将图片导出给前端人员。PS时间轴动画一般用于制作稍微简单一些的动画,操作简单方便。或者是设计师在AE的时间轴里设计的,因为AE内置了更丰富的动作效果,比如转换,翻转等,AE可以帮我们实现更复杂的效果,然后把图片导出到前台——端人员。在这里,帧动画素材要求,每一帧的图片最好宽高是偶数,张数是偶数,周围最好有一些空白。实现方案目前想到的方案整理如下图,我们将详细介绍每一种方案。1、GIF图片我们可以将上面制作的帧动画导出为GIF图片。GIF图像将连续播放,不能暂停。常用于实现小细节动画,成本低,使用方便。但它的缺点也很明显:在图像质量方面,gif支持的颜色少(最多256色),alpha透明度支持差,图像边缘锯齿严重;交互方面,不能直接控制播放、暂停、播放次数,灵活性差;performance另一方面,gif会导致页面周期性绘制,性能较差。2、CSS3框架动画CSS3框架动画是我们今天需要重点关注的解决方案。核心是利用CSS3中的Animation动画,准确的说是利用animation-timing-function的步长函数steps(number_of_steps,direction)来实现动画的逐帧连续播放。帧动画的实现原理是在视觉中不断切换画面内容,利用视觉滞留的生理现象,实现连续播放的动画效果。下面介绍几种制作CSS3帧动画的方案。(1)不断切换动画图片地址src(不推荐)。我们把图片放在元素的背景中(background-image),通过改变background-image的值来切换frame。但是这种方法有以下缺点,所以不推荐这种方案。多张图片会带来多个HTTP请求。每张图片第一次加载会导致切换图片时出现闪烁,不利于文件管理(2)不断切换精灵图片的位置(推荐)。我们将动画图片的所有帧合并为一张精灵图,通过改变background-position的值来实现动画帧的切换。分为两步:第一步:将动画帧合并成精灵图。精灵图的要求可以参考上面的素材准备。例如,下面的帧动画精灵图像共有20帧。[图片上传失败...(image-91f7b7-1556627487319)]第二步:使用steps步进函数切换Sprite图片的位置先看写法一:
.sprite{width:300px;高度:300px;背景重复:不重复;背景图像:url(frame.png);动画:帧333ms步长(1,结束)都是无限的;}@keyframes帧{0%{background-position:00;}5%{background-position:-300px0;}10%{background-position:-600px0;}15%{背景位置:-900px0;}20%{背景位置:-1200px0;}25%{背景位置:-1500px0;}30%{背景位置:-1800px0;}}35%{background-position:-2100px0;}40%{background-position:-2400px0;}45%{background-position:-2700px0;}50%{background-position:-3000px0;}55%{background-position:-3300px0;}60%{background-position:-3600px0;}65%{background-position:-3900px0;}70%{background-position:-4200px0;}75%{背景位置on:-4500px0;}80%{background-position:-4800px0;}85%{background-position:-5100px0;}90%{background-position:-5400px0;}95%{background-position:-5700px0;}100%{background-position:-6000px0;}}对上面的动画有疑问吗?问题1:既然已经详细定义了关键帧,是否可以使用steps函数代替直接定义线性变化?动画:帧10s线性无限;如果我们这样定义的话,动画就不会是一步步的,而是会不断的改变背景图的位置,这是移动的效果,不是切换,如下图:问题2:应该不设置为20步?怎么变成1了?这里我们先了解一下animation-timing-function属性CSSanimation-timing-function属性定义了CSS动画在每个动画周期中执行的节奏。对于关键帧动画,定时函数作用于一个关键帧周期而不是整个动画周期,即从关键帧开始到关键帧结束为止。计时函数作用于每两个关键帧之间,而不是整个动画。接下来我们看一下steps()函数:steps函数指定了一个step函数,它接受两个参数。第一个参数接受一个整数值,指示两个关键帧之间的步数。第二个参数有两个值
或。默认为<结束>。step-start等同于step(1,start)。step-end等价于step(1,end)。综上所述,我们可以知道,因为我们详细定义了一个关键帧循环,从开始到结束,每两个关键帧一步显示,也就是说在0%到5%之间变化一次,而5%~10%变化一次,这样写就可以达到想要的效果了。看第二种写法: .sprite{width:300px;高度:300px;背景重复:不重复;背景图像:url(frame.png);animation:frame333mssteps(20)bothinfinite;}@keyframesframe{0%{background-position:00;}//100%可以省略{background-position:-6000px0;}}这里定义开始而End的意思是定义一个关键帧周期,但是因为我们没有详细定义每一帧的显示,所以我们要将0%到100%的区间分成20个step来分阶段显示。也可以改为关键字的写法,只能定义最后一帧,因为默认第一帧是初始位置。@keyframesframe{from{background-position:00;}//可以省略到{background-position:-6000px0;}}(3)连续移动spritemap的位置(移动端推荐)为与第二种基本相同,只是将精灵贴图位置切换的过程换成了transform:translate3d(),只是需要加一个overflow:hidden;集装箱包装。这里我们仅以定义初始帧和结束帧为例。使用transform可以开启GPU加速,提升机器渲染效果,有效解决移动端帧动画抖动问题。