1 | var now = require('performance-now')
|
---|
2 | , root = typeof window === 'undefined' ? global : window
|
---|
3 | , vendors = ['moz', 'webkit']
|
---|
4 | , suffix = 'AnimationFrame'
|
---|
5 | , raf = root['request' + suffix]
|
---|
6 | , caf = root['cancel' + suffix] || root['cancelRequest' + suffix]
|
---|
7 |
|
---|
8 | for(var i = 0; !raf && i < vendors.length; i++) {
|
---|
9 | raf = root[vendors[i] + 'Request' + suffix]
|
---|
10 | caf = root[vendors[i] + 'Cancel' + suffix]
|
---|
11 | || root[vendors[i] + 'CancelRequest' + suffix]
|
---|
12 | }
|
---|
13 |
|
---|
14 | // Some versions of FF have rAF but not cAF
|
---|
15 | if(!raf || !caf) {
|
---|
16 | var last = 0
|
---|
17 | , id = 0
|
---|
18 | , queue = []
|
---|
19 | , frameDuration = 1000 / 60
|
---|
20 |
|
---|
21 | raf = function(callback) {
|
---|
22 | if(queue.length === 0) {
|
---|
23 | var _now = now()
|
---|
24 | , next = Math.max(0, frameDuration - (_now - last))
|
---|
25 | last = next + _now
|
---|
26 | setTimeout(function() {
|
---|
27 | var cp = queue.slice(0)
|
---|
28 | // Clear queue here to prevent
|
---|
29 | // callbacks from appending listeners
|
---|
30 | // to the current frame's queue
|
---|
31 | queue.length = 0
|
---|
32 | for(var i = 0; i < cp.length; i++) {
|
---|
33 | if(!cp[i].cancelled) {
|
---|
34 | try{
|
---|
35 | cp[i].callback(last)
|
---|
36 | } catch(e) {
|
---|
37 | setTimeout(function() { throw e }, 0)
|
---|
38 | }
|
---|
39 | }
|
---|
40 | }
|
---|
41 | }, Math.round(next))
|
---|
42 | }
|
---|
43 | queue.push({
|
---|
44 | handle: ++id,
|
---|
45 | callback: callback,
|
---|
46 | cancelled: false
|
---|
47 | })
|
---|
48 | return id
|
---|
49 | }
|
---|
50 |
|
---|
51 | caf = function(handle) {
|
---|
52 | for(var i = 0; i < queue.length; i++) {
|
---|
53 | if(queue[i].handle === handle) {
|
---|
54 | queue[i].cancelled = true
|
---|
55 | }
|
---|
56 | }
|
---|
57 | }
|
---|
58 | }
|
---|
59 |
|
---|
60 | module.exports = function(fn) {
|
---|
61 | // Wrap in a new function to prevent
|
---|
62 | // `cancel` potentially being assigned
|
---|
63 | // to the native rAF function
|
---|
64 | return raf.call(root, fn)
|
---|
65 | }
|
---|
66 | module.exports.cancel = function() {
|
---|
67 | caf.apply(root, arguments)
|
---|
68 | }
|
---|
69 | module.exports.polyfill = function(object) {
|
---|
70 | if (!object) {
|
---|
71 | object = root;
|
---|
72 | }
|
---|
73 | object.requestAnimationFrame = raf
|
---|
74 | object.cancelAnimationFrame = caf
|
---|
75 | }
|
---|