From 981c86e9f4c7dc2e1647a485d5eb08917f58f3c6 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Fri, 6 Mar 2026 09:30:06 -0500 Subject: [PATCH] Don't grow the grid if not needed, (shift tiles instead) At least, shifting of the tiles is what the user experiences. Within the code, the concept is simpler: We don't have a grid size at all anymore, but simply compute the grid bounds that we want whenever things change. The bounds are made to just fit the tiles (plus one extra row/column on each side) and never smaller than the original size chosen to fill the screen. --- letterrip/letterrip.jsx | 59 +++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 31 deletions(-) diff --git a/letterrip/letterrip.jsx b/letterrip/letterrip.jsx index a9e5437..ca07ee7 100644 --- a/letterrip/letterrip.jsx +++ b/letterrip/letterrip.jsx @@ -191,7 +191,10 @@ function get_cell_size() { /* The grid starts as the largest square that fits the viewport width * (capped at 10x10) and only grows when a tile is placed in one of - * the outermost rows/columns. */ + * the outermost rows/columns. When the grid expands in one direction, + * empty rows/columns on the opposite side are trimmed (keeping at + * least one empty row/column adjacent to the nearest tile). The grid + * never shrinks below the initial size. */ function initial_grid_size() { const cell_size = get_cell_size() + 2; /* +2 for 1px border each side */ const available = window.innerWidth - 32; /* rough page padding */ @@ -199,10 +202,12 @@ function initial_grid_size() { return Math.max(4, Math.min(10, fit)); } -function grid_bounds(grid, prev_bounds) { +function grid_bounds(grid) { + const min_size = initial_grid_size(); const keys = Object.keys(grid); + if (keys.length === 0) { - const half = Math.floor(initial_grid_size() / 2); + const half = Math.floor(min_size / 2); return { minR: -half, maxR: half - 1, minC: -half, maxC: half - 1 }; } @@ -217,28 +222,25 @@ function grid_bounds(grid, prev_bounds) { if (c > tileMaxC) tileMaxC = c; } - /* Start from previous bounds (or initial size if none). */ - let minR, maxR, minC, maxC; - if (prev_bounds) { - minR = prev_bounds.minR; - maxR = prev_bounds.maxR; - minC = prev_bounds.minC; - maxC = prev_bounds.maxC; - } else { - const half = Math.floor(initial_grid_size() / 2); - minR = Math.min(-half, tileMinR - 1); - maxR = Math.max(half - 1, tileMaxR + 1); - minC = Math.min(-half, tileMinC - 1); - maxC = Math.max(half - 1, tileMaxC + 1); - } - - /* Expand only if a tile touches the edge (ensure 1 empty row/col). */ - if (tileMinR <= minR) minR = tileMinR - 1; - if (tileMaxR >= maxR) maxR = tileMaxR + 1; - if (tileMinC <= minC) minC = tileMinC - 1; - if (tileMaxC >= maxC) maxC = tileMaxC + 1; - - return { minR, maxR, minC, maxC }; + /* The grid must include all tiles plus 1 empty row/column on each + * side, and must be at least min_size in each dimension. */ + const tile_rows = tileMaxR - tileMinR + 1 + 2; /* +2 for padding */ + const tile_cols = tileMaxC - tileMinC + 1 + 2; + const rows = Math.max(min_size, tile_rows); + const cols = Math.max(min_size, tile_cols); + + /* Center the extra space around the tiles. */ + const extra_rows = rows - tile_rows; + const extra_cols = cols - tile_cols; + const pad_top = Math.floor(extra_rows / 2); + const pad_left = Math.floor(extra_cols / 2); + + return { + minR: tileMinR - 1 - pad_top, + maxR: tileMinR - 1 - pad_top + rows - 1, + minC: tileMinC - 1 - pad_left, + maxC: tileMinC - 1 - pad_left + cols - 1 + }; } /********************************************************* @@ -343,7 +345,6 @@ class Game extends React.Component { drag_source: null, drag_over_cell: null, rack_drag_over: false, - grid_bounds: null, selected: null }; } @@ -927,11 +928,7 @@ class Game extends React.Component { render_board(analysis, invalid_cells, unconnected_cells) { const { grid, drag_over_cell, drag_source, selected } = this.state; - const bounds = grid_bounds(grid, this.state.grid_bounds); - /* Store bounds so the grid only grows, never shrinks. */ - if (JSON.stringify(bounds) !== JSON.stringify(this.state.grid_bounds)) { - setTimeout(() => this.setState({ grid_bounds: bounds }), 0); - } + const bounds = grid_bounds(grid); const rows = []; for (let r = bounds.minR; r <= bounds.maxR; r++) { -- 2.45.2