Add play/pause button and toggle cell

This commit is contained in:
Fabian Schmidt 2025-02-24 11:12:17 +01:00
parent 7a68255eac
commit f68977a557
3 changed files with 65 additions and 2 deletions

View File

@ -28,6 +28,15 @@ pub enum Cell {
Alive = 1,
}
impl Cell {
fn toggle(&mut self) {
*self = match *self {
Cell::Dead => Cell::Alive,
Cell::Alive => Cell::Dead,
}
}
}
#[wasm_bindgen]
pub struct Universe {
width: u32,
@ -151,13 +160,20 @@ impl Universe {
self.height = height;
self.cells = (0..height * self.height).map(|_i| Cell::Dead).collect();
}
pub fn toggle_cell(&mut self, row: u32, col: u32) {
let idx = self.get_index(row, col);
self.cells[idx].toggle();
}
}
impl Universe {
// for test
pub fn get_cells(&self) -> &[Cell] {
&self.cells
}
// for test
pub fn set_cells(&mut self, cells: &[(u32, u32)]) {
for (row, col) in cells.iter().cloned() {
let idx = self.get_index(row, col);

View File

@ -22,6 +22,7 @@
<body>
<canvas id="game-of-life-canvas"></canvas>
<button id="play-pause"></button>
<script src="./bootstrap.js"></script>
</body>

View File

@ -16,8 +16,28 @@ const canvas = document.getElementById("game-of-life-canvas");
canvas.height = (CELL_SIZE + 1) * height + 1;
canvas.width = (CELL_SIZE + 1) * width + 1;
canvas.addEventListener("mousedown", event => {
const boundingRect = canvas.getBoundingClientRect();
const scaleX = canvas.width / boundingRect.width;
const scaleY = canvas.height / boundingRect.height;
const canvasLeft = (event.clientX - boundingRect.left) * scaleX;
const canvasTop = (event.clientY - boundingRect.top) * scaleY;
const row = Math.min(Math.floor(canvasTop / (CELL_SIZE + 1)), height - 1);
const col = Math.min(Math.floor(canvasLeft / (CELL_SIZE + 1)), width - 1);
universe.toggle_cell(row, col);
drawGrid();
drawCells();
});
const ctx = canvas.getContext('2d');
const playPauseButton = document.getElementById("play-pause");
const drawGrid = () => {
ctx.beginPath();
ctx.strokeStyle = GRID_COLOR;
@ -66,16 +86,42 @@ const drawCells = () => {
ctx.stroke();
};
const isPaused = () => {
return animationId === null;
};
const play = () => {
playPauseButton.textContent = "⏸";
renderLoop();
};
const pause = () => {
playPauseButton.textContent = "▶";
cancelAnimationFrame(animationId);
animationId = null;
};
playPauseButton.addEventListener("click", event => {
if (isPaused()) {
play();
} else {
pause();
}
});
let animationId = null;
const renderLoop = () => {
universe.tick();
drawGrid();
drawCells();
requestAnimationFrame(renderLoop);
animationId = requestAnimationFrame(renderLoop);
};
drawGrid();
drawCells();
requestAnimationFrame(renderLoop);
// requestAnimationFrame(renderLoop);
play();