scale by whole pixels, and make the stage small enough to matter
Two halves of the same problem: the picture was sharp everywhere and wrong overall. ── whole-number scaling ── The canvas is now sized to the largest WHOLE number of device pixels per source pixel that fits the panel, measured with a ResizeObserver and the device pixel ratio. Below 1x it takes a unit fraction instead, so the rows that survive are evenly spaced rather than dropped in clumps. This is a 16px-per-cell bitmap from 1995. At a fractional scale one cell gets three screen pixels and its neighbour gets two, the grid goes uneven and the digits wobble — which reads as "not quite right" rather than as blur, and `image-rendering: pixelated` does not help because unevenness is not blur. A fractional devicePixelRatio produces exactly this at what looks like 1:1. It is also allowed to scale UP past the framebuffer's own size, which was the other half of it: `max-w-full` only ever shrinks, so on a wide panel the canvas sat at its intrinsic size using a fraction of the pixels available. ── a smaller stage ── 800x600 down to 560x400. The stage is what gets scaled to fill the panel, so every pixel of empty surround is panel the game does not get, and the whole- number steps are far apart: in an 1866-device-pixel panel, 800 wide lands on 2x and 560 wide lands on 3x. Same panel, half again as much game. 560x400 is expert (504x342, measured on this machine) plus a margin. A custom board bigger than the stage is now clipped at the right and bottom rather than shrunk; `centre` clamps at zero so the menu bar stays reachable. Widen the two constants if that turns out to be the wrong trade. Verified: beginner centres at 204,93 on the new stage, which is exact. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Officer-Session: de3ed4e6-f88a-429c-94e6-a760336ba83b
This commit is contained in:
@@ -60,11 +60,19 @@ The check that matters is `ss -lntp` against the **running** process. Reading th
|
||||
listener that exists because a flag is missing, and running the same arguments by hand did not reproduce
|
||||
it either.
|
||||
|
||||
**The game is centred on a fixed stage, and the whole stage is what you see.** The framebuffer is 800x600
|
||||
**The game is centred on a fixed stage, and the whole stage is what you see.** The framebuffer is 560x400
|
||||
whatever the difficulty, `sidecar/session.ts` keeps the window in the middle of it, and the panel draws the
|
||||
framebuffer entire — scaled to fit, never cropped. So changing difficulty moves the board rather than
|
||||
resizing the panel, and the surround is teal (`-solid`) rather than the root's black.
|
||||
|
||||
**The stage is small because the panel scales it by whole numbers.** Pixel art at a fractional scale gets
|
||||
uneven cells — some three screen pixels wide, their neighbours two — which reads as "not quite right"
|
||||
rather than as blur, and `image-rendering: pixelated` does not help because unevenness is not blur. So the
|
||||
panel picks the largest whole number of DEVICE pixels per source pixel and every pixel of empty stage is
|
||||
panel the game does not get: in an 1866-device-pixel panel, 800 wide lands on 2x and 560 wide lands on 3x.
|
||||
560x400 is expert (504x342) plus a margin. A custom board bigger than that is clipped at the right and
|
||||
bottom rather than shrunk, with the menu bar kept reachable.
|
||||
|
||||
It used to park the window at the origin and have the client crop to the window's size, polled every four
|
||||
seconds. That resized the panel under the player, and it was off by the 3x29 wine puts between the root
|
||||
origin and the window — a black strip along the top and a row of cut-off cells along the bottom, worst on
|
||||
|
||||
Reference in New Issue
Block a user