feat(map): tile-mode basemap mosaic previews on map picker cards
This commit is contained in:
parent
8c95c1ee82
commit
d51c8445bb
1 changed files with 31 additions and 0 deletions
|
|
@ -23,6 +23,21 @@ function basemapUrl(map: MapDoc): string | null {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Static preview for tile-mode maps: a 2x2 mosaic of the map's own zoom-1
|
||||||
|
* tiles covering the whole world square, center-cropped by the card frame.
|
||||||
|
*/
|
||||||
|
function tilePreviewUrls(template: string): string[] | null {
|
||||||
|
if (!template.includes("{z}") || !template.includes("{x}") || !template.includes("{y}")) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return [0, 1].flatMap((y) =>
|
||||||
|
[0, 1].map((x) =>
|
||||||
|
template.replace("{z}", "1").replace("{x}", String(x)).replace("{y}", String(y)),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export default async function MapPickerPage() {
|
export default async function MapPickerPage() {
|
||||||
const payload = await getPayload({ config: await config });
|
const payload = await getPayload({ config: await config });
|
||||||
|
|
||||||
|
|
@ -70,6 +85,10 @@ export default async function MapPickerPage() {
|
||||||
? (map.factionControl as Faction)
|
? (map.factionControl as Faction)
|
||||||
: null;
|
: null;
|
||||||
const url = basemapUrl(map);
|
const url = basemapUrl(map);
|
||||||
|
const tileUrls =
|
||||||
|
map.basemapMode === "tiles" && map.tileUrlTemplate
|
||||||
|
? tilePreviewUrls(map.tileUrlTemplate)
|
||||||
|
: null;
|
||||||
const stats = [
|
const stats = [
|
||||||
map.weather
|
map.weather
|
||||||
? {
|
? {
|
||||||
|
|
@ -101,6 +120,18 @@ export default async function MapPickerPage() {
|
||||||
alt={map.name}
|
alt={map.name}
|
||||||
className="size-full object-cover opacity-80 transition-opacity group-hover:opacity-100"
|
className="size-full object-cover opacity-80 transition-opacity group-hover:opacity-100"
|
||||||
/>
|
/>
|
||||||
|
) : tileUrls ? (
|
||||||
|
<div
|
||||||
|
aria-hidden="true"
|
||||||
|
className="absolute inset-0 flex items-center justify-center overflow-hidden"
|
||||||
|
>
|
||||||
|
<div className="grid size-[512px] max-w-none grid-cols-2 opacity-80 transition-opacity group-hover:opacity-100">
|
||||||
|
{tileUrls.map((tileUrl) => (
|
||||||
|
// eslint-disable-next-line @next/next/no-img-element
|
||||||
|
<img key={tileUrl} src={tileUrl} alt="" className="size-[256px]" />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="flex size-full items-center justify-center text-muted-foreground">
|
<div className="flex size-full items-center justify-center text-muted-foreground">
|
||||||
<MapIcon className="size-8 opacity-40" />
|
<MapIcon className="size-8 opacity-40" />
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue