forked from d3/d3
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtimer.js
More file actions
104 lines (91 loc) · 2.34 KB
/
timer.js
File metadata and controls
104 lines (91 loc) · 2.34 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
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
var d3_timer_queue = null,
d3_timer_interval, // is an interval (or frame) active?
d3_timer_timeout; // is a timeout active?
// The timer will continue to fire until callback returns true.
d3.timer = function(callback, delay, then) {
var found = false,
t0,
t1 = d3_timer_queue;
if (arguments.length < 3) {
if (arguments.length < 2) delay = 0;
else if (!isFinite(delay)) return;
then = Date.now();
}
// See if the callback's already in the queue.
while (t1) {
if (t1.callback === callback) {
t1.then = then;
t1.delay = delay;
found = true;
break;
}
t0 = t1;
t1 = t1.next;
}
// Otherwise, add the callback to the queue.
if (!found) d3_timer_queue = {
callback: callback,
then: then,
delay: delay,
next: d3_timer_queue
};
// Start animatin'!
if (!d3_timer_interval) {
d3_timer_timeout = clearTimeout(d3_timer_timeout);
d3_timer_interval = 1;
d3_timer_frame(d3_timer_step);
}
}
function d3_timer_step() {
var elapsed,
now = Date.now(),
t1 = d3_timer_queue;
while (t1) {
elapsed = now - t1.then;
if (elapsed >= t1.delay) t1.flush = t1.callback(elapsed);
t1 = t1.next;
}
var delay = d3_timer_flush() - now;
if (delay > 24) {
if (isFinite(delay)) {
clearTimeout(d3_timer_timeout);
d3_timer_timeout = setTimeout(d3_timer_step, delay);
}
d3_timer_interval = 0;
} else {
d3_timer_interval = 1;
d3_timer_frame(d3_timer_step);
}
}
d3.timer.flush = function() {
var elapsed,
now = Date.now(),
t1 = d3_timer_queue;
while (t1) {
elapsed = now - t1.then;
if (!t1.delay) t1.flush = t1.callback(elapsed);
t1 = t1.next;
}
d3_timer_flush();
};
// Flush after callbacks, to avoid concurrent queue modification.
function d3_timer_flush() {
var t0 = null,
t1 = d3_timer_queue,
then = Infinity;
while (t1) {
if (t1.flush) {
t1 = t0 ? t0.next = t1.next : d3_timer_queue = t1.next;
} else {
then = Math.min(then, t1.then + t1.delay);
t1 = (t0 = t1).next;
}
}
return then;
}
var d3_timer_frame = window.requestAnimationFrame
|| window.webkitRequestAnimationFrame
|| window.mozRequestAnimationFrame
|| window.oRequestAnimationFrame
|| window.msRequestAnimationFrame
|| function(callback) { setTimeout(callback, 17); };