From 401577ba210d25b68ecb62b17a75a0b6d4e52584 Mon Sep 17 00:00:00 2001 From: psychedelicious <4822129+psychedelicious@users.noreply.github.com> Date: Fri, 20 Sep 2024 05:59:56 +1000 Subject: [PATCH] fix(ui): gallery grid calculation There was an issue w/ the calculation causing an infinite loop but the fixed algorithm wasn't correct bc it doesn't take into account the grid gap correctly. This then breaks arrow key navigation. - Restore the previous calculation - Bail out if the gallery elements don't have any width, which causes the infinite loop - this part was missed when copying the logic from GalleryImageGrid --- .../gallery/hooks/useGalleryNavigation.ts | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/invokeai/frontend/web/src/features/gallery/hooks/useGalleryNavigation.ts b/invokeai/frontend/web/src/features/gallery/hooks/useGalleryNavigation.ts index 7e699aff979..fddd3fd6ea0 100644 --- a/invokeai/frontend/web/src/features/gallery/hooks/useGalleryNavigation.ts +++ b/invokeai/frontend/web/src/features/gallery/hooks/useGalleryNavigation.ts @@ -35,7 +35,6 @@ const getImagesPerRow = (): number => { if (!imageEl || !gridEl) { return 0; } - const container = gridEl.parentElement; if (!container) { return 0; @@ -44,16 +43,27 @@ const getImagesPerRow = (): number => { const imageRect = imageEl.getBoundingClientRect(); const containerRect = container.getBoundingClientRect(); + // We need to account for the gap between images const gridElStyle = window.getComputedStyle(gridEl); const gap = parseFloat(gridElStyle.gap); - // Validate input values - if (imageRect.width <= 0 || gap < 0) { + if (!imageRect.width || !imageRect.height || !containerRect.width || !containerRect.height) { + // Gallery is too small to fit images or not rendered yet return 0; } - // Calculate maximum number of images per row - const imagesPerRow = Math.floor((containerRect.width + 1) / (imageRect.width + gap)); + let imagesPerRow = 0; + let spaceUsed = 0; + + // Floating point precision can cause imagesPerRow to be 1 too small. Adding 1px to the container size fixes + // this, without the possibility of accidentally adding an extra column. + while (spaceUsed + imageRect.width <= containerRect.width + 1) { + imagesPerRow++; // Increment the number of images + spaceUsed += imageRect.width; // Add image size to the used space + if (spaceUsed + gap <= containerRect.width) { + spaceUsed += gap; // Add gap size to the used space after each image except after the last image + } + } return imagesPerRow; };