本文主要是介绍css requestAnimationFrame,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
绘制动画,一般有两个选择:
- js脚本 setTimeout和setInterval
- css3 transition和animation属性
这两个方法有各自的局限性:
- js脚本实现动画的局限性:
- 即使向 setTimeout和setInterval 传递ms级的参数,由于js单线程的关系,可能会引发堵塞,不能达到高精度的准确性
- 没有对动画的循环机制进行优化,只是以一个大致的时间间隔循环,而且“最优帧速率”和“选择绘制下一帧的最优时机”都需要开发者自己来控制;ms设置过小,比如小于16.67ms(60帧)那么就会引起掉帧(一般显示器显示最高频率是60帧);设置过大,帧数小,动画效果不流畅
- css3实现动画的局限性
- 兼容性问题,对于PC浏览器,IE8, IE9之流,你想兼容实现某些动画效果,比如说淡入淡出,就无能为力了
- 不能应用所有属性问题,CSS3动画可以改变高宽,方位,角度,透明度等等,但是对于scrollTop,就无能无力了
- CSS3支持的动画效果有限
于是,我们引入requestAnimationFrame
- requestAnimationFrame会把每一帧中的dom操作集中起来,再一次重绘或者重排中就完成,并且刷新频率紧跟浏览器的刷新频率
- 在隐藏或不可见的元素中,requestAnimationFrame将不会进行重绘或回流,这当然就意味着更少的CPU、GPU和内存使用量
- requestAnimationFrame是由浏览器专门为动画提供的API,在运行时浏览器会自动优化方法的调用,并且如果页面不是激活状态下的话,动画会自动暂停,有效节省了CPU开销
requestAnimationFrame的用法与setTimeout相似,只是不需要设置时间间隔而已。requestAnimationFrame使用一个回调函数作为参数,这个回调函数会在浏览器重绘之前调用。它返回一个整数,表示定时器的编号,这个值可以传递给cancelAnimationFrame用于取消这个函数的执行
timerID = requestAnimationFrame(callback);
//控制台输出1和0
var timer = requestAnimationFrame(function(){console.log(0);
});
console.log(timer);//1
cancelAnimationFrame方法用于取消定时器
//控制台什么都不输出
var timer = requestAnimationFrame(function(){console.log(0);
});
cancelAnimationFrame(timer);
也可以直接使用返回值进行取消
var timer = requestAnimationFrame(function(){console.log(0);
});
cancelAnimationFrame(1);
其实我们在《vue 页面加载进度条组件》中使用了setInterval作为动画脚本,现在我们可以用requestAnimationFrame重写(主要是一个递归调用,看mounted和watch中的代码就可以了)
<template><transition name="fade"><div class="progress-bar" v-if="isShow"></div></transition>
</template><script type="text/babel">export default {data() {return {isShow: true, // 是否显示进度条val: 0, // 进度}},props: {/*** 每10毫秒自增幅度*/step: {type: Number,default: 5,},/*** 初始值*/initVal: {type: Number,default: 0,},/*** 到一定进度停止*/stopVal: {type: Number,default: 80,},/*** 进度条继续到成功*/isOk: {type: Boolean,default: false,},},mounted() {this.val = this.initVallet step = this.steplet loop = () => {this.val = this.val + stepthis.$el.style.width = this.val + '%'if (this.val >= this.stopVal) {cancelAnimationFrame(timer)return}requestAnimationFrame(loop)}let timer = requestAnimationFrame(loop)},watch: {isOk() {let val = this.vallet step = this.steplet loop = () => {val = val + stepthis.$el.style.width = val + '%'if (val >= 100) {cancelAnimationFrame(timer)this.isShow = falsethis.$emit('callback', 'load success')return}requestAnimationFrame(loop)}let timer = requestAnimationFrame(loop)},},}
</script><style lang="stylus" rel="stylesheet/stylus">.progress-bar {position fixedtop 0height 6pxwidth 0background-color #999}.fade {&-enter-active, &-leave-active {transition: all .3s}&-enter, &-leave-active {opacity: 0}}
</style>
这篇关于css requestAnimationFrame的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!