3

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

 3 years ago
source link: https://xie.infoq.cn/article/0d7e633d08c5a94b4b25ce7e3
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

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



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

<!DOCTYPEhtml>
<html>
<head>
<metacharset=" utf-8">
<style>
#box {
width: 100px;
height: 100px;
background: red;
position: relative;
}
</style>
</head>
<body>
<divid="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%三个状态。



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

<styletype="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动画

编写动画函数:

letanimationFun =function(){
letbox =document.getElementById('box')
letpos =0// 起始位置
letend =500// 终点位置
letstep =10// 步长
lettoRight =true// 方向
returnfunctionanimate(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

letanimate = animationFun()
lettimer =setInterval(function(){
animate()
},1000/60)

requestAnimationFrame

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

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

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

letanimate = animateFun()
functionanimloop(){
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动画。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK