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) <noreply@anthropic.com>
This commit is contained in:
parent
2b9aa7f4ae
commit
2f21159acb
1 changed files with 38 additions and 0 deletions
|
|
@ -3657,6 +3657,10 @@ function showRadarWindow(name) {
|
||||||
listContainer.appendChild(listBody);
|
listContainer.appendChild(listBody);
|
||||||
content.appendChild(listContainer);
|
content.appendChild(listContainer);
|
||||||
|
|
||||||
|
// Load map image for radar background
|
||||||
|
const radarMapImg = new Image();
|
||||||
|
radarMapImg.src = 'dereth.png';
|
||||||
|
|
||||||
// Store refs on the window
|
// Store refs on the window
|
||||||
win._radarCanvas = canvas;
|
win._radarCanvas = canvas;
|
||||||
win._radarListBody = listBody;
|
win._radarListBody = listBody;
|
||||||
|
|
@ -3664,6 +3668,7 @@ function showRadarWindow(name) {
|
||||||
win._radarRangeDisplay = rangeDisplay;
|
win._radarRangeDisplay = rangeDisplay;
|
||||||
win._radarSelectedId = null;
|
win._radarSelectedId = null;
|
||||||
win._radarLastObjects = []; // cache for click hit-testing
|
win._radarLastObjects = []; // cache for click hit-testing
|
||||||
|
win._radarMapImg = radarMapImg;
|
||||||
|
|
||||||
// Scroll-wheel zoom on canvas
|
// Scroll-wheel zoom on canvas
|
||||||
canvas.addEventListener('wheel', (e) => {
|
canvas.addEventListener('wheel', (e) => {
|
||||||
|
|
@ -3726,6 +3731,39 @@ function updateRadarWindow(msg) {
|
||||||
ctx.arc(cx, cy, cx, 0, Math.PI * 2);
|
ctx.arc(cx, cy, cx, 0, Math.PI * 2);
|
||||||
ctx.fill();
|
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
|
// Range rings
|
||||||
ctx.strokeStyle = '#333';
|
ctx.strokeStyle = '#333';
|
||||||
ctx.lineWidth = 1;
|
ctx.lineWidth = 1;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue