index.js
1.89 KB
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
63
64
65
66
67
68
69
70
71
72
73
74
75
var now = require('performance-now')
, root = typeof window === 'undefined' ? global : window
, vendors = ['moz', 'webkit']
, suffix = 'AnimationFrame'
, raf = root['request' + suffix]
, caf = root['cancel' + suffix] || root['cancelRequest' + suffix]
for(var i = 0; !raf && i < vendors.length; i++) {
raf = root[vendors[i] + 'Request' + suffix]
caf = root[vendors[i] + 'Cancel' + suffix]
|| root[vendors[i] + 'CancelRequest' + suffix]
}
// Some versions of FF have rAF but not cAF
if(!raf || !caf) {
var last = 0
, id = 0
, queue = []
, frameDuration = 1000 / 60
raf = function(callback) {
if(queue.length === 0) {
var _now = now()
, next = Math.max(0, frameDuration - (_now - last))
last = next + _now
setTimeout(function() {
var cp = queue.slice(0)
// Clear queue here to prevent
// callbacks from appending listeners
// to the current frame's queue
queue.length = 0
for(var i = 0; i < cp.length; i++) {
if(!cp[i].cancelled) {
try{
cp[i].callback(last)
} catch(e) {
setTimeout(function() { throw e }, 0)
}
}
}
}, Math.round(next))
}
queue.push({
handle: ++id,
callback: callback,
cancelled: false
})
return id
}
caf = function(handle) {
for(var i = 0; i < queue.length; i++) {
if(queue[i].handle === handle) {
queue[i].cancelled = true
}
}
}
}
module.exports = function(fn) {
// Wrap in a new function to prevent
// `cancel` potentially being assigned
// to the native rAF function
return raf.call(root, fn)
}
module.exports.cancel = function() {
caf.apply(root, arguments)
}
module.exports.polyfill = function(object) {
if (!object) {
object = root;
}
object.requestAnimationFrame = raf
object.cancelAnimationFrame = caf
}