From 2f21159acb243072f78f1690b7fb2a62002c73f4 Mon Sep 17 00:00:00 2001 From: Erik Date: Wed, 8 Apr 2026 12:49:38 +0200 Subject: [PATCH] feat: add dereth.png map background to radar canvas Draws a rotated/scaled slice of the overworld map behind radar dots. Map clips to the radar circle, rotates with heading-up mode, and renders at 40% opacity so dots remain visible on top. Co-Authored-By: Claude Opus 4.6 (1M context) --- static/script.js | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/static/script.js b/static/script.js index 3e5fc474..ab3dd9cf 100644 --- a/static/script.js +++ b/static/script.js @@ -3657,6 +3657,10 @@ function showRadarWindow(name) { listContainer.appendChild(listBody); content.appendChild(listContainer); + // Load map image for radar background + const radarMapImg = new Image(); + radarMapImg.src = 'dereth.png'; + // Store refs on the window win._radarCanvas = canvas; win._radarListBody = listBody; @@ -3664,6 +3668,7 @@ function showRadarWindow(name) { win._radarRangeDisplay = rangeDisplay; win._radarSelectedId = null; win._radarLastObjects = []; // cache for click hit-testing + win._radarMapImg = radarMapImg; // Scroll-wheel zoom on canvas canvas.addEventListener('wheel', (e) => { @@ -3726,6 +3731,39 @@ function updateRadarWindow(msg) { ctx.arc(cx, cy, cx, 0, Math.PI * 2); ctx.fill(); + // Map background (clip to circle, rotate to heading-up) + const mapImg = win._radarMapImg; + if (mapImg && mapImg.complete && mapImg.naturalWidth) { + ctx.save(); + // Clip to radar circle + ctx.beginPath(); + ctx.arc(cx, cy, cx - 1, 0, Math.PI * 2); + ctx.clip(); + // Map coordinate system: -102.1 to 102.1 for both axes + const mapCoordRange = 204.2; + const pixPerCoord = mapImg.naturalWidth / mapCoordRange; + // Player position in map pixel space + const mapPx = (playerEW + 102.1) * pixPerCoord; + const mapPy = (102.1 - playerNS) * pixPerCoord; // Y flipped (north = top) + // How many map pixels correspond to the radar range + const mapPixelsPerRadarPixel = (range * pixPerCoord) / (size / 2); + // Draw rotated map centered on player + ctx.translate(cx, cy); + ctx.rotate(-playerHeading * Math.PI / 180); // heading-up rotation + ctx.globalAlpha = 0.4; + const srcSize = range * pixPerCoord * 2; + ctx.drawImage(mapImg, + mapPx - srcSize / 2, mapPy - srcSize / 2, srcSize, srcSize, + -cx, -cy, size, size + ); + ctx.globalAlpha = 1.0; + ctx.restore(); + // Re-clip for remaining draws + ctx.beginPath(); + ctx.arc(cx, cy, cx, 0, Math.PI * 2); + ctx.clip(); + } + // Range rings ctx.strokeStyle = '#333'; ctx.lineWidth = 1;