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触发重新播放功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!
稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!
昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。
这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。
而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?
更新动态
- 小骆驼-《草原狼2(蓝光CD)》[原抓WAV+CUE]
- 群星《欢迎来到我身边 电影原声专辑》[320K/MP3][105.02MB]
- 群星《欢迎来到我身边 电影原声专辑》[FLAC/分轨][480.9MB]
- 雷婷《梦里蓝天HQⅡ》 2023头版限量编号低速原抓[WAV+CUE][463M]
- 群星《2024好听新歌42》AI调整音效【WAV分轨】
- 王思雨-《思念陪着鸿雁飞》WAV
- 王思雨《喜马拉雅HQ》头版限量编号[WAV+CUE]
- 李健《无时无刻》[WAV+CUE][590M]
- 陈奕迅《酝酿》[WAV分轨][502M]
- 卓依婷《化蝶》2CD[WAV+CUE][1.1G]
- 群星《吉他王(黑胶CD)》[WAV+CUE]
- 齐秦《穿乐(穿越)》[WAV+CUE]
- 发烧珍品《数位CD音响测试-动向效果(九)》【WAV+CUE】
- 邝美云《邝美云精装歌集》[DSF][1.6G]
- 吕方《爱一回伤一回》[WAV+CUE][454M]
