写点什么

重学 JS | 通过无限循环动画案例理解 CSS3 动画与 JS 动画

用户头像
梁龙先森
关注
发布于: 2021 年 01 月 23 日
重学JS | 通过无限循环动画案例理解CSS3动画与JS动画

聊到动画我们首先想到 CSS3,JS 动画,哪种在实现无限循环更优呢?这里总结下涉及的知识点,以及基本无限循环动画的实现,还有优劣势分析。


下面以如下 HTML 元素,实现元素从左往右,再从右往左无限循环的动画

<!DOCTYPE html><html><head>   <meta charset=" utf-8">   <style>  	 #box {       width: 100px;       height: 100px;       background: red;       position: relative;     }   </style></head><body>    <div id="box"></div></body></html>
复制代码

CSS3 动画

animation

看看 CSS3 animation 动画属性。

animation:

name

duration

timing-function

delay

iteration-count

direction

fill-mode

play-state;

  1. animation-name:指定要绑定到选择器的关键帧的名称,即 @keyframes 动画指定的名称,或者 none。

  2. animation-duration: 定义动画完成一个周期需要多少秒或毫秒。

  3. animation-timing-function:通过定义速度曲线,指定动画将如何完成一个周期。(速度曲线:定义动画从一套 CSS 样式变为另一套所用的时间)

  4. 预定义的速度曲线

linear | ease | ease-in | ease-out | ease-in-out

2. 三次贝塞尔曲线

cubic-bezier(n,n,n,n),值的范围是 0 到 1 的数值

  1. animation-delay: 定义动画什么时候开始

  2. animation-iteration-count: 定义动画应该播放多少次,值为 infinite,则无限次播放,为数字,则播放几次。

  3. animation-direction: 是否循环交替反向播放动画,定义只播放 1 次,则该属性不起作用。值为 alternate,则奇数次正常播放,偶数次,向后播放。

  4. animation-fill-mode: 当动画不播放时(当动画完成时,或当动画有一个延迟未开始播放时),要应用到元素的样式。

  5. animation-play-state:指定动画是否正在运行或已暂停,值为 paused|running。

@keyframes

关键帧的意思,定义动画在不同阶段的状态。通常将它分为 0%,50%,100%三个状态。


相关理论知识学完了,看下以下代码实现:

<style type="text/css">   #box {     animation: loopanimation 4s infinite alternate;     -webkit-animation: loopanimation 4s infinite alternate;     -moz-animation: loopanimation 4s infinite alternate;     -o-animation: loopanimation 4s infinite alternate;     -ms-animation: loopanimation 4s infinite alternate;   }    @keyframes loopanimation {     0% {        left: 0px;     }     50% {        left: 100px;     }     100% {        left: 0px;     }   } </style>
复制代码
优缺点

优点:

浏览器可以对动画进行优化,相应的点如下:

  1. 浏览器使用与 requestAnimationFrame 类似的机制,相应机制在下面 JS 动画中介绍。

  2. 通过 GUP 提高动画性能(强制使用硬件加速)

缺点:

  1. CSS3 动画运行过程难以把控,无法附加事件进行回调函数绑定,它只能暂停,同时它也不能在动画中寻找特定的时间点、反转动画,或者变换时间尺度。

  2. 不利于编写复杂动画,容易造成代码冗长。

JS 动画

编写动画函数:

let animationFun = function(){	let box = document.getElementById('box')	let pos = 0  // 起始位置	let end = 500 // 终点位置	let step = 10 // 步长	let toRight = true // 方向	return function animate(box,pos,end,step,toRight){   	if(toRight){      	if(pos<=end ){         	pos+=step         	toRight = pos>=end?false:true      	}   	}else{      	pos-=step      	toRight = pos<=0?true:false   	}   	box.style.left = pos+'px'	}}
复制代码
setInterval

通过 setInterval 实现循环,时间为 1000/60,因为大多数浏览器渲染是 60 帧/s

let animate = animationFun()let timer = setInterval(function(){    animate()},1000/60) 
复制代码
requestAnimationFrame

requestAnimationFrame 是个动画框架,它的优势如下:

  1. 会把每一帧中的所有 DOM 操作集中起来,在一次重绘或回流中就完成,并且重绘或回流的时间间隔紧紧跟随浏览器的刷新频率,一般来说,这个频率为每秒 60 帧。

  2. 在隐藏或不可见的元素中 requestAnimationFrame 不会进行重绘或回流,这当然就意味着更少的的 cpu,gpu 和内存使用量。

let animate = animateFun()function animloop() {   animate();   window.requestAnimationFrame(animloop);}animloop()
复制代码
优缺点

优点:

  1. JS 动画控制能力强,可以在动画播放中对其进行开始、暂停、中止、取消等操作。

  2. JS 动画能实现更复杂的动画效果,比如:曲线运动、冲击闪烁等。

  3. CSS3 有兼容性问题,而 JS 大多数没有兼容问题。

缺点:

  1. JavaScript 在浏览器的主线程中运行,而主线程中还有其它需要运行的 JavaScript 脚本、样式计算、布局、绘制任务等,对其干扰导致线程可能出现阻塞,从而造成丢帧的情况。

  2. 代码复杂度高于 CSS 动画。

总结

最后再解答个问题?为啥 CSS3 动画比 JS 动画更流畅?

渲染线程分为主线程和合成器线程。如果 CSS 动画只改变 transform、opacity 两种属性,则此时动画直接在合成器线程完成。采用 JS 动画,会在主线程进行,然后触发合成器线程进行下步操作。若此时 JS 线程执行昂贵的任务,主线程繁忙,会造成失帧堵塞,此时采用 CSS 动画更流畅。因此,CSS3 动画比 JS 动画流畅是基于一定前提的:

  1. JS 在执行昂贵的任务

  2. 同时 CSS 动画不触发 layout 或 paint。

因为触发了重绘或者重排,都需要主线程进行 Layer 树的重新计算,这时动画都会阻塞后续操作。不触发重绘重排的属性有:transfrom|opacity|perspective-origin|perspective|backface-visibility


至此,我们借助实现无限循环的动画例子,学习了 CSS3 动画以及 JS 动画,以及之前的优劣势。简而言之,不需要中间过程控制,只是简单状态切换,选 CSS 动画。若需复杂动画、进行过程控制等,选 JS 动画。


附:

前端知识体系总结输出文章目录大全


发布于: 2021 年 01 月 23 日阅读数: 759
用户头像

梁龙先森

关注

脚踏V8引擎的无情写作机器 2018.03.17 加入

还未添加个人简介

评论

发布
暂无评论
重学JS | 通过无限循环动画案例理解CSS3动画与JS动画