fix: HTML coord labels honor coordPlacement setting (top/middle/bottom)

After the SVG coord-label rendering was removed in 3cc956e, the
top/middle/bottom placement setting silently stopped working — the
HTML `.duckmage-hex-label` spans were just flex-centered inside the
hex, ignoring the setting.

Restored honour via CSS:
- `.duckmage-hex-label` is now `position: absolute; left: 50%;
  transform: translate(-50%, -50%)` so the parent's flex centering
  doesn't pin it. `top` is set per-placement class.
- `renderGrid` writes a `duckmage-coord-{top,middle,bottom}` class on
  the viewport, derived from `settings.coordPlacement`. Three CSS
  rules anchor the label at top: 22% / 50% / 78% (matching the
  previous SVG ±0.28 hex-height offsets so visual position is
  unchanged for users who never touched the setting).
- Default (when no class set) renders at top: 78% so an
  uninitialized state still looks like "bottom" — the same fallback
  the dropdown UI defaults to.

Coord-slip regression test in
frontend-testing/examples/coord-slip-on-zoom still PASSes: 0 slips
in the NEW bake mid-frame.
This commit is contained in:
isaprettycoolguy@protonmail.com 2026-06-21 11:29:11 -04:00
parent 3cc956ea79
commit d062bef610
2 changed files with 36 additions and 1 deletions

View file

@ -2660,6 +2660,18 @@ export class HexMapView extends ItemView {
/^\d*\.?\d+$/.test(gap) ? `${gap}em` : gap,
);
// Apply the coord-placement class so CSS can position HTML labels
// top / middle / bottom inside the hex. The setting was previously
// honoured only by the (now-removed) SVG coord-label copies; the
// HTML labels need this class to know where to render.
const placement = this.plugin.settings.coordPlacement ?? "bottom";
this.viewportEl.removeClass(
"duckmage-coord-top",
"duckmage-coord-middle",
"duckmage-coord-bottom",
);
this.viewportEl.addClass(`duckmage-coord-${placement}`);
const region = this.getActiveMap();
// Background image layer (behind hex grid; shares the viewport's pan/zoom

View file

@ -424,14 +424,37 @@ div.duckmage-hex-icon {
object-fit: unset; /* not applicable to divs */
}
/* Coord label: absolutely-positioned inside the hex so the parent's
flex centering doesn't fight us. Vertical anchor is set by a
`duckmage-coord-{top,middle,bottom}` class on the viewport see
the rules below. Horizontal is always centered via translate(-50%). */
.duckmage-hex-label {
position: relative; /* above icon */
position: absolute;
left: 50%;
transform: translate(-50%, -50%);
top: 78%; /* default: bottom — matches the previous SVG-label offset */
font-size: 0.6em;
font-weight: 600;
color: var(--text-muted);
pointer-events: none;
user-select: none;
z-index: 1;
white-space: nowrap;
}
/* Coord placement (settings "Coordinate placement"). The %s are tuned
so the label sits inside the visible hex polygon (which is clipped at
25%/75% on the vertical axis for pointy-top hexes and at 0/100% for
flat-top but the label needs to stay readable in both, so we use a
conservative margin from the edge). */
.duckmage-hex-map-viewport.duckmage-coord-top .duckmage-hex-label {
top: 22%;
}
.duckmage-hex-map-viewport.duckmage-coord-middle .duckmage-hex-label {
top: 50%;
}
.duckmage-hex-map-viewport.duckmage-coord-bottom .duckmage-hex-label {
top: 78%;
}
/* Outline keeps coordinates readable over any terrain color */