Skip to content

Commit 8714c25

Browse files
committed
update
1 parent cf1291e commit 8714c25

4 files changed

Lines changed: 470 additions & 86 deletions

File tree

app.js

Lines changed: 125 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,28 @@ const routes = {
88
"/piano": "pages/piano.html",
99
};
1010

11+
// Create a PCG random number generator
12+
function createPcgRandom(seed = 1) {
13+
let state = BigInt(seed);
14+
const multiplier = 6364136223846793005n;
15+
const increment = 1442695040888963407n;
16+
const mod = 2n ** 64n;
17+
const mod32 = 2 ** 32;
18+
19+
return function () {
20+
const oldState = state;
21+
state = (oldState * multiplier + increment) % mod;
22+
23+
const xorshifted = Number(((oldState >> 18n) ^ oldState) >> 27n);
24+
const rot = Number(oldState >> 59n);
25+
const result = (xorshifted >>> rot) | (xorshifted << (-rot & 31));
26+
27+
return (result >>> 0) / mod32;
28+
};
29+
}
30+
31+
const pcg = createPcgRandom(Date.now());
32+
1133
const app = document.getElementById("app");
1234
let currentPage = null; // To track the current page animation
1335

@@ -167,13 +189,13 @@ const matrixEffect = (canvasId, containerSelector) => {
167189
"lulz",
168190
"pwn",
169191
];
192+
const matrixLength = matrix.length;
193+
const sparkleTextLength = sparkleText.length;
170194

171-
const vec2 = (x, y) => ({ x, y });
172195
const font_size = 10;
173-
174-
const circle_buffer_width = canvas.width / font_size;
175-
const circle_buffer_height = canvas.height / font_size;
176-
const columns = canvas.width / font_size;
196+
const circle_buffer_width = (canvas.width / font_size) | 0;
197+
const circle_buffer_height = (canvas.height / font_size) | 0;
198+
const columns = circle_buffer_width;
177199
const drops = [];
178200
const particles = [];
179201
const lines = [];
@@ -187,28 +209,28 @@ const matrixEffect = (canvasId, containerSelector) => {
187209
drops[x] = 1;
188210
}
189211
for (let i = 0; i < drops.length; i++) {
190-
drops[i] = canvas.height / font_size;
212+
drops[i] = circle_buffer_height;
191213
}
192214
for (let i = 0; i < maxParticles; i++) {
193215
particles.push({
194-
x: Math.random() * canvas.width,
195-
y: Math.random() * canvas.height,
196-
radius: Math.random() * 170 + 25,
197-
speed: Math.random() * 6,
198-
dir: vec2(Math.random() - 0.5, Math.random() - 0.5),
216+
x: pcg() * canvas.width,
217+
y: pcg() * canvas.height,
218+
radius: pcg() * 170 + 25,
219+
speed: pcg() * 6,
220+
dir: { x: pcg() - 0.5, y: pcg() - 0.5 },
199221
});
200222
}
201223

202224
function plotPixel(x, y, v) {
203-
const sx = Math.floor(x) | 0;
204-
const sy = Math.floor(y) | 0;
205-
const index = (sy * circle_buffer_width + sx) | 0;
225+
const sx = x | 0;
226+
const sy = y | 0;
206227
if (
207228
sx >= 0 &&
208229
sx < circle_buffer_width &&
209230
sy >= 0 &&
210231
sy < circle_buffer_height
211232
) {
233+
const index = (sy * circle_buffer_width + sx) | 0;
212234
circle_buffer[index] = v;
213235
}
214236
}
@@ -225,92 +247,103 @@ const matrixEffect = (canvasId, containerSelector) => {
225247
}
226248

