From e33598476aa9c8b4ec98fa289ae71710259e9247 Mon Sep 17 00:00:00 2001 From: Richard Zink Date: Thu, 8 Oct 2026 09:28:28 +0200 Subject: [PATCH] Labels in normal orientation (not X-mirrored) User wanted the image to be X-mirrored (NS-mirror, so place names on a map are correctly mirrored for the corridor orientation), but the text labels to be readable normally. Now labels are drawn in normal orientation: - N at top-left - S at bottom-left - y at top-right - x at bottom-right The text is no longer reversed. With the corridor's X-swap arrangement, this means: - screen left = west tiles (low x) - screen right = east tiles (high x) - within each tile, the image is X-mirrored, but the text inside is readable --- vendor/clouds3d.js | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/vendor/clouds3d.js b/vendor/clouds3d.js index 09574eb..61c6cdc 100644 --- a/vendor/clouds3d.js +++ b/vendor/clouds3d.js @@ -370,29 +370,27 @@ function drawTileAt(lng, perp, dx, dz, centerTileX, centerTileY) { groundCtx.strokeStyle = 'rgba(0,0,0,0.85)'; groundCtx.lineWidth = 3; groundCtx.font = 'bold 40px sans-serif'; - // Helper: draw a horizontally-mirrored label at (x, y). - function mirrorLabel(text, x, y, align) { - groundCtx.save(); - groundCtx.translate(x, y); - groundCtx.scale(-1, 1); - groundCtx.textAlign = align; - groundCtx.strokeText(text, 0, 0); - groundCtx.fillText(text, 0, 0); - groundCtx.restore(); - } - // S at top-left, textAlign 'right' so the text's right edge - // is at the anchor (text extends into the tile from the left - // edge of the tile area). - mirrorLabel('S', canvasX + 12, canvasY + 44, 'right'); - // N at bottom-left - mirrorLabel('N', canvasX + 12, canvasY + 244, 'right'); - // Tile coordinates, top-right and bottom-right corners + // Labels in normal (non-mirrored) orientation so the user can + // read them. The image content itself is X-flipped (NS-mirror) + // for the corridor orientation; the labels are drawn on top + // in normal orientation for legibility. + groundCtx.font = 'bold 40px sans-serif'; + groundCtx.textAlign = 'left'; + // N at top-left of tile area (image north is at canvas top) + groundCtx.strokeText('N', canvasX + 12, canvasY + 44); + groundCtx.fillText('N', canvasX + 12, canvasY + 44); + // S at bottom-left + groundCtx.strokeText('S', canvasX + 12, canvasY + 244); + groundCtx.fillText('S', canvasX + 12, canvasY + 244); + // Tile coordinates groundCtx.font = 'bold 18px monospace'; - // y at top-right, textAlign 'left' so text extends into the - // tile from the right edge. - mirrorLabel('y=' + tileY, canvasX + GROUND_TILE_SIZE - 12, canvasY + 28, 'left'); + groundCtx.textAlign = 'right'; + // y at top-right + groundCtx.strokeText('y=' + tileY, canvasX + GROUND_TILE_SIZE - 12, canvasY + 28); + groundCtx.fillText('y=' + tileY, canvasX + GROUND_TILE_SIZE - 12, canvasY + 28); // x at bottom-right - mirrorLabel('x=' + tileX, canvasX + GROUND_TILE_SIZE - 12, canvasY + GROUND_TILE_SIZE - 12, 'left'); + groundCtx.strokeText('x=' + tileX, canvasX + GROUND_TILE_SIZE - 12, canvasY + GROUND_TILE_SIZE - 12); + groundCtx.fillText('x=' + tileX, canvasX + GROUND_TILE_SIZE - 12, canvasY + GROUND_TILE_SIZE - 12); return true; }).catch(function() {