马黑PHP整站系统

使用getAnimations()方法控制CSS动画

位置: 首页 > 前端三套件[ 发布时间: 2024.6.13  作者: 马黑  阅读: 195 ]

如下效果是纯CSS关键帧动画,请特别注意,未经干预前动画由CSS直接驱动,三朵花的旋转无限循环:

点击接力旋转按钮,其中一朵花朵继续旋转,另外两朵花暂停,旋转着的花朵停下,下一朵花紧接着旋转,如此循环往复。点击恢复原状按钮,结束接力赛旋转,三朵花的旋转状态恢复到初始时的样子。

接力运行动画的实现得益于 getAnimations() 方法,该方法由 Web Animations API(简称WAAPI) 提供,我们之前介绍的原生 JS animate() 方法也是由 WAAPI 提供。

getAnimations() 方法可以基于 document 即 DOM,document.getAnimations();,这将拿到整个页面的所有动画,包含三种类型的动画:① CSS动画(CSS Animations),② CSS过度动画(CSS Transitions),③ Web动画(Web Animations,即之前介绍的原生JS Animate动画),数据以数组形式存储;也可以基于 element 即某个或某些特定的HTML元素,拿到的也是数组数据。利用这些数据,我们可以相应地管理各类WAAPI所能管理的动画,本文重点讨论的动画类型是CSS动画——如前已述,接力旋转按钮点击后的效果就是通过基于 document 的 getAnimations() 方法实现的。

考虑一下下面的CSS样式表:

<style> .pic { position: absolute; left: 20px; top: 20px; animation: rot 4s linear infinite; } @keyframes rot { to { transform: rotate(360deg); } } </style>

留意第2行代码,简写形式的 animation 属性中有一个参数 infinite,它是 animation-iteration-count 的值,指动画运行次数,infinite 是无限循环运行。无限循环运行的动画 onfinish 事件(动画完成事件)永远不会被触发,因此需要动态修改动画运行次数,比如改为运行一次。控制CSS关键帧动画可以通过修改元素级CSS样式来处理,我们会拿到要控制动画的所有元素,在JS中这么处理就可以达到目的:

element.style.animationIterationCount = 1;

当然,如果CSS样式表中直接在简写属性的 animation 值中去掉 infinite,那一切将很简单,我们只需简单地通过 getAnimations() 方法获取所有的动画然后控制这些动画就好。或者,不在CSS样式表中修改动画运行次数,那能否通过拿到的动画操作句柄,使用 WAAPI 的方式去修改动画运行次数呢?针对CSS动画目前不行,动画对象.iterations = 1; 这样的设置目前仅能作用于由 JS 的 animate() 方法生成的动画。

修改动画运行次数为1次之后,接着就可以真奔主题,让CSS关键帧动画接力运行。我们要做的仅仅是封装 动画对象.onfinish 事件:让前一个动画运行结束时开启下一个动画的运行,并且令其头尾衔接。以下是完整的实现代码,其运行结果是动画一开始就进入接力状态,且每一朵花都具备接受点击功能,通过点击任意一朵花,动画都会在播放、暂停两种状态间切换:

<style> .tz { margin: 20px auto; width: 760px; height: 400px; border: 1px solid gray; position: relative; } .pic { position: absolute; left: 20px; top: 20px; animation: rot 4s linear infinite; } .pic:nth-of-type(1) { left: 120px; top: 30px; } .pic:nth-of-type(2) { left: 460px; top: 10px; } .pic:nth-of-type(3) { left: 320px; top: 200px; } @keyframes rot { to { transform: rotate(360deg); } } </style> <div id="tz"> <img class="pic" alt="" src="https://638183.freep.cn/638183/t23/btn/12f.png" /> <img class="pic" alt="" src="https://638183.freep.cn/638183/t23/btn/12f.png" /> <img class="pic" alt="" src="https://638183.freep.cn/638183/t23/btn/12f.png" /> </div>   <script> const pics = document.querySelectorAll('.pic'); //所有运行动画的元素 const anis = document.getAnimations(); //所有动画对象 var isplaying = true, current = 0; //播放状态、当前播放的动画索引   //遍历动画对象 anis.forEach((ani,key) => {     pics[key].style.animationIterationCount = 1; //改变元素的动画运行次数     if(key > 0) ani.pause(); //除了第一个动画,都先暂停 //如果不是最后一个动画对象,它运行结束时     if(key < anis.length - 1) ani.onfinish = () => {         anis[key+1].play(); //启动下一个动画         current = key + 1; //当前动画索引加 1     } //否则如果是最后一个动画,它运行结束时     else ani.onfinish = () => {         anis[0].play(); //启动第一个动画 current = 0; //当前动画索引是 0     } });   //花朵点击事件 pics.forEach((pic, key) => pic.onclick = () => { //如果动画正在运行,则令当前运行的动画对象暂停,反之,如果动画暂停中,则令当前动画对象播放     isplaying ? anis[current].pause() : anis[current].play();     isplaying = !isplaying; //布尔变量值取反 }); </script>

以上代码可以复制到 pencil code 或存为本地HTML文档运行以查看运行效果及进行相关研究。

前一篇: JS原生animate动画函数应用实例:文本转场效果
下一篇: JS原生animate动画之:编写自己的动画

发表评论:

       

评论列表 [3条]

#3 | 小希 于 2024-6-13 12:57 发布: 示例代码跟演示的效果有点点不一样。每个小花都可控暂停,看了一下它们是按左、右、下的顺序排好队的。

#2 | 飞飞 于 2024-6-13 12:49 发布: 接力旋转特别好玩,每个小花转4秒,下一个接上。。最喜欢这种直观演示的小程序。。。一直觉得好神啊,多种情况可以选择。。。代码比提供出来的复杂几倍的吧。。

#1 | 悄然 于 2024-6-13 12:46 发布: 每天都有好玩颜值又高的动画效果出炉。。。教程看得赏心悦目,看得懂不懂的另说。:))

Copyright © 2023 All Right Reserved 马黑PHP文章管理整站系统v1.8
联系我们: gxblk@163.com