Spaces:
Paused
Refit the canvas on any layout change, not just window resize (topbar-wrap bug)
Browse filesOn a narrow window the topbar's flex-wrap pushes its actions (the Help "?" among
them) onto a second line, growing the topbar and shrinking the view below it —
but that fires no window `resize` event, so resizeCanvas never ran. The backing
store kept its old, taller size: the never-redrawn strip showed as a thick band
at the bottom of the view, and because the render viewport and the click→world
transform then disagreed on the canvas height, every selection landed offset.
A ResizeObserver on the canvas refits the backing store the instant its box
changes — covering the topbar wrap, the Home button appearing, and the portrait
sheet collapse in one place — and re-clamps the camera into the map. Verified in
a real browser: narrowing to 460px wraps the topbar to 83px and the backing
store tracks the new client box exactly (no stale strip, no offset).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AEQUVetLk31Jj7niDQAsXL
|
@@ -55,6 +55,23 @@ function resizeCanvas() {
|
|
| 55 |
}
|
| 56 |
window.addEventListener("resize", resizeCanvas);
|
| 57 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 58 |
// A monitor move (or an OS scaling change) can change devicePixelRatio WITHOUT firing a resize
|
| 59 |
// event — the CSS layout size is unchanged — leaving the backing store at the old DPR (blurry on
|
| 60 |
// the sharper screen, oversampled on the other). matchMedia on the current dppx fires once when
|
|
|
|
| 55 |
}
|
| 56 |
window.addEventListener("resize", resizeCanvas);
|
| 57 |
|
| 58 |
+
// The canvas fills a flex region, so its box can change from a LAYOUT shift that fires NO window
|
| 59 |
+
// `resize` event — most visibly the topbar wrapping to a second line on a narrow window (its
|
| 60 |
+
// `flex-wrap` grows it, shrinking the view below), but also the Home button appearing or the
|
| 61 |
+
// portrait sheet collapsing. Without a refit, resizeCanvas never ran: the backing store kept its
|
| 62 |
+
// old, taller size, so the never-redrawn strip showed as a thick band at the bottom AND — because
|
| 63 |
+
// the render viewport and the click→world transform then disagreed on the canvas height — every
|
| 64 |
+
// selection landed offset. A ResizeObserver refits the backing store the instant the box changes,
|
| 65 |
+
// in one place (superseding the ad-hoc triggers above), and re-clamps the camera into the map.
|
| 66 |
+
if (window.ResizeObserver) {
|
| 67 |
+
new ResizeObserver(() => {
|
| 68 |
+
resizeCanvas();
|
| 69 |
+
if (game.state && game.input) {
|
| 70 |
+
clampCamera(game.input.getCamera(), game.state.map, canvas.clientWidth, canvas.clientHeight);
|
| 71 |
+
}
|
| 72 |
+
}).observe(canvas);
|
| 73 |
+
}
|
| 74 |
+
|
| 75 |
// A monitor move (or an OS scaling change) can change devicePixelRatio WITHOUT firing a resize
|
| 76 |
// event — the CSS layout size is unchanged — leaving the backing store at the old DPR (blurry on
|
| 77 |
// the sharper screen, oversampled on the other). matchMedia on the current dppx fires once when
|