Grid density: cut the board finer or coarser, per browser #14
@@ -277,8 +277,10 @@ below. Nothing is installed without someone clicking.
|
|||||||
**Grid** stepper sets how many columns this browser cuts the board into —
|
**Grid** stepper sets how many columns this browser cuts the board into —
|
||||||
8 to 24, 12 by default. Finer lets tiles be smaller so more fit across (a
|
8 to 24, 12 by default. Finer lets tiles be smaller so more fit across (a
|
||||||
4K wall), coarser suits a small screen read close up; row height follows,
|
4K wall), coarser suits a small screen read close up; row height follows,
|
||||||
so tiles keep their shape and simply change size. It saves with the
|
so tiles keep their shape and simply change size. Going coarser, a tile
|
||||||
layout, so a named layout comes back at the density it was arranged on.
|
that no longer fits where it was moves to the first free spot rather than
|
||||||
|
onto another tile. It saves with the layout, so a named layout comes back
|
||||||
|
at the density it was arranged on.
|
||||||
- Every tile has a **status dot**: green = live, amber = connecting,
|
- Every tile has a **status dot**: green = live, amber = connecting,
|
||||||
red = upstream unreachable (hover it for details). Tiles reconnect
|
red = upstream unreachable (hover it for details). Tiles reconnect
|
||||||
automatically.
|
automatically.
|
||||||
|
|||||||
+22
-3
@@ -296,8 +296,9 @@ function cellHeightFor(cols) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Cut the board into `cols` columns. Tiles keep their grid units — the
|
/** Cut the board into `cols` columns. Tiles keep their grid units — the
|
||||||
board gets denser or coarser and everything on it changes size with it;
|
board gets denser or coarser and everything on it changes size with it.
|
||||||
only a tile now past the right edge is pulled back in. */
|
A tile now past the right edge is pulled back in, and one that would then
|
||||||
|
sit on another moves to the first free spot instead. */
|
||||||
function setGridCols(value, { save = true } = {}) {
|
function setGridCols(value, { save = true } = {}) {
|
||||||
const next = normalizeGridCols(value);
|
const next = normalizeGridCols(value);
|
||||||
const changed = next !== COLS;
|
const changed = next !== COLS;
|
||||||
@@ -305,9 +306,16 @@ function setGridCols(value, { save = true } = {}) {
|
|||||||
grid.style.gridTemplateColumns = `repeat(${COLS}, minmax(0, 1fr))`;
|
grid.style.gridTemplateColumns = `repeat(${COLS}, minmax(0, 1fr))`;
|
||||||
document.documentElement.style.setProperty('--cell-h', cellHeightFor(COLS) + 'px');
|
document.documentElement.style.setProperty('--cell-h', cellHeightFor(COLS) + 'px');
|
||||||
if (changed) {
|
if (changed) {
|
||||||
for (const tile of tiles) {
|
// A coarser board may not have room for every tile where it was. Settle
|
||||||
|
// them in reading order: pull a tile past the right edge back in, and
|
||||||
|
// give one that would then land on a tile already settled the first free
|
||||||
|
// spot instead — tiles never overlap here, any more than under a drag.
|
||||||
|
const settled = [];
|
||||||
|
for (const tile of tiles.slice().sort((a, b) => a.y - b.y || a.x - b.x)) {
|
||||||
tile.w = Math.max(1, Math.min(COLS, tile.w));
|
tile.w = Math.max(1, Math.min(COLS, tile.w));
|
||||||
tile.x = Math.max(0, Math.min(COLS - tile.w, tile.x));
|
tile.x = Math.max(0, Math.min(COLS - tile.w, tile.x));
|
||||||
|
if (settled.some((s) => overlaps(tile, s))) Object.assign(tile, spotAmong(tile.w, tile.h, settled));
|
||||||
|
settled.push(tile);
|
||||||
applyRect(tile);
|
applyRect(tile);
|
||||||
notifyResize(tile);
|
notifyResize(tile);
|
||||||
}
|
}
|
||||||
@@ -386,6 +394,17 @@ function isFree(rect, excludeId) {
|
|||||||
return isFreeExcept(rect, [excludeId]);
|
return isFreeExcept(rect, [excludeId]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** First spot, scanning top-to-bottom, left-to-right, clear of these tiles. */
|
||||||
|
function spotAmong(w, h, others) {
|
||||||
|
for (let y = 0; y < 400; y += 1) {
|
||||||
|
for (let x = 0; x <= COLS - w; x += 1) {
|
||||||
|
const rect = { x, y, w, h };
|
||||||
|
if (!others.some((o) => overlaps(rect, o))) return { x, y };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return { x: 0, y: 0 };
|
||||||
|
}
|
||||||
|
|
||||||
/** First free spot scanning top-to-bottom, left-to-right. */
|
/** First free spot scanning top-to-bottom, left-to-right. */
|
||||||
function findSpot(w, h) {
|
function findSpot(w, h) {
|
||||||
for (let y = 0; y < 200; y += 1) {
|
for (let y = 0; y < 200; y += 1) {
|
||||||
|
|||||||
Reference in New Issue
Block a user