feat(ui): F8-12 — map polish (zoom invariance, labels, selection, soft radius) (#55)
* Honest pixel-space sizing for `pointRadiusPx` / `strokeWidthPx`: the renderer divides by the current camera scale on every `viewport.zoomed` so thin lines / small markers stay the same on-screen size at any zoom. * Known-size planets switch to `pointRadiusWorld`, softened against the reference scale by `PLANET_SIZE_ZOOM_ALPHA = 0.33`; unidentified planets pin to a 3-px disc. * New planet label layer renders a two-line `name / #N` legend under each planet (`#N` only for unidentified or when the new `planetNames` toggle is off). Selection now paints an inverse-fill frame around the selected planet's label plus an outline on the disc; the old selection-ring primitive is retired. * Bombing markers swap the separate CirclePrim for a planet-outline overlay (damaged / wiped colour); the report deep-link moves to a "view bombing report" link in the planet inspector. * Docs + tests follow: `renderer.md` reflects the new sizing contract + label / outline layers, vitest covers the sizing math, label formatting, and the new toggle, and the map-toggles e2e adds a persistence case for `planetNames`. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -365,9 +365,39 @@ test("toggle state persists across a page reload", async ({ page }) => {
|
||||
expect(
|
||||
await page.getByTestId("map-toggles-bombing-markers").isChecked(),
|
||||
).toBe(false);
|
||||
// Battle X-cross and bombing ring are hidden in the renderer.
|
||||
// Battle X-cross primitives stay hidden in the renderer. F8-12 / #30
|
||||
// retired the bombing CirclePrim — the toggle now hides a planet
|
||||
// outline overlay, which sits outside the primitive surface; the
|
||||
// high-bit 0xc… range is permanently empty.
|
||||
expect(await visibleHighBitCount(page, 0xa0000000)).toBe(0);
|
||||
expect(await visibleHighBitCount(page, 0xc0000000)).toBe(0);
|
||||
});
|
||||
|
||||
test("planet-names toggle persists across a page reload (F8-12 / #29)", async ({
|
||||
page,
|
||||
}) => {
|
||||
await mockGateway(page, { currentTurn: 1 });
|
||||
await bootSession(page);
|
||||
await openGame(page);
|
||||
|
||||
await page.getByTestId("map-toggles-trigger").click();
|
||||
// Default ON; flip it OFF.
|
||||
expect(await page.getByTestId("map-toggles-planet-names").isChecked()).toBe(
|
||||
true,
|
||||
);
|
||||
await page.getByTestId("map-toggles-planet-names").click();
|
||||
expect(await page.getByTestId("map-toggles-planet-names").isChecked()).toBe(
|
||||
false,
|
||||
);
|
||||
|
||||
await page.reload({ waitUntil: "commit" });
|
||||
await expect(page.getByTestId("active-view-map")).toHaveAttribute(
|
||||
"data-status",
|
||||
"ready",
|
||||
);
|
||||
await page.getByTestId("map-toggles-trigger").click();
|
||||
expect(await page.getByTestId("map-toggles-planet-names").isChecked()).toBe(
|
||||
false,
|
||||
);
|
||||
});
|
||||
|
||||
// settledRenderCount waits out the mount/resize paint burst and returns
|
||||
|
||||
Reference in New Issue
Block a user