-
Notifications
You must be signed in to change notification settings - Fork 22
/
patches.js
127 lines (106 loc) · 4.02 KB
/
patches.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
// Config
const MAX_PATCHES = 35;
const USE_SPEED_RANDOM = false;
const MIN_SPEED = 5;
const MAX_SPEED = 10;
const MIN_COLOUR_RANGE_VAL = 128;
const MS_PERIOD_BEFORE_ADDING_NEW_PATCH = 100;
const BRIGHTNESS_DISTANCE_RANGE = 15;
return class PatchesEffect {
patches = [];
constructor(display) {
this.display = display;
this.#clear();
this.#initPatches(1);
}
#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();
}
#randomColor() {
return [
Math.floor(Math.random() * MIN_COLOUR_RANGE_VAL) + (255 - MIN_COLOUR_RANGE_VAL),
Math.floor(Math.random() * MIN_COLOUR_RANGE_VAL) + (255 - MIN_COLOUR_RANGE_VAL),
Math.floor(Math.random() * MIN_COLOUR_RANGE_VAL) + (255 - MIN_COLOUR_RANGE_VAL)
];
}
#initPatches(count) {
for (let i = 0; i < count; i++) {
this.patches.push({
x: Math.random() * this.display.width,
y: Math.random() * this.display.height,
color: this.#randomColor(),
directionX: (Math.random() - 0.5) * 2,
directionY: (Math.random() - 0.5) * 2,
speed: USE_SPEED_RANDOM ? Math.random() * (MAX_SPEED - MIN_SPEED) + MIN_SPEED : 5
});
}
}
#movePatch(patch) {
patch.x += patch.directionX * patch.speed;
patch.y += patch.directionY * patch.speed;
if (patch.x <= 0 || patch.x >= this.display.width) {
patch.directionX *= -1;
}
if (patch.y <= 0 || patch.y >= this.display.height) {
patch.directionY *= -1;
}
}
#blendColor(baseColor, blendColor, blendFactor) {
return [
Math.min(255, baseColor[0] + blendColor[0] * blendFactor),
Math.min(255, baseColor[1] + blendColor[1] * blendFactor),
Math.min(255, baseColor[2] + blendColor[2] * blendFactor)
];
}
lastPatchTime = Date.now();
update() {
const now = Date.now();
if (now - this.lastPatchTime > MS_PERIOD_BEFORE_ADDING_NEW_PATCH && this.patches.length <= MAX_PATCHES) {
this.lastPatchTime = now;
this.patches.push({
x: Math.random() * this.display.width,
y: Math.random() * this.display.height,
color: this.#randomColor(),
directionX: (Math.random() - 0.5) * 2,
directionY: (Math.random() - 0.5) * 2,
speed: USE_SPEED_RANDOM ? Math.random() * (MAX_SPEED - MIN_SPEED) + MIN_SPEED : 5
});
}
let pixelBuffer = [];
for (let x = 0; x < this.display.width; x++) {
pixelBuffer[x] = [];
for (let y = 0; y < this.display.height; y++) {
pixelBuffer[x][y] = [0, 0, 0];
}
}
const total = this.display.width * this.display.height;
for (let patch of this.patches) {
this.#movePatch(patch);
for (let i = 0; i < total; i++) {
const x = i % this.display.width;
const y = Math.floor(i / this.display.width);
const distance = Math.sqrt(
Math.pow(x - patch.x, 2) + Math.pow(y - patch.y, 2)
);
const brightness = Math.max(0, 1 - distance / BRIGHTNESS_DISTANCE_RANGE);
pixelBuffer[x][y] = this.#blendColor(
pixelBuffer[x][y],
patch.color,
brightness
);
}
}
// Incredibly laggy to flush when iterating the patches for some reason, so using a buffer to record changes.
for (let x = 0; x < this.display.width; x++) {
for (let y = 0; y < this.display.height; y++) {
this.display.setPixel(x, y, pixelBuffer[x][y]);
}
}
this.display.flush();
}
}