diff --git a/src/lib.rs b/src/lib.rs index 36fda2d..c14017d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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); diff --git a/www/index.html b/www/index.html index e8472f4..c287893 100644 --- a/www/index.html +++ b/www/index.html @@ -22,6 +22,7 @@
+ diff --git a/www/index.js b/www/index.js index 81fbad5..d7cb343 100644 --- a/www/index.js +++ b/www/index.js @@ -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();