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

前端动画技术的研究与比较

时间:2023-04-06 00:05:14 HTML5

第一次在segmentfault上发文章:),欢迎评论指正。原文首发于https://github.com/WarpPrism/...动画相关概念frames:动画过程中的各个静态,各个静态图片framerate:刷新率,每秒播放的帧数,FPS(framepersecond),单位是HzFrameduration:每一帧停留的时间,比如60FPS的动画帧持续时间大约是16.7ms,也就是说浏览器必须在16.7ms内绘制这一帧硬件加速:硬件处理器分为三种:CPU、GPU和APU(声音处理器)。它们通过PCI/AGP/PCIE总线交换数据。GPU在浮点运算、并行计算等一些计算上的性能明显高于CPU。硬件加速是利用GPU计算和缓动动画:最常见的动画是均匀动画,每次增加一个固定值。Easing用于修改每次增加的值,使其以不规则的方式增加,实现动画变化。浏览器刷新率:通常为60Hz前端动画分类从控制的角度,前端动画分为两种:JavaScript控制的动画CSS控制的动画JS动画JS动画的原理是通过setTimeout绘制动画帧setInterval或requestAnimationFrame方法(render),从而动态改变网页中图形的显示属性(如DOM样式、canvas位图数据、SVG对象属性等),进而达到动画的目的。大多数情况下,应该优先选择requestAnimationFrame方法(RAF),因为RAF的原理是在浏览器下次重绘之前更新动画,即其刷新率与浏览器自身的刷新率(通常为60Hz)保持一致,从而保证性能。此外,RAF会在浏览器切入后台时暂停执行,这也可以提高性能和电池寿命。(来自MDN)//requestAnimationFrameDemoleti=0letrender=(){if(i>=frame.length)i=0letcurrentFrame=frame[i]drawFrame(currentFrame)i++requestAnimationFrame(render)}requestAnimationFrame(render)下面的代码是使用js+ca??nvas实现帧动画的例子,可以帮助大家更好的理解js动画的原理:/***基于Canvas的帧动画库*最后修改日期:2018-06-22*/import{IsArray}from'Utils'classFrameAnim{constructor({frames,canvas,fps,useRAF}){this._init({frames,canvas,fps,useRAF})}/***实例初始化*@paramoptions->*@param{Array}frames图像对象数组*@param{Object}canvascanvasdom对象*@param{Number}fps帧率*@param{Boolean}useRAF是否使用requestAnimationFrame方法*/_init({frames,画布,fps,useRAF}){this.frames=[]if(IsArray(frames)){this.frames=frames}this.canvas=canvasthis.fps=fps||60这个。useRAF=useRAF||falsethis.ctx=这个。canvas.getContext('2d')//绘图上下文this.cwidth=this.canvas.widththis.cheight=this.canvas.heightthis.animTimer=null//动画定时器this.currentIndex=0//当前屏this.stopLoop=false//停止循环播放}_play(frameSections,fromIndex=0){returnnewPromise((resolve,reject)=>{this.currentIndex=fromIndex||0if(this.useRAF){letrender=()=>{this.ctx.clearRect(0,0,this.cwidth,this.cheight)letcurrentFrame=frameSections[this.currentIndex]this.ctx.drawImage(currentFrame,0,0,currentFrame.width,currentFrame.height)this.currentIndex++if(this.currentIndex<=frameSections.length-1){requestAnimationFrame(render)}else{this._stopPlay()resolve({finish:true})}}this.animTimer=requestAnimationFrame(render)}else{this.animTimer=setInterval(()=>{if(this.currentIndex>frameSections.length-1){这个._stopPlay()resolve({finish:true})return}this.ctx.clearRect(0,0,this.cwidth,this.cheight)让currentFrame=frameSections[this.currentIndex]this.ctx.drawImage(currentFrame,0,0,currentFrame.width,currentFrame.height)this.currentIndex++},1000/this.fps)}})}_stopPlay(){if(this.useRAF){cancelAnimationFrame(this.animTimer)this.animTimer=null}else{clearInterval(this.animTimer)this.animTimer=null}}stopAllFrameAnimation(){this.stopLoop=truethis._stopPlay()}/***顺序播放*@param{Array}frameSections动画片片段*/linearPlay(frameSections=this...this.currentIndex).then((res)=>{if(!this.stopLoop){this.currentIndex=0this.loopPlay(frameSections,this.currentIndex)}})}//倒序播放reversePlay(frameSections=this.frames){frameSections.reverse()returnthis.linearPlay(frameSections)}//反向循环播放reverseLoopPlay(frameSections=this.frames){frameSections.reverse()this.loopPlay(frameSections)}//摆动(单摆)循环播放:即从第一帧播放到最后一帧,并然后从最后一帧播放到第一帧,所以循环swingLoopPlay(frameSections=this.frames){this._play(frameSections,this.currentIndex).then((res)=>{if(!this.stopLoop){this.currentIndex=0frameSections.reverse()this.swingLoopPlay(frameSections)}})}/***销毁资源,谨慎使用*/disposeResource(){this.stopAllFrameAnimation()for(leti=0;iCSS+DOM>JS+DOM下面是一个CodepenDemo动画动画技术对比的缓动函数Linear:无缓动效果Quadratic:二次缓动(t^2)Cubic:三次缓动(t^3)Quartic:二次缓动(t^4)Quintic:五次方缓动(t^5)Sinusoidal:正弦曲线缓动(sin(t))Exponential:指数曲线缓动(2^t)Circular:圆曲线缓动(sqrt(1-t^2))Elastic:指数衰减的正弦缓动超过三次缓动的范围((s+1)t^3–st^2)exponentiallydecayingreboundeasingeasing函数的实现可以参考Tween.js前端绘图技术VS前端动画技术前端绘图技术通常指2D和以HTML5(canvas、svg、webgl等)为代表的3D图形绘制技术。它和前端动画之间没有包容和包容关系,不能混为一谈。只有两者的有机结合,才能打造出炫酷的UI界面。参考链接深入浏览器理解CSS动画和过渡性能问题前端性能优化让动画更流畅CSSvsJS动画:谁更快?一篇讲解浏览器解析和CSS(GPU)动画优化的文章