forked from lancaster-university/infolab-lights
-
Notifications
You must be signed in to change notification settings - Fork 0
/
rainbow.js
75 lines (61 loc) · 1.71 KB
/
rainbow.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
return class RainbowEffect {
/**
* Converts an HSV color value to RGB. Conversion formula
* adapted from http://en.wikipedia.org/wiki/HSV_color_space.
* Assumes h, s, and v are contained in the set [0, 1] and
* returns r, g, and b in the set [0, 255].
*
* @param Number h The hue
* @param Number s The saturation
* @param Number v The value
* @return Array The RGB representation
*/
hsvToRgb(h, s, v) {
var r, g, b;
var i = Math.floor(h * 6);
var f = h * 6 - i;
var p = v * (1 - s);
var q = v * (1 - f * s);
var t = v * (1 - (1 - f) * s);
switch (i % 6) {
case 0: r = v, g = t, b = p; break;
case 1: r = q, g = v, b = p; break;
case 2: r = p, g = v, b = t; break;
case 3: r = p, g = q, b = v; break;
case 4: r = t, g = p, b = v; break;
case 5: r = v, g = p, b = q; break;
}
return [r * 255, g * 255, b * 255];
}
constructor(display) {
this.display = display;
this.#clear();
this.position = 0;
this.tick = 0;
}
#clear() {
for (let x = 0; x < this.display.width; x++) {
for (let y = 0; y < this.display.height; y++) {
this.display.setPixel(x, y, [0, 0, 0]);
}
}
this.display.flush();
}
update() {
// limit our fps a bit
this.tick += 1;
if (this.tick < 3) {
return;
}
this.tick = 0;
for (let x = 0; x < this.display.width; x++) {
const color = this.hsvToRgb((this.position + x / this.display.width) % 1, 1, 0.5);
for (let y = 0; y < this.display.height; y++) {
this.display.setPixel(x, y, color);
}
}
this.display.flush();
this.position += 0.002;
this.position %= 1;
}
}