css动画
css3中引入了animation模块,自此css动画进入了我们的视野。css动画名符其实,会写css样式就可以创作动画,对一些不怎么会JS的设计师也是比较包容的。但也正因为如此,当你需要重新播放或者说手动触发动画时,css的局限性就突显出来了,毕竟它不是一门编程语言。像这种在页面中创建一个按钮,点击按钮时开始播放一段动画这种活交给JS才是最合适的。
原理和思路
重新播放css动画,我们只需要将CSS动画效果 删除 ,然后再 重新加上 css动画效果即可。那么如何让浏览器理解我们的意图呢,今天的主角 requestAnimationFrame
,这个任务就交给它来完成。 requestAnimationFrame
会告诉浏览器--你需要执行一个动画,并要求在下一次重绘前调用指定的回调函数更新动画。也就是 requestAnimationFrame
需要传入一个回调函数作为参数,这个函数会在浏览器下一次重绘之前执行。 这个机制可以用花费最短的时间让浏览器理解我们需要重新播放动画的意图。
当然 requestAnimationFrame
只是其中的一步,我们还需要再加上个小技巧-- 分离动画样式 .
关键代码
<template> <div class="page-animate"> <button @click="handleAnimate">开始动画</button> <div class="rabbit-box"> <div class="rabbit" ref="rabbit"></div> </div> </div> </template> <script> export default { name: "animate", methods: { handleAnimate() { let $rabbit = this.$refs.rabbit; $rabbit.classList.remove('animated'); window.requestAnimationFrame(()=> { window.requestAnimationFrame(()=>{ $rabbit.classList.add('animated'); }) }) } } } </script> <style lang="less"> .page-animate { .rabbit-box { margin-top: 10px; width: 100px; height: 100px; background:#e2b29f; font-size:120%; padding: 100px; border-radius: 50%; } .rabbit { width:5em; height:3em; background:#ffffff; border-radius:70% 90% 60% 50%; position:relative; box-shadow: -0.2em 1em 0 -0.75em #b78e81; transform:rotate(0deg) translate(-2em,0); z-index:1; .no-flexbox & {margin:10em auto 0;} //tail, eye, feet &:before { content:""; position:absolute; width:1em; height:1em; background:white; // tail border-radius:100%; top:0.5em; left:-0.3em; box-shadow: 4em 0.4em 0 -0.35em #3f3334, // eye 0.5em 1em 0 white, // back foot 4em 1em 0 -0.3em white, // front foot 4em 1em 0 -0.3em white, 4em 1em 0 -0.4em white;; } // ears &:after { content:""; position:absolute; width:.75em; height:2em; background:white; border-radius:50% 100% 0 0; transform:rotate(-30deg); right:1em; top:-1em; border-top:1px solid #f7f5f4; border-left: 1px solid #f7f5f4; box-shadow:-0.5em 0em 0 -0.1em white; } &.animated { animation: hop 1s linear; &:before { animation: kick 1s linear; } } } @keyframes hop { 20% { transform:rotate(-10deg) translate(1em,-2em); box-shadow: -0.2em 3em 0 -1em #b78e81; } 40% { transform:rotate(10deg) translate(3em,-4em); box-shadow: -0.2em 3.25em 0 -1.1em #b78e81; } 60%,75% { transform:rotate(0) translate(4em,0); box-shadow: -0.2em 1em 0 -0.75em #b78e81; } } @keyframes kick { 20%,50% { box-shadow: 4em 0.4em 0 -0.35em #3f3334, 0.5em 1.5em 0 white, 4em 1.75em 0 -0.3em white, 4em 1.75em 0 -0.3em white, 4em 1.9em 0 -0.4em white; } 40% { box-shadow: 4em 0.4em 0 -0.35em #3f3334, 0.5em 2em 0 white, 4em 1.75em 0 -0.3em white, 4.2em 1.75em 0 -0.2em white, 4.4em 1.9em 0 -0.2em white; } } } </style>
效果:
:grin:为了生动形象一些,特地找了个兔子的CSS动画。css类 .rabbit 中只定义了兔子的外观,没有定义动画相关的信息。我们把动画相关的信息都放到了 .animated 类中。
demo传送
handleAnimate 函数是我们的关键部分:
- $rabbit.classList.remove('animated') 的作用是每次点击按钮的时候删除动画效果。
- requestAnimationFrame 这里用到了两次,而且是嵌套着使用,为何要如此呢?其实也好理解,有个细节--删除Dom元素的class类后,只有在样式重新计算后才会生效,也就是要等到下一次重绘。而 requestAnimationFrame 注册的回调函数是下一次重绘前,所以我们需要调用两次,相当于在中间插入了一个空隙专门用来让删除动画效果生效,然后紧接着下一次重绘重新触发动画。
总结
javascript 相对css更适合用来控制动画,动画的触发机制和浏览器渲染机制相关。
参考
MDN
总结
以上所述是小编给大家介绍的CSS3动画之利用requestAnimationFrame触发重新播放功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!
更新日志
- 张芸京.2016-失败的高歌【泡耳音乐】【WAV+CUE】
- 天籁女声《2024第31届上海国际高端音影展纪念CD》[WAV+CUE][1.1G]
- 姚斯婷 《敢爱敢做》头版限量编号24K金碟[低速原抓WAV+CUE][1.2G]
- 雷婷 《把爱留在昨天》紫银合金AQCD[低速原抓WAV+CUE][1.1G]
- 董文华2024-《精选30年·长城长HQ》头版限量[WAV+CUE]
- 柏菲·魏松2024-《跟你走》限量开盘母带ORMCD[WAV+CUE]
- 柏菲·甘雅丹《雅鲁藏布》限量开盘母带ORMCD[WAV+CUE]
- 孙露《明天你是否依然爱我》1:1母盘直刻[低速原抓WAV+CUE][1G]
- 群星2024《龙年精选.音乐盛宴》纯银CD[WAV+CUE][1.1G]
- 童丽《君再来VI》妙音首版[WAV+CUE][1G]
- 柏菲·李跃君2024-《寂寞公路》限量开盘母带ORMCD[WAV+CUE]
- 柏菲·古璇2024-《东山飘雨西山晴》限量开盘母带ORMCD[WAV+CUE]
- 群星《2024好听新歌38》AI调整音效【WAV分轨】
- 台湾荷东《周末狂热1》[WAV+CUE][1.1G]
- 群星《Hi.Fi.怀旧金曲.Vol.1》[低速原抓WAV+分轨][996M]