-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
128 lines (108 loc) · 2.91 KB
/
index.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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
export default class ShowReel {
/*
* Builds a showreel with the incoming array of tasks.
* Each task is a function, with an optional `title` property
* attached.
*
* `delay` controls the delay time between each task.
* `infinite` forces the showreel to continuously loop through the tasks forever.
*/
constructor (tasks = [], delay = 4000, infinite = false) {
this._interval = null
this._tasks = []
this._delay = delay
this._lastTick = 0
this._taskIdx = 0 // Counter to keep track of what task is running
this._infinite = infinite // If we should infinite the task list while the showreel is running
this._el = document.createElement('ul')
this._el.className = 'showreel-task-list'
this._stopped = true
document.addEventListener('visibilitychange', () => {
if (document.hidden) {
window.clearInterval(this._interval)
} else {
setTimeout(this._createInterval.bind(this), 2000) // Give it a 2 second pause, then fire
}
}, false)
// Add all the tasks we received
tasks.forEach(task => this.add(task))
this._totalTasks = tasks.length
}
_clearActive () {
let active = this._el.querySelector('li.active')
if (active) {
active.classList.remove('active')
}
}
_tick () {
let now = performance.now()
, delta = now - this._lastTick
if (delta > this._delay) {
let next = this._tasks.shift()
this._taskIdx++
if (this._taskIdx > this._totalTasks && this._infinite) {
this._taskIdx = 1 // reset
}
if (!next) {
return this.clear()
}
next.call() // Fires the function
this._clearActive()
this._el.querySelector(`li:nth-child(${this._taskIdx})`).classList.add('active')
this._lastTick = now
if (this._infinite) {
// Add to the end of tasks
this._tasks.push(next)
}
}
}
_createInterval () {
if (!this._stopped) {
this._interval = window.setInterval(this._tick.bind(this), 50)
}
}
/*
* Adds the incoming task to our list of all tasks.
*/
add (task) {
this._tasks.push(task.callback)
let li = document.createElement('li')
li.innerHTML = task.title
this._el.append(li)
}
/*
* Returns the DOM node containing the list of tasks
*/
container () {
return this._el
}
/*
* Stops the showreel and removes all the tasks
*/
clear () {
this.stop()
this._tasks.length = 0
this._clearActive()
}
/*
* Showtime!
*/
start () {
delete this._stopped
if (this._interval) {
return
}
if (!this._lastTick) {
// No _lastTick, create a new one so we start firing immediately
this._lastTick = (new Date()).setFullYear(1900)
}
this._createInterval()
}
stop () {
this._stopped = true
if (this._interval) {
window.clearInterval(this._interval)
delete this._interval
}
}
}