From 01d89cf22cb418e3099c8a51d49e2f5c37f36565 Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Wed, 1 Jul 2026 21:07:24 -0500 Subject: [PATCH] Map tweaks --- editor/client/public/map/map.css | 2 +- editor/client/public/map/map.js | 75 +++++++++++++++++++++++++------- 2 files changed, 61 insertions(+), 16 deletions(-) diff --git a/editor/client/public/map/map.css b/editor/client/public/map/map.css index e4b3b054..54b8843d 100644 --- a/editor/client/public/map/map.css +++ b/editor/client/public/map/map.css @@ -9,7 +9,7 @@ flex-direction: column; flex-wrap: wrap; gap: 6px; - max-height: 512px; + max-height: 600px; } .tile-swatch { diff --git a/editor/client/public/map/map.js b/editor/client/public/map/map.js index d5b2592f..0693663c 100644 --- a/editor/client/public/map/map.js +++ b/editor/client/public/map/map.js @@ -41,16 +41,15 @@ [ChunkTerrain.TILE_SHAPE_RAMP_SOUTHWEST_INNER]: { dx: -1, dy: 1 }, }; - // Draws an arrow centered at (cx, cy) pointing toward the ramp's high - // side, so ramp direction is visible at a glance on both the palette - // swatches and the tile grid. - function drawArrow(ctx, cx, cy, size, dx, dy) { - const mag = Math.hypot(dx, dy) || 1; - const ux = dx / mag, uy = dy / mag; - const len = size * 0.32; - const tipX = cx + ux * len, tipY = cy + uy * len; - const tailX = cx - ux * len, tailY = cy - uy * len; + const INNER_CORNER_SHAPES = new Set([ + ChunkTerrain.TILE_SHAPE_RAMP_NORTHEAST_INNER, + ChunkTerrain.TILE_SHAPE_RAMP_NORTHWEST_INNER, + ChunkTerrain.TILE_SHAPE_RAMP_SOUTHEAST_INNER, + ChunkTerrain.TILE_SHAPE_RAMP_SOUTHWEST_INNER, + ]); + // Draws a single-headed arrow from (tailX, tailY) to (tipX, tipY). + function drawArrowSegment(ctx, tailX, tailY, tipX, tipY, size) { ctx.strokeStyle = "#ffffff"; ctx.fillStyle = "#ffffff"; ctx.lineWidth = Math.max(1, size * 0.08); @@ -62,7 +61,7 @@ ctx.stroke(); const headLen = size * 0.18; - const angle = Math.atan2(uy, ux); + const angle = Math.atan2(tipY - tailY, tipX - tailX); const leftAngle = angle + Math.PI * 0.8; const rightAngle = angle - Math.PI * 0.8; ctx.beginPath(); @@ -73,6 +72,54 @@ ctx.fill(); } + // Draws an arrow centered at (cx, cy) pointing toward the ramp's high + // side, so ramp direction is visible at a glance on both the palette + // swatches and the tile grid. Used for cardinal ramps and outer-corner + // ramps (a single raised corner). + function drawArrow(ctx, cx, cy, size, dx, dy) { + const mag = Math.hypot(dx, dy) || 1; + const ux = dx / mag, uy = dy / mag; + const len = size * 0.32; + drawArrowSegment(ctx, cx - ux * len, cy - uy * len, cx + ux * len, cy + uy * len, size); + } + + // Draws a plain right-angle bracket - two line segments meeting at 90 + // degrees at the tile's corner, one running along each of the two edges + // adjacent to it - so inner-corner ramps (three corners raised, one + // dropped) read as "the adjacent sides meeting in a 90-degree corner", + // distinct from the single diagonal arrow used for outer-corner ramps. + function drawCornerBracket(ctx, cx, cy, size, dx, dy) { + const cornerDist = size * 0.42; + const armLen = size * 0.34; + const cornerX = cx + dx * cornerDist; + const cornerY = cy + dy * cornerDist; + + ctx.strokeStyle = "#ffffff"; + ctx.lineWidth = Math.max(1, size * 0.08); + ctx.lineCap = "round"; + ctx.lineJoin = "round"; + + ctx.beginPath(); + ctx.moveTo(cornerX - dx * armLen, cornerY); + ctx.lineTo(cornerX, cornerY); + ctx.lineTo(cornerX, cornerY - dy * armLen); + ctx.stroke(); + } + + // Draws the direction icon for a ramp tile `type` in a `size`x`size` area + // centered at (cx, cy): a diagonal arrow for cardinal/outer-corner ramps, + // or a right-angle bracket for inner-corner ramps. No-op for shapes with + // no direction (ground, erase). + function drawShapeIcon(ctx, cx, cy, size, type) { + const dir = SHAPE_DIRECTIONS[type]; + if(!dir) return; + if(INNER_CORNER_SHAPES.has(type)) { + drawCornerBracket(ctx, cx, cy, size, dir.dx, dir.dy); + } else { + drawArrow(ctx, cx, cy, size, dir.dx, dir.dy); + } + } + // Draws a small pencil icon centered in a `size`x`size` canvas. function drawPencilIcon(ctx, size) { ctx.save(); @@ -434,13 +481,12 @@ buildPalette(); }); - const dir = SHAPE_DIRECTIONS[s.type]; - if(dir) { + if(SHAPE_DIRECTIONS[s.type]) { const icon = document.createElement("canvas"); icon.width = 32; icon.height = 32; icon.className = "tile-swatch-icon"; - drawArrow(icon.getContext("2d"), 16, 16, 32, dir.dx, dir.dy); + drawShapeIcon(icon.getContext("2d"), 16, 16, 32, s.type); btn.appendChild(icon); } @@ -500,8 +546,7 @@ ctx.strokeStyle = "rgba(255, 255, 255, 0.25)"; ctx.strokeRect(x * cell, sy, cell, cell); - const dir = SHAPE_DIRECTIONS[type]; - if(dir) drawArrow(ctx, x * cell + cell / 2, sy + cell / 2, cell, dir.dx, dir.dy); + drawShapeIcon(ctx, x * cell + cell / 2, sy + cell / 2, cell, type); } }