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

使用WebAnimationsAPI制作炫酷动画

时间:2023-03-30 18:28:19 CSS

原生JS如何优雅的写动画?相信WAAPI可以帮助您。WebAnimationsAPIWebAnimationsAPI(WebAnimationAPI,简称WAAPI)允许我们用JavaScript编写和控制动画。这些API被设计为CSS动画和CSS过渡的接口。未来会补充这些API,使其更加强大,是目前支持web动画最有效的方式之一。使用WebAnimationsAPI,我们可以将交互式动画从样式表转移到JavaScript,将表现与行为分开。我们不再需要依赖DOM,比如将CSS属性和作用域类写入元素来控制播放方向。与纯声明式CSS不同,JavaScript还允许我们将属性值动态设置为持续时间。对于构建自定义动画库和创建交互式动画,WebAnimationsAPI可能是完成这项工作的完美工具。一个简单的例子:WAAPI实现轮播相对于其他动画实现方式。说起网页动画,我们自然而然会想到CSS3动画、JS动画、SVG动画、APNG动画等技术,以及jQuery.animate()等动画封装库。根据实际动画内容设计选择不同的实现方式。然而,目前的每一种动画技术都有一定的缺点。比如CSS3动画必须使用JS获取动态变化的值,setInterval的时间经常不准确会卡顿,APNG动画会带来较大的文件体积。但是引入额外的动画包库不适合对性能敏感的业务。在目前的情况下,开发商似乎鱼和熊掌兼得。他们不仅希望获得更强大便捷的动画控制能力,更希望表现和体验足够流畅优雅。如果有一个浏览器原生支持的通用动画解决方案,那就太棒了。W3C也因此提出了WebAnimationAPI(简称WAAPI)。它致力于融合CSS3动画的性能、JavaScript的灵活性、动画库的丰富性等,实现尽可能多的原生浏览器的动画控制。并添加许多CSS没有的变量、控件和/或调整选项。浏览器支持Firefox48+和Chrome36+支持WAAPI功能。Webkit和Edge已将WAAPI移至各自的待办事项列表中。可以在我可以使用中找到完整的浏览器支持。WAAPI有一个成熟且强大的polyfill外部库,允许我们现在在生产中使用它,即使是在浏览器受限的环境中。web-animations.min.js使WAAPI能够在大多数浏览器中运行。WAAPI核心用法element.animate(keyframes,AnimationEffectTimingProperties);keyframes:关键帧对象数组AnimationEffectTimingProperties:动画效果属性对象E.g.document.getElementById("elementId").animate([{transform:'rotate(0)',color:'#000'},{transform:'rotate(360deg)',color:'#fff'}],{duration:3000,iterations:Infinity});WAAPI的基本语法和jQuery的.animate()看起来很相似。但是WWAPI是浏览器原生支持的,所以不需要引入外部库,在性能上也有很大的优势。接下来,我们将一步步学习WAAPI的使用方法。关键帧对象数组使用WAAPI,首先要做的是创建类似于CSS3@keyframes的关键帧对象数组。例如。为轮播的滑动动画创建一个关键帧对象数组varslidingLeft=[//简单的滑动是通过margin-left和opacity的渐变实现的{marginLeft:'0px',opacity:1},{opacity:0.6,offset:0.7},{marginLeft:"-5rem",opacity:1}];Web动画API和CSS3动画的区别:WAAPI不需要明确告知动画中每个关键帧的百分比,它会使用显示的关键帧数自动将动画分成等份。当我们要显式设置一个关键帧与其他关键帧的偏移量时,可以直接在对象中指定一个偏移量(偏移量:大小范围为0~1)。在WAAPI的关键帧对象中,需要使用元素属性的驼峰式大小写,例如对应CSS的属性“margin-Left”,WAAPI的关键帧对象应该使用“marginLeft”。WAAPI必须指定至少两个关键帧(代表动画序列的开始和结束状态)。如果您的关键帧对象数组只有一个对象成员,Element.animate()将抛出不受支持的异常错误。动画效果属性对象我们还需要创建一个动画效果属性对象(AnimationEffectTimingProperties对象)。E.g.varanimateOptions={duration:1500,easing:'ease-in-out',}需要注意的是,AnimationEffectTimingProperties有一些专业术语与大家熟悉的CSS3动画属性不同。下表是两者的对应关系。AnimationEffectTimingPropertiesCSS3动画属性briefdurationanimation-duration指定动画完成一个周期所需的秒数或毫秒数。默认为0。easinganimation-timing-function指定动画的速度曲线。delayanimation-delay指定动画开始的时间。默认为0。iterationsanimation-iteration-count指定动画播放的次数。默认为1。directionanimation-direction指定动画是否在下一个循环中反向播放。默认为'normal'。fillanimation-fill-mode指定动画效果是在动画播放之前还是之后可见。endDelay没有对应的属性来指定动画结束后的延迟时间。iterationStart没有相应的属性来指定迭代过程中动画的开始时间点。easing的默认值是线性的,animation-timing-function的默认值是ease。使用WAAPI时应该使用适当的缓动,这样动画就不会变得机械和乏味(默认的线性意味着动画从开始到结束具有相同的速度)。与animation-iteration-count对应的是iterations。如果您希望动画永远重复,请使用Infinity而不是infinite。注意Infinity不需要用逗号包裹,它是一个JavaScript关键字,而其他值是字符串。时间单位使用ms而不是s,对于写过JavaScript的开发者来说更??容易接受。(其实ms也可以用在css动画中,但是几乎没有人会这么用。)endDelay表示动画结束后的延迟时间,delay的默认值为0,可以使用endDlay的时候您想要将多个动画链接在一起,但希望在一个动画的结束和任何后续动画的开始之间有一个时间间隔。iterationStart表示动画在迭代过程中的开始时间点。例如。如果iterations设置为1,iterationStart设置为0.5,则动画将从动画的中间开始播放到动画的结尾,然后从动画的开头开始播放,在中间结束。但是,如果iterations和iterationStart都设置为0.5,则动画会在中间开始,在最后结束。创建完上面提到的“关键帧对象数组”和“动画效果属性对象”之后,就可以简单的开始一段动画了。你可以在文章后面看到具体的例子。element.animate(slidingLeft,animateOptions);我们要学习如何控制用WAAPI创建的动画,我们还需要了解Animation对象。Animation对象的animate方法不仅为元素设置动画,它还返回一个自己的Animation对象。通过改变这个对象的属性,调用它的方法,就可以优雅的控制动画了。varanimationObj=element.animate(关键帧,AnimationEffectTimingProperties);Animation对象的属性:属性名含义currentTime动画的当前时间值,以毫秒为单位。如果缺少时间线,则其值为null,这意味着动画未激活或尚未播放。效果动画的目标效果。可以是基于AnimationEffectReadOnly类型的效果对象,例如KeyframeEffect或null。finished是只读的。返回一个在此动画完成时执行的Promise。id是标识动画的字符串。playState是只读的。动画的播放状态,常见的有运行、暂停、结束。playbackRate动画的播放速度,默认值为1。当值为0.5时,动画将减半播放,当值为负时,动画将反向播放。准备只读。返回当前动画准备好播放时完成的Promise。startTime动画播放开始的预定时间。默认为空。可以更改此值以使动画在不同的时间开始。timeline与当前动画关联的时间线。默认与文档的时间轴相同。Animation对象具有的方法:方法名称使用cancel()清除该动画引起的所有关键帧效果并停止播放。finish()将当前播放时间设置为当前播放方向对应的动画结束时间。如果是正常播放,则将当前播放时间设置为动画的总时长;如果是反向播放,则将当前播放时间设置为0。pause()暂停动画play()开始或恢复动画。如果动画完成,则重新开始动画。reverse()反转动画的播放方向。如果在未播放的动画上调用,动画将从末尾向后播放到开头。如果对暂停的动画进行调用,则动画将以相反的方向继续播放。设置playbackRate*=-1也可以达到同样的效果;实现Animation对象的事件处理器(回调函数):WWAPI支持使用event和Promise两种方式处理事件。下面是两种事件:oncancel:定义了动画取消或执行cancel()时触发的回调函数。onfinish:定义动画自然播放结束或执行finish()时触发的回调函数。例如。如果动画被取消,删除它的元素。animation.oncancel=animation.effect.target.remove();PromisePromise对象用于表示异步操作的最终完成(或失败)及其结果值。动画对象的ready和finished属性会返回一个Promise对象,对应动画什么时候准备好播放,什么时候结束。下面是一个使用Promise处理事件回调的例子:myAnimation.finished.then(()=>element.remove())document.getAnimations()方法返回一个包含所有当前有效的Animation对象的数组,这个数组包括CSS动画、CSS过渡和Web动画。在较新版本Chrome浏览器的开发者工具(F12)的控制台抽屉中,还可以查看到页面上所有的动画,包括用CSS3定义的动画:WAAPIexample-carouselimage了解上面提到的知识,我们就可以使用WWAPI实现一个简单的轮播,点击打开codepen预览查看完整代码。部分JS代码:querySelector('.slidebox');varitems=slideBox.getElementsByClassName("slide_item");//使用网页动画制作动画,左右滑动共用一个动画varslidingLeft=[{marginLeft:'0px',opacity:1},{opacity:0.6,offset:0.7},{marginLeft:"-5rem",opacity:1}];var滑动=滑动框。animate(slidingLeft,{duration:1500,easing:'ease-in-out',});sliding.onfinish=function(){slideBox.style.marginLeft='0px';}if(sliding.playbackRate!=-1){slideBox.appendChild(items[0]);}btnRight.onclick=slideRight;btnLeft.onclick=slideLeft;};functionslideRight(){sliding.playbackRate=1;//将滑动方向切换为右sliding.play();btnLeft.onclick=null;btnRight.onclick=null;//console.log(sliding.effect);};functionslideLeft(){slideBox.insertBefore(items[items.length-1],items[0]);slideBox.style.marginLeft='-5rem';滑动.playbackRate=-1;//将滑动方向切换到左侧sliding.play();btnLeft.onclick=null;btnRight.onclick=null;};btnRight.onclick=slideRight;btnLeft.onclick=slideLeft;//自动滑动varslideTimer=setInterval(()=>{btnRight.click();},3000);//停止滑动鼠标悬停indexBody.onmouseover=function(){clearInterval(slideTimer);};//鼠标离开时继续自动滑动indexBody.onmouseout=function(){slideTimer=setInterval(()=>{btnRight.click();},3000);};web-animations官方demo非常适合刚接触WAAPI的同学作为入门示例。另外推荐一个很酷的动画库——Animista,里面有很多用CSS3实现的动画(代码可以网上查看,主要是关键帧),我们可以尝试用WWAPI来实现同样的动画效果。参考文献《 Using the Web Animations API 》网址:MDN《 CSS Animation 与 Web Animation API 之争 》译者:范红春原文:OLLIEWILLIAMS《 Web Animation API 从入门到上座 》作者:AlloyTeam《 Animation 》网址:MDN《 CSS3 animation 属性 》网址:W3school