src/sim/grid.ts 1.2 K raw
1
import { COLS, ROWS } from '../audio/scales';
2
3
export function cellAt(
4
	x: number,
5
	y: number,
6
	W: number,
7
	H: number,
8
): number {
9
	const col = Math.min(COLS - 1, Math.max(0, Math.floor((x / W) * COLS)));
10
	const row = Math.min(ROWS - 1, Math.max(0, Math.floor((y / H) * ROWS)));
11
	return row * COLS + col;
12
}
13
14
export function cellRowCol(idx: number): { row: number; col: number } {
15
	return { row: Math.floor(idx / COLS), col: idx % COLS };
16
}
17
18
export function drawGrid(
19
	ctx: CanvasRenderingContext2D,
20
	W: number,
21
	H: number,
22
	flashes: Map<number, number>,
23
	now: number,
24
	flashMs: number,
25
) {
26
	const cw = W / COLS;
27
	const ch = H / ROWS;
28
29
	for (const [idx, end] of flashes) {
30
		const remain = end - now;
31
		if (remain <= 0) {
32
			flashes.delete(idx);
33
			continue;
34
		}
35
		const a = (remain / flashMs) * 0.18;
36
		const { row, col } = cellRowCol(idx);
37
		ctx.fillStyle = `rgba(245, 243, 238, ${a})`;
38
		ctx.fillRect(col * cw, row * ch, cw, ch);
39
	}
40
41
	ctx.strokeStyle = 'rgba(245, 243, 238, 0.08)';
42
	ctx.lineWidth = 1;
43
	ctx.beginPath();
44
	for (let c = 1; c < COLS; c++) {
45
		const x = c * cw;
46
		ctx.moveTo(x, 0);
47
		ctx.lineTo(x, H);
48
	}
49
	for (let r = 1; r < ROWS; r++) {
50
		const y = r * ch;
51
		ctx.moveTo(0, y);
52
		ctx.lineTo(W, y);
53
	}
54
	ctx.stroke();
55
}