import { describe, expect, it } from "vitest"; import { MAX_ZOOM, MIN_ZOOM } from "../src/map/camera"; import { backgroundRect } from "../src/map/layout"; const viewports = [ { width: 390, height: 700 }, { width: 1280, height: 720 }, { width: 2560, height: 1440 }, { width: 320, height: 2000 }, ]; const pans = [-50_000, -800, -1, 0, 3, 640, 50_000]; const zooms = [MIN_ZOOM, 0.75, 1, 3, 12, MAX_ZOOM]; const images = [ { width: 1254, height: 1254 }, { width: 2048, height: 1024 }, ]; describe("background placement (decision 0.5.40)", () => { it("always fully contains the viewport", () => { for (const view of viewports) { for (const image of images) { for (const panX of pans) { for (const panY of pans) { for (const zoom of zooms) { const r = backgroundRect(view, { zoom, panX, panY }, image); const where = JSON.stringify({ view, image, panX, panY, zoom, r }); expect(r.x, where).toBeLessThanOrEqual(0); expect(r.y, where).toBeLessThanOrEqual(0); expect(r.x + r.width, where).toBeGreaterThanOrEqual(view.width - 1e-9); expect(r.y + r.height, where).toBeGreaterThanOrEqual(view.height - 1e-9); } } } } } }); it("moves a fraction of the pan (parallax) and keeps its aspect ratio", () => { const view = { width: 1280, height: 720 }; const image = { width: 1254, height: 1254 }; const still = backgroundRect(view, { zoom: 1, panX: 0, panY: 0 }, image); const panned = backgroundRect(view, { zoom: 1, panX: 100, panY: -60 }, image); expect(panned.x - still.x).toBeCloseTo(15); expect(panned.y - still.y).toBeCloseTo(-9); expect(still.width / still.height).toBeCloseTo(1); }); it("zooms only slightly with the map", () => { const view = { width: 1280, height: 720 }; const image = { width: 1254, height: 1254 }; const one = backgroundRect(view, { zoom: 1, panX: 0, panY: 0 }, image); const far = backgroundRect(view, { zoom: MAX_ZOOM, panX: 0, panY: 0 }, image); expect(far.width / one.width).toBeGreaterThan(1); expect(far.width / one.width).toBeLessThan(1.3); }); });