state.rAF = requestAnimationFrame(count)

简介: q

requestAnimationFrame.js思路
先判断是不是浏览器还是其他环境
如果是浏览器判断浏览器内核类型
如果浏览器不支持requestAnimationFrame,cancelAnimationFrame方法,改写setTimeout定时器
导出两个方法 requestAnimationFrame, cancelAnimationFrame
各个浏览器前缀:let prefixes = 'webkit moz ms o';
判断是不是浏览器:let isServe = typeof window == 'undefined';
增加各个浏览器前缀:
let prefix;
let requestAnimationFrame;
let cancelAnimationFrame;
// 通过遍历各浏览器前缀,来得到requestAnimationFrame和cancelAnimationFrame在当前浏览器的实现形式

for (let i = 0; i < prefixes.length; i++) {
    if (requestAnimationFrame && cancelAnimationFrame) { break }
    prefix = prefixes[i]
    requestAnimationFrame = requestAnimationFrame || window[prefix + 'RequestAnimationFrame']
    cancelAnimationFrame = cancelAnimationFrame || window[prefix + 'CancelAnimationFrame'] || window[prefix + 'CancelRequestAnimationFrame']
}

//不支持使用setTimeout方式替换:模拟60帧的效果
// 如果当前浏览器不支持requestAnimationFrame和cancelAnimationFrame,则会退到setTimeout

if (!requestAnimationFrame || !cancelAnimationFrame) {
    requestAnimationFrame = function (callback) {
        const currTime = new Date().getTime()
        // 为了使setTimteout的尽可能的接近每秒60帧的效果
        const timeToCall = Math.max(0, 16 - (currTime - lastTime))
        const id = window.setTimeout(() => {
            callback(currTime + timeToCall)
        }, timeToCall)
        lastTime = currTime + timeToCall
        return id
    }

    cancelAnimationFrame = function (id) {
        window.clearTimeout(id)
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
完整代码:
requestAnimationFrame.js

let lastTime = 0
const prefixes = 'webkit moz ms o'.split(' ') // 各浏览器前缀

let requestAnimationFrame
let cancelAnimationFrame

// 判断是否是服务器环境
const isServer = typeof window === 'undefined'
if (isServer) {

requestAnimationFrame = function () {
    return
}
cancelAnimationFrame = function () {
    return
}

} else {

requestAnimationFrame = window.requestAnimationFrame
cancelAnimationFrame = window.cancelAnimationFrame
let prefix
// 通过遍历各浏览器前缀,来得到requestAnimationFrame和cancelAnimationFrame在当前浏览器的实现形式
for (let i = 0; i < prefixes.length; i++) {
    if (requestAnimationFrame && cancelAnimationFrame) { break }
    prefix = prefixes[i]
    requestAnimationFrame = requestAnimationFrame || window[prefix + 'RequestAnimationFrame']
    cancelAnimationFrame = cancelAnimationFrame || window[prefix + 'CancelAnimationFrame'] || window[prefix + 'CancelRequestAnimationFrame']
}

// 如果当前浏览器不支持requestAnimationFrame和cancelAnimationFrame,则会退到setTimeout
if (!requestAnimationFrame || !cancelAnimationFrame) {
    requestAnimationFrame = function (callback) {
        const currTime = new Date().getTime()
        // 为了使setTimteout的尽可能的接近每秒60帧的效果
        const timeToCall = Math.max(0, 16 - (currTime - lastTime))
        const id = window.setTimeout(() => {
            callback(currTime + timeToCall)
        }, timeToCall)
        lastTime = currTime + timeToCall
        return id
    }

    cancelAnimationFrame = function (id) {
        window.clearTimeout(id)
    }
}

}

export { requestAnimationFrame, cancelAnimationFrame }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
CountTo.vue组件思路
首先引入requestAnimationFrame.js,使用requestAnimationFrame方法接受count函数,还需要格式化数字,进行正则表达式转换,返回我们想要的数据格式。

引入 import { requestAnimationFrame, cancelAnimationFrame } from './requestAnimationFrame.js'
1
需要接受的参数:

const props = defineProps({
start: {

type: Number,
required: false,
default: 0

},
end: {

type: Number,
required: false,
default: 0

},
duration: {

type: Number,
required: false,
default: 5000

},
autoPlay: {

type: Boolean,
required: false,
default: true

},
decimals: {

type: Number,
required: false,
default: 0,
validator (value) {
  return value >= 0
}

},
decimal: {

type: String,
required: false,
default: '.'

},
separator: {

type: String,
required: false,
default: ','

},
prefix: {

type: String,
required: false,
default: ''

},
suffix: {

type: String,
required: false,
default: ''

},
useEasing: {

type: Boolean,
required: false,
default: true

},
easingFn: {

type: Function,
default(t, b, c, d) {
  return c * (-Math.pow(2, -10 * t / d) + 1) * 1024 / 1023 + b;
}

}
})

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
启动数字动效

const startCount = () => {
state.localStart = props.start
state.startTime = null
state.localDuration = props.duration
state.paused = false
state.rAF = requestAnimationFrame(count)
}
1
2
3
4
5
6
7
核心函数,对数字进行转动

相关文章
|
1天前
|
存储 JavaScript 前端开发
说说你对Event Loop的理解是什么
Event Loop(事件循环)是JavaScript中处理异步操作的一种机制,它帮助我们协调和处理各种任务的执行顺序。
30 0
|
6月前
|
内存技术
Egret的TimerEvent.TIMER和Event.ENTER_FRAME的区别
Egret的TimerEvent.TIMER和Event.ENTER_FRAME的区别
35 0
|
9月前
|
JavaScript
event loop的理解
event loop的理解
|
11月前
|
前端开发 JavaScript
前端|event.target与event.currentTarget的区别
前端|event.target与event.currentTarget的区别
61 0
this.counter$ = store.select(fromExample.getCounterCounter);
this.counter$ = store.select(fromExample.getCounterCounter);
79 0
this.counter$ = store.select(fromExample.getCounterCounter);
this.counter$ = store.select(fromExample.getCounterCounter)之后马上subscribe
this.counter$ = store.select(fromExample.getCounterCounter)之后马上subscribe
65 0
this.counter$ = store.select(fromExample.getCounterCounter)之后马上subscribe
|
Web App开发 前端开发
周期性取count请求是如何在前台setup的 - Tile count
Created by Jerry Wang, last modified on Oct 25, 2014
125 0
周期性取count请求是如何在前台setup的 - Tile count
|
前端开发 JavaScript
Event Loop详解
事件循环其实就是入栈出栈的循环。上面例子中说到了setTimeout,那setInterval呢,Promise呢等等等等,有很多异步的函数。但是这些异步任务有分宏任务(macro-task)和微任务(micro-task): macro-task包括: setTimeout, setInterval, setImmediate, I/O, UI rendering。
2401 0