227249
function bresenhamCircle(centerX, centerY, radius) {
228-
centerX /= font_size;
229-
centerY /= font_size;
230-
radius /= font_size;
231-
centerX = Math.floor(centerX) | 0;
232-
centerY = Math.floor(centerY) | 0;
233-
radius = Math.floor(radius) | 0;
250+
const cx = (centerX / font_size) | 0;
251+
const cy = (centerY / font_size) | 0;
252+
const r = (radius / font_size) | 0;
253+
234254
let x = 0 | 0;
235-
let y = radius | 0;
236-
let d = (3 - 2 * radius) | 0;
237-
while (y > x) {
255+
let y = r | 0;
256+
let d = (3 - 2 * r) | 0;
257+
while (y >= x) {
258+
plotOctants(x, y, cx, cy);
238259
x++;
239260
if (d > 0) {
240261
y--;
241-
d = (d + 4 * (x - y)) | 0;
262+
d = d + 4 * (x - y); // + 10;
242263
} else {
243-
d = (d + 4 * x) | 0;
264+
d = d + 4 * x; // + 6;
244265
}
245-
plotOctants(x, y, centerX, centerY);
246266
}
247267
}
248268
const epsilon = 0.01;
249269

250270
function line(x0, y0, x1, y1) {
251-
x0 /= font_size;
252-
y0 /= font_size;
253-
x1 /= font_size;
254-
y1 /= font_size;
255-
x0 = Math.floor(x0) | 0;
256-
y0 = Math.floor(y0) | 0;
257-
x1 = Math.floor(x1) | 0;
258-
y1 = Math.floor(y1) | 0;
259-
const dx = Math.abs(x1 - x0);
260-
const dy = Math.abs(y1 - y0);
261-
const sx = Math.sign(x1 - x0);
262-
const sy = Math.sign(y1 - y0);
271+
let cx0 = (x0 / font_size) | 0;
272+
let cy0 = (y0 / font_size) | 0;
273+
const cx1 = (x1 / font_size) | 0;
274+
const cy1 = (y1 / font_size) | 0;
275+
276+
const dx = Math.abs(cx1 - cx0);
277+
const dy = Math.abs(cy1 - cy0);
278+
const sx = Math.sign(cx1 - cx0);
279+
const sy = Math.sign(cy1 - cy0);
263280
let err = dx - dy;
264281

265282
while (true) {
266-
plotPixel(x0, y0, 2);
283+
plotPixel(cx0, cy0, 2);
267284

268-
if (Math.abs(x0 - x1) + Math.abs(y0 - y1) < epsilon) break;
285+
if (Math.abs(cx0 - cx1) < epsilon && Math.abs(cy0 - cy1) < epsilon) break;
269286

270287
const e2 = 2 * err;
271288
if (e2 > -dy) {
272289
err -= dy;
273-
x0 += sx;
290+
cx0 += sx;
274291
}
275292
if (e2 < dx) {
276293
err += dx;
277-
y0 += sy;
294+
cy0 += sy;
278295
}
279296
}
280297
}
281298

282299
function drawCicleBuffer() {
300+
const blackFill = "rgba(0, 0, 0, 1)";
301+
const redFill = "rgba(122, 5, 5, 1)";
302+
const greenFill = "rgba(6, 46, 6, 1)";
303+
let currentFill = "";
304+
283305
for (let y = 0; y < circle_buffer_height; y++) {
284306
for (let x = 0; x < circle_buffer_width; x++) {
285307
const index = (y * circle_buffer_width + x) | 0;
286-
const xx = (x * font_size) | 0;
287-
const yy = (y * font_size) | 0;
288-
if (circle_buffer[index] > 0) {
289-
ctx.fillStyle = "rgba(0, 0, 0, 1)";
308+
const value = circle_buffer[index];
309+
310+
if (value > 0) {
311+
const xx = (x * font_size) | 0;
312+
const yy = (y * font_size) | 0;
313+
314+
if (currentFill !== blackFill) {
315+
ctx.fillStyle = blackFill;
316+
currentFill = blackFill;
317+
}
290318
ctx.fillRect(xx, yy, font_size, font_size);
291-
if (circle_buffer[index] === 2) {
292-
ctx.fillStyle = "rgba(122, 5, 5, 1)";
319+
320+
if (value === 2) {
321+
if (currentFill !== redFill) {
322+
ctx.fillStyle = redFill;
323+
currentFill = redFill;
324+
}
293325
} else {
294-
ctx.fillStyle = "rgba(6, 46, 6, 1)";
326+
if (currentFill !== greenFill) {
327+
ctx.fillStyle = greenFill;
328+
currentFill = greenFill;
329+
}
295330
}
296331

297-
const text = matrix[Math.floor(Math.random() * matrix.length)];
332+
const text = matrix[(pcg() * matrixLength) | 0];
298333
ctx.fillText(text, xx, yy + font_size);
299334
}
300335
}
301336
}
302337
}
303338

304339
function rndInt(min, max) {
305-
return Math.floor(Math.random() * (max - min + 1)) + min;
340+
return ((pcg() * (max - min + 1)) | 0) + min;
306341
}
307342

308343
function draw(deltaTime) {
309344
ctx.fillStyle = "rgba(0, 0, 0, 0.05)";
310345
ctx.fillRect(0, 0, canvas.width, canvas.height);
311346

312-
// Set the fill color to green
313-
ctx.fillStyle = "green";
314347
ctx.font = font_size + "px arial";
315348

316349
circle_buffer.fill(0);
@@ -322,17 +355,19 @@ const matrixEffect = (canvasId, containerSelector) => {
322355
if (p.x < 0 || p.x > canvas.width) p.dir.x *= -1;
323356
if (p.y < 0 || p.y > canvas.height) p.dir.y *= -1;
324357
bresenhamCircle(p.x, p.y, p.radius);
325-
if (Math.random() < 0.01) {
326-
p.dir = vec2(Math.random() - 0.5, Math.random() - 0.5);
327-
p.radius = Math.random() * 100 + 25;
358+
359+
if (pcg() < 0.01) {
360+
p.dir.x = pcg() - 0.5;
361+
p.dir.y = pcg() - 0.5;
362+
p.radius = pcg() * 100 + 25;
328363
}
329364
if (rndInt(0, 1000) < 5) {
330-
p.radius += Math.random() * 50 - 25;
365+
p.radius += pcg() * 50 - 25;
331366
}
332367

333368
if (rndInt(0, 1000) < 10) {
334-
ctx.fillStyle = "rgba(140, 213, 239, 0.75)";
335-
ctx.fillText(sparkleText[rndInt(0, sparkleText.length - 1)], p.x, p.y);
369+
ctx.fillStyle = "rgba(129, 199, 225, 0.75)";
370+
ctx.fillText(sparkleText[rndInt(0, sparkleTextLength - 1)], p.x, p.y);
336371
}
337372
}
338373

@@ -359,38 +394,46 @@ const matrixEffect = (canvasId, containerSelector) => {
359394

360395
drawCicleBuffer();
361396
for (let i = 0; i < drops.length; i++) {
362-
const text = matrix[Math.floor(Math.random() * matrix.length)];
397+
const text = matrix[(pcg() * matrixLength) | 0];
363398

364399
const tx = i * font_size;
365400
const ty = drops[i] * font_size;
366401

367402
ctx.fillText(text, tx, ty);
368403

369-
const cx = tx / font_size;
370-
const cy = ty / font_size;
371-
const index = (cy * circle_buffer_width + cx) | 0;
372-
if (circle_buffer[index] === 1) {
373-
ctx.fillStyle = "rgba(18, 215, 202, 1)";
374-
ctx.fillText(sparkleText[rndInt(0, sparkleText.length - 1)], tx, ty);
375-
ctx.fillText(
376-
sparkleText[rndInt(0, sparkleText.length - 1)],
377-
tx + font_size,
378-
ty + font_size
379-
);
380-
ctx.fillText(
381-
sparkleText[rndInt(0, sparkleText.length - 1)],
382-
tx - font_size,
383-
ty + font_size
384-
);
385-
}
386-
if (circle_buffer[index] === 2) {
387-
ctx.fillStyle = "rgba(215, 18, 18, 1)";
388-
ctx.fillText("FF", tx + font_size, ty + font_size);
389-
ctx.fillText("90", tx - font_size, ty + font_size);
404+
const cx = (tx / font_size) | 0;
405+
const cy = (ty / font_size) | 0;
406+
407+
if (
408+
cx >= 0 &&
409+
cx < circle_buffer_width &&
410+
cy >= 0 &&
411+
cy < circle_buffer_height
412+
) {
413+
const index = (cy * circle_buffer_width + cx) | 0;
414+
if (circle_buffer[index] === 1) {
415+
ctx.fillStyle = "rgba(18, 215, 202, 1)";
416+
ctx.fillText(sparkleText[rndInt(0, sparkleTextLength - 1)], tx, ty);
417+
ctx.fillText(
418+
sparkleText[rndInt(0, sparkleTextLength - 1)],
419+
tx + font_size,
420+
ty + font_size
421+
);
422+
ctx.fillText(
423+
sparkleText[rndInt(0, sparkleTextLength - 1)],
424+
tx - font_size,
425+
ty + font_size
426+
);
427+
}
428+
if (circle_buffer[index] === 2) {
429+
ctx.fillStyle = "rgba(215, 18, 18, 1)";
430+
ctx.fillText("FF", tx + font_size, ty + font_size);
431+
ctx.fillText("90", tx - font_size, ty + font_size);
432+
}
390433
}
391434
ctx.fillStyle = baseCol;
392435

393-
if (drops[i] * font_size > canvas.height && Math.random() > 0.975) {
436+
if (drops[i] * font_size > canvas.height && pcg() > 0.975) {
394437
drops[i] = 0;
395438
}
396439
drops[i]++;

pages/piano.html

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,24 @@ <h1>Piano Roll</h1>
22

33
<div class="piano-controls-section">
44
<div class="controls">
5-
<button id="clearBtn">Clear</button>
6-
<button id="playBtn">Play</button>
7-
<button id="stopBtn">Stop</button>
5+
<button id="clearBtn" class="btn">Clear</button>
6+
<button id="playBtn" class="btn">Play</button>
7+
<button id="stopBtn" class="btn">Stop</button>
88
</div>
99

1010
<div class="song-selector">
1111
<label for="songSelect">Load Song:</label>
1212
<select id="songSelect">
1313
<option value="">-- Select a Song --</option>
14+
<optgroup label="Themes">
15+
<option value="star-wars">Star Wars Main Theme</option>
16+
<option value="minder">Minder Theme</option>
17+
</optgroup>
1418
<optgroup label="Ragtime & Honky Tonk">
1519
<option value="honky-tonk" selected>Honky Tonk Stomp</option>
1620
</optgroup>
1721
</select>
18-
<button id="loadSongBtn">Load</button>
22+
<button id="loadSongBtn" class="btn">Load</button>
1923

2024
<label for="bpmSelect" style="margin-left: 20px">BPM:</label>
2125
<select id="bpmSelect">

0 commit comments

Comments
 (0)