forked from angular/angular.js
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathraf.js
104 lines (92 loc) · 2.66 KB
/
raf.js
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
'use strict';
function $$RAFProvider() { //rAF
var provider = this;
provider.$$bufferLimit = 10;
this.$get = ['$window', '$timeout', function($window, $timeout) {
var requestAnimationFrame = $window.requestAnimationFrame ||
$window.webkitRequestAnimationFrame;
var cancelAnimationFrame = $window.cancelAnimationFrame ||
$window.webkitCancelAnimationFrame ||
$window.webkitCancelRequestAnimationFrame;
var rafSupported = !!requestAnimationFrame;
var rafFn = rafSupported
? function(fn) {
var id = requestAnimationFrame(fn);
return function() {
cancelAnimationFrame(id);
};
}
: function(fn) {
var timer = $timeout(fn, 16.66, false); // 1000 / 60 = 16.666
return function() {
$timeout.cancel(timer);
};
};
queueFn.supported = rafSupported;
function RAFTaskQueue(fn) {
this.queue = [];
this.count = 0;
this.afterFlushFn = fn;
}
RAFTaskQueue.prototype = {
push: function(fn) {
var self = this;
self.queue.push(fn);
self.count++;
self.rafWait(function() {
self.flush();
});
},
remove: function(index) {
if (this.queue[index] !== noop) {
this.queue[index] = noop;
if (--this.count === 0) {
this.reset();
this.flush();
}
}
},
reset:function() {
(this.cancelRaf || noop)();
this.count = this.queue.length = 0;
},
rafWait: function(fn) {
var self = this;
if (!self.cancelRaf) {
self.cancelRaf = rafFn(function() {
self.cancelRaf = null;
fn();
});
}
},
flush: function() {
for (var i = 0; i < this.queue.length; i++) {
this.queue[i]();
}
this.count = this.queue.length = 0;
this.afterFlushFn(this);
}
};
var tasks = [];
return queueFn;
function queueFn(fn) {
var lastTask = tasks.length && tasks[tasks.length - 1];
if (!lastTask || lastTask.count === provider.$$bufferLimit) {
lastTask = tasks[tasks.length] = new RAFTaskQueue(function(self) {
var taskIndex = tasks.indexOf(self);
if (taskIndex >= 0) {
tasks.splice(taskIndex, 1);
}
});
}
lastTask.push(fn);
var index = lastTask.count - 1;
return function cancelQueueFn() {
if (index >= 0) {
lastTask.remove(index);
index = null;
}
};
}
}];
}