CSS3动画之利用requestAnimationFrame触发重新播放功能


Posted in HTML / CSS onSeptember 11, 2019

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>

效果:

CSS3动画之利用requestAnimationFrame触发重新播放功能

:grin:为了生动形象一些,特地找了个兔子的CSS动画。css类 .rabbit 中只定义了兔子的外观,没有定义动画相关的信息。我们把动画相关的信息都放到了 .animated 类中。

demo传送

handleAnimate 函数是我们的关键部分:

  • $rabbit.classList.remove('animated') 的作用是每次点击按钮的时候删除动画效果。
  • requestAnimationFrame 这里用到了两次,而且是嵌套着使用,为何要如此呢?其实也好理解,有个细节--删除Dom元素的class类后,只有在样式重新计算后才会生效,也就是要等到下一次重绘。而 requestAnimationFrame 注册的回调函数是下一次重绘前,所以我们需要调用两次,相当于在中间插入了一个空隙专门用来让删除动画效果生效,然后紧接着下一次重绘重新触发动画。

总结

javascript 相对css更适合用来控制动画,动画的触发机制和浏览器渲染机制相关。

参考

MDN

 总结

以上所述是小编给大家介绍的CSS3动画之利用requestAnimationFrame触发重新播放功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

HTML / CSS 相关文章推荐
纯css3实现鼠标经过图片显示描述的动画效果
Sep 01 HTML / CSS
前端隐藏出边界内容的实现方法
Apr 14 HTML / CSS
浅析css3中matrix函数的使用
Jun 06 HTML / CSS
HTML5+CSS3网页加载进度条的实现,下载进度条的代码实例
Dec 30 HTML / CSS
基于Canvas+Vue的弹幕组件的实现
Jul 23 HTML / CSS
html5新增的属性和废除的属性简要概述
Feb 20 HTML / CSS
HTML5如何为形状图上颜色怎么绘制具有颜色和透明度的矩形
Jun 23 HTML / CSS
浅谈关于html5中图片抛物线运动的一些心得
Jan 09 HTML / CSS
基于canvas的骨骼动画的示例代码
Jun 12 HTML / CSS
5分钟实现Canvas鼠标跟随动画背景
Nov 18 HTML / CSS
html5的pushstate以及监听浏览器返回事件的实现
Aug 11 HTML / CSS
css3 响应式媒体查询的示例代码
Sep 25 #HTML / CSS
移动端rem布局的两种实现方法
Jan 03 #HTML / CSS
css3实现波纹特效、H5实现动态波浪效果
Jan 31 #HTML / CSS
css3动画过渡实现鼠标跟随导航效果
Feb 08 #HTML / CSS
CSS3 calc()会计算属性详解
Feb 27 #HTML / CSS
CSS3 clip-path 用法介绍详解
Mar 01 #HTML / CSS
CSS3混合模式mix-blend-mode/background-blend-mode简介
Mar 15 #HTML / CSS
You might like
检查用户名是否已在mysql中存在的php写法
2014/01/20 PHP
获取HTML DOM节点元素的方法的总结
2009/08/21 Javascript
使用js获取QueryString的方法小结
2010/02/28 Javascript
鼠标拖拽移动子窗体的JS实现
2014/02/25 Javascript
JavaScript中获取鼠标位置相关属性总结
2014/10/11 Javascript
jQuery实现瀑布流的取巧做法分享
2015/01/12 Javascript
JavaScript中用sort()方法对数组元素进行排序的操作
2015/06/09 Javascript
深入理解jQuery之防止冒泡事件
2016/05/24 Javascript
Chrome不支持showModalDialog模态对话框和无法返回returnValue问题的解决方法
2016/10/30 Javascript
微信小程序实现鼠标拖动效果示例
2017/12/01 Javascript
VS Code转换大小写、修改选中文字或代码颜色的方法
2017/12/15 Javascript
在vue项目中引入highcharts图表的方法(详解)
2018/03/05 Javascript
angularjs结合html5实现拖拽功能
2018/06/25 Javascript
React 无状态组件(Stateless Component) 与高阶组件
2018/08/14 Javascript
Vue.js 使用v-cloak后仍显示变量的解决方法
2018/11/19 Javascript
关于layui表单中按钮自动提交的解决方法
2019/09/09 Javascript
Vue分页插件的前后端配置与使用
2019/10/09 Javascript
JavaScrip如果基于url实现图片下载
2020/07/03 Javascript
[03:57]《不朽》——2015DOTA2国际邀请赛—中国军团出征主题曲MV
2015/07/15 DOTA
[36:02]DOTA2上海特级锦标赛D组小组赛#2 Liquid VS VP第一局
2016/02/28 DOTA
python实现颜色rgb和hex相互转换的函数
2015/03/19 Python
学习python之编写简单简单连接数据库并执行查询操作
2016/02/27 Python
将pandas.dataframe的数据写入到文件中的方法
2018/12/07 Python
python设计微型小说网站(基于Django+Bootstrap框架)
2019/07/08 Python
全网最全python库selenium自动化使用详细教程
2021/01/12 Python
香港时尚女装购物网站:ZAFUL
2017/07/19 全球购物
艺术家策划的室内设计:Curious Egg
2019/03/06 全球购物
eBay奥地利站:eBay.at
2019/07/24 全球购物
网站开发实习生的自我评价
2013/12/11 职场文书
办公室秘书自我鉴定
2014/01/18 职场文书
财务学生的职业生涯发展
2014/02/11 职场文书
电工工作职责范本
2014/02/22 职场文书
关于安全的演讲稿
2014/05/09 职场文书
全国劳模先进事迹材料(2016精选版)
2016/02/25 职场文书
Python使用海龟绘图实现贪吃蛇游戏
2021/06/18 Python
Python进程间的通信之语法学习
2022/04/11 Python