Stage 7 UI polish: fix ad-marquee end, drop-time zoom, focus centring, sticky rack selection
Tests · UI / test (push) Successful in 11s
Tests · Go / test (pull_request) Successful in 6s
Tests · Integration / integration (pull_request) Successful in 12s
Tests · UI / test (pull_request) Successful in 11s

- AdBanner: move the side inset onto the scrolling track so the long message
  scrolls to its very end; pin body text-size-adjust:100% so iOS/Safari stops
  inflating the long marquee text.
- Game: do not zoom on drag start (the player may change their mind) — zoom and
  centre happen on drop, in attemptPlace; a stray tap on an occupied cell no
  longer cancels the rack selection (wait for an empty cell).
- Board: centre the focus cell after the zoom width transition finishes (was
  clamping to top-left mid-transition); compute the cell from the rendered
  scrollWidth.
This commit is contained in:
Ilia Denisov
2026-06-03 16:22:01 +02:00
parent 10d48884ac
commit 1e7da5925a
4 changed files with 35 additions and 8 deletions
+23 -6
View File
@@ -47,12 +47,29 @@
$effect(() => {
const vp = viewport;
if (!vp || !zoomed || !focus) return;
const cell = (vp.clientWidth * Z) / 15;
vp.scrollTo({
left: (focus.col + 0.5) * cell - vp.clientWidth / 2,
top: (focus.row + 0.5) * cell - vp.clientHeight / 2,
behavior: 'smooth',
});
const f = focus;
const scaler = vp.firstElementChild as HTMLElement | null;
const center = () => {
// Use the rendered scrollable width so the maths stays correct (gaps, padding).
const cell = vp.scrollWidth / 15;
vp.scrollTo({
left: (f.col + 0.5) * cell - vp.clientWidth / 2,
top: (f.row + 0.5) * cell - vp.clientHeight / 2,
behavior: 'smooth',
});
};
// When zoom has just turned on the board is still widening; centring now would
// clamp to the still-small scroll range and land top-left. Wait for the width
// transition to finish. If already zoomed (only the focus changed), centre at once.
if (scaler && scaler.clientWidth < vp.clientWidth * Z - 1) {
const onEnd = () => {
scaler.removeEventListener('transitionend', onEnd);
center();
};
scaler.addEventListener('transitionend', onEnd);
return () => scaler.removeEventListener('transitionend', onEnd);
}
center();
});
// Double-tap toggles zoom (pinch was dropped — it conflicts with native scroll).