export class Renderer { constructor(canvas, { cellSize = 12 } = {}) { this.canvas = canvas; this.ctx = canvas.getContext("2d", { alpha: false }); this.cellSize = cellSize; } setCellSize(cellSize) { this.cellSize = cellSize; } resizeCanvas(rows, cols) { this.canvas.width = cols * this.cellSize; this.canvas.height = rows * this.cellSize; } clear(backgroundColor) { this.ctx.fillStyle = backgroundColor; this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height); } drawGrid(rows, cols, color) { const { ctx, cellSize } = this; ctx.save(); ctx.beginPath(); ctx.strokeStyle = color; ctx.lineWidth = 1; ctx.globalAlpha = 0.35; for (let col = 0; col <= cols; col += 1) { const x = col * cellSize + 0.5; ctx.moveTo(x, 0); ctx.lineTo(x, this.canvas.height); } for (let row = 0; row <= rows; row += 1) { const y = row * cellSize + 0.5; ctx.moveTo(0, y); ctx.lineTo(this.canvas.width, y); } ctx.stroke(); ctx.restore(); } drawCells(buffer, rows, cols, fillColor) { const { ctx, cellSize } = this; ctx.fillStyle = fillColor; for (let row = 0; row < rows; row += 1) { const rowOffset = row * cols; for (let col = 0; col < cols; col += 1) { const idx = rowOffset + col; if (buffer[idx] === 1) { const x = col * cellSize; const y = row * cellSize; ctx.fillRect(x, y, cellSize, cellSize); } } } } render(engine, { showGrid, colors }) { this.clear(colors.background); this.drawCells(engine.current, engine.rows, engine.cols, colors.cell); if (showGrid) { this.drawGrid(engine.rows, engine.cols, colors.grid); } } }