From 521e611d6b1000c227bc684ef59458db921c838c Mon Sep 17 00:00:00 2001 From: Agent Date: Tue, 11 Aug 2026 16:51:30 -0400 Subject: [PATCH] fix: three bugs in computeUniformGrid sizing and scoring 1. Array-comparison bug (CRITICAL): 'key < bestKey' coerces arrays to comma-joined strings, so [1668,...] < [23,...] is TRUE ('1'<'2'). Replaced with explicit numeric lexicographic compare (compareKeys). Root cause of @matt's report: n=2 @1920x500 picked 1x2 stacked with 1668px overflow instead of 2x1 side-by-side fitting nearly exactly. 2. { + for (let i = 0; i < a.length; i++) { + if (a[i] !== b[i]) return a[i] - b[i] + } + return 0 +} + /** * Pick the column count that best fills the viewport. Prioritises: * 1. No vertical overflow (avoids unnecessary scroll) - * 2. Minimal leftover whitespace (h-pad + v-pad) - * 3. Aspect ratio closest to 16:9 - * 4. Larger tiles + * 2. No horizontal overflow (avoids sideways clip/scroll) + * 3. Minimal leftover whitespace (h-pad + v-pad) + * 4. Aspect ratio closest to 16:9 + * 5. Larger tiles */ export const computeUniformGrid = ( tileCount: number, @@ -83,9 +93,9 @@ export const computeUniformGrid = ( tileW = widthLimit tileH = widthLimit / TILE_ASPECT_MAX } else if (fillAspect < TILE_ASPECT_MIN) { - // Too tall: cap at 3:4, tiles narrower than full width -> h-pad - tileH = rowH - tileW = rowH * TILE_ASPECT_MIN + // Too tall: cap at 3:4, tiles shorter than row -> v-pad (letterbox) + tileW = widthLimit + tileH = widthLimit / TILE_ASPECT_MIN } else { // In range: fills both dims exactly tileW = widthLimit @@ -95,15 +105,17 @@ export const computeUniformGrid = ( const bboxW = cols * tileW + (cols - 1) * TILE_GAP const bboxH = rows * tileH + (rows - 1) * TILE_GAP const vOverflow = Math.max(0, bboxH - ch) + const hOverflow = Math.max(0, bboxW - cw) const waste = Math.max(0, cw - bboxW) + Math.max(0, ch - bboxH) const key = [ Math.round(vOverflow), + Math.round(hOverflow), Math.round(waste), Number(Math.abs(aspect - TILE_ASPECT_MAX).toFixed(3)), -Math.round(tileW * tileH), ] - if (!bestKey || key < bestKey) { + if (!bestKey || compareKeys(key, bestKey) < 0) { bestKey = key best = {cols, rows, tileWidth: tileW, tileHeight: tileH, aspect} }