Files
ComfyAssets-ComfyUI_PromptM…/web/js/workspace/image-layout.mjs
T
Vito 590aa2cd0e feat(workspace): add native Images browsing and infinite scroll (#201)
* feat(workspace): add native image browsing and continuous loading

* test(workspace): assert empty collections through their status

* fix(workspace): rescan refreshed images and expose ancestor folders
2026-10-17 11:22:10 -07:00

43 lines
2.1 KiB
JavaScript

export function layoutImages(images, width, mode, minWidth = 240) {
const gap = 16;
const columns = mode === 'list' ? 1 : Math.max(1, Math.floor((width + gap) / (minWidth + gap)));
const cardWidth = Math.max(1, (width - gap * (columns - 1)) / columns);
const bottoms = Array(columns).fill(0);
let maxHeight = 0;
const positions = images.map((image, index) => {
const column = mode === 'masonry' ? bottoms.indexOf(Math.min(...bottoms)) : index % columns;
const ratio = image.width > 0 && image.height > 0 ? image.width / image.height : 4 / 3;
const height = mode === 'list' ? 106 :
(mode === 'masonry' ? Math.max(130, Math.min(440, cardWidth / ratio)) : cardWidth * .75) + 72;
maxHeight = Math.max(maxHeight, height);
const y = mode === 'grid' ? Math.floor(index / columns) * (height + gap) : bottoms[column];
bottoms[column] = y + height + gap;
return { x: column * (cardWidth + gap), y, width: cardWidth, height };
});
return { positions, height: Math.max(0, ...bottoms) - (images.length ? gap : 0), maxHeight };
}
export function visibleImages(positions, top, viewportHeight, focusedIndex = -1, maxHeight = 1024) {
const buffer = Math.max(600, viewportHeight);
const firstTop = top - buffer - maxHeight;
const lastTop = top + viewportHeight + buffer;
let low = 0, high = positions.length;
// Every layout emits monotonically increasing tops, including shortest-column masonry.
while (low < high) {
const middle = Math.floor((low + high) / 2);
if (positions[middle].y < firstTop) low = middle + 1;
else high = middle;
}
const indexes = [];
for (let index = low; index < positions.length; index++) {
const position = positions[index];
if (position.y > lastTop) break;
if (index === focusedIndex || position.y + position.height >= top - buffer) indexes.push(index);
}
if (focusedIndex >= 0 && focusedIndex < positions.length && !indexes.includes(focusedIndex)) {
indexes.push(focusedIndex);
indexes.sort((a, b) => a - b);
}
return indexes;
}