/** * How big a picture of `w`×`h` units is drawn in a preview of `room` and where its top left lands. * `pad` is the room a worn shader asks for around it, as a share of each side (see `quadPadding`). * From one device pixel per unit on the zoom is whole device pixels, and the corner sits on one, so * pixel art stays sharp; below that the picture only shrinks to fit. `ratio` is device pixels per * panel pixel. */ export function previewFit( w: number, h: number, room: { w: number; h: number }, options: { margin: number; maxZoom: number; ratio: number; pad?: { u: number; v: number } | null }, ): { zoom: number; x: number; y: number } { const { margin, maxZoom, ratio, pad } = options; const fits = Math.min( (room.w - 2 * margin) / (w * (1 + 2 * (pad?.u ?? 0))), (room.h - 2 * margin) / (h * (1 + 2 * (pad?.v ?? 0))), maxZoom, ); const device = fits * ratio; const zoom = Math.max(0, device >= 1 ? Math.floor(device) / ratio : fits); const corner = (space: number, size: number) => Math.round(((space - size * zoom) / 2) * ratio) / ratio; return { zoom, x: corner(room.w, w), y: corner(room.h, h) }; }