clone

a browser grid puzzle game where you push words around to rewrite the rules of each level

Fix pause highlight layering and mobile hints

Dami committed 4636e19
commit
4636e19b640ac577f813f69a7ae959f978bbb50a
parent
b3a754ee49b8e85c14e957f8f74442f2056e5fce
author
Dami <dami.etoile@gmail.com>
2 files changed, +44 -7
Msrc/render/stage-pause.js42+++++++++++++++++++++++++-----
Mtests/menu-motion.test.js9++++++
M src/render/stage-pause.js +35 -7
@@ -3,6 +3,22 @@ import { drawIndex } from "./index.js";
33 import { drawKeycap, drawTouchControls } from "./stage-hud.js";44 import { pauseMotionFrame, pauseMotionLayout } from "./menu-motion.js";55 6+export function wrapCanvasText(ctx, value, maxWidth) {7+ const words = String(value || "").trim().split(/\s+/).filter(Boolean);8+ if (!words.length) return [];9+ const lines = [];10+ let line = "";11+ for (const word of words) {12+ const candidate = line ? `${line} ${word}` : word;13+ if (line && ctx.measureText(candidate).width > maxWidth) {14+ lines.push(line);15+ line = word;16+ } else line = candidate;17+ }18+ if (line) lines.push(line);19+ return lines;20+}21+622 export function renderPauseScene(ctx, view = {}) {723 const { width: w, height: h } = view;824 const {
@@ -54,30 +70,42 @@ export function renderPauseScene(ctx, view = {}) {
5470 ctx.globalAlpha = 1;5571 const itemTop = h * 0.24;5672 const selectedY = itemTop + motion.selectedPosition * pauseMotionLayout.pitch;73+ pauseItems.forEach((item, i) => {74+ const itemMotion = motion.itemProgress[i] ?? 1;75+ const y = itemTop + i * pauseMotionLayout.pitch - (1 - itemMotion) * 22;76+ ctx.globalAlpha = itemMotion;77+ ctx.fillStyle = "#000000"; ctx.fillRect(w / 2 - 154, y - 21, 320, 54);78+ ctx.fillStyle = "#232120";79+ ctx.fillRect(w / 2 - 160, y - 27, 320, 54);80+ ctx.globalAlpha = 1;81+ });5782 if (pauseItems.length && motion.openProgress > 0) {5883 ctx.fillStyle = "#FF4B3E";59- ctx.fillRect(w / 2 - 160, selectedY - 27, 320, 54);84+ ctx.fillRect(w / 2 - 160, selectedY - 27, 320, pauseMotionLayout.height);6085 }6186 pauseItems.forEach((item, i) => {6287 const itemMotion = motion.itemProgress[i] ?? 1;6388 const y = itemTop + i * pauseMotionLayout.pitch - (1 - itemMotion) * 22;89+ const highlightTop = selectedY - 27;90+ const labelInHighlight = y >= highlightTop && y <= highlightTop + pauseMotionLayout.height;6491 ctx.globalAlpha = itemMotion;65- ctx.fillStyle = "#000000"; ctx.fillRect(w / 2 - 154, y - 21, 320, 54);66- ctx.fillStyle = i === selected ? "rgba(255,75,62,0)" : "#232120";67- ctx.fillRect(w / 2 - 160, y - 27, 320, 54);6892 ctx.fillStyle = "#0F0E0D";6993 ctx.font = "800 20px 'Apple Color Emoji', 'Segoe UI Emoji', sans-serif";7094 ctx.textAlign = "right";7195 ctx.fillText(i === Math.round(motion.selectedPosition) ? "🐾" : "", w / 2 - 176,7296 y + 1 - (i === Math.round(motion.selectedPosition) ? motion.pawHop : 0));73- ctx.fillStyle = i === selected ? "#0F0E0D" : "#F2EEE6";97+ ctx.fillStyle = labelInHighlight ? "#0F0E0D" : "#F2EEE6";7498 ctx.font = "800 13px Recursive, monospace"; ctx.textAlign = "center";7599 ctx.fillText(item.label, w / 2, y + 1 + (i === selected ? motion.pressOffset : 0));76100 ctx.globalAlpha = 1;77101 });78102 ctx.textAlign = "left"; ctx.fillStyle = "#8E877C"; ctx.font = "500 11px Recursive, monospace";79- if (pausedFrom !== "index" && pausedFrom !== "title")80- ctx.fillText(String(boardState?.hint || "Choose an action").trim(), 32, h - 86);103+ if (pausedFrom !== "index" && pausedFrom !== "title") {104+ const hintLines = wrapCanvasText(ctx, boardState?.hint || "Choose an action", Math.max(120, w - 64));105+ const hintLineHeight = 14;106+ const hintStart = h - 86 - (hintLines.length - 1) * hintLineHeight;107+ hintLines.forEach((line, index) => ctx.fillText(line, 32, hintStart + index * hintLineHeight));108+ }81109 const coarsePointer = view.coarsePointer ?? false;82110 if (w > 760 && !coarsePointer) {83111 drawKeycap(ctx, "↑↓", "choose", 32, h - 46);
M tests/menu-motion.test.js +9 -0