Commit graph

3 commits

Author SHA1 Message Date
isaprettycoolguy@protonmail.com
0e65565e25 fix: coord labels no longer slip up-left during zoom bake
The bug the user has been chasing for several sessions. Sandbox
repro at dev/coord-slip-sandbox.html, snapshot-coord-slip.mjs
captures the half-baked frame so we can SEE the slip.

Root cause: bakeZoom mutates the viewport font-size mid-function,
which triggers a layout reflow growing every em-based hex
dimension. The path-overlay SVG holds coord labels at pixel
positions computed against the PRE-bake hex sizes, so any paint
frame between the font-size change and the SVG rebuild shows the
labels at where the hexes USED to be — visibly shifted up-left of
the now-larger hexes. updatePathOverlay() further down in bakeZoom
eventually fixes it ("snap back into place"), but the intermediate
slip-then-snap is what the user reported across multiple zoom
sessions.

Fix: tear down the path / faction / region SVGs at the START of
bakeZoom, before the font-size mutation. The CSS rule
`.duckmage-svg-labels-active .duckmage-hex-label { visibility:
hidden }` is keyed off a class on the viewport — that class gets
removed alongside the SVG, so the intermediate paint falls back to
the HTML `.duckmage-hex-label` spans. Those live inside each hex's
own DOM tree, so they always track the hex's layout perfectly
across font-size changes. No slip.

The overlays are then re-rendered later in the function via the
existing updatePathOverlay() / updateFactionOverlay() /
updateRegionOverlay() / updateTokenLayer() calls. Net result: zero
extra rebuild work, just earlier tear-down.

Sandbox confirms:
  buggy-mid: SVG labels visibly shifted up-left of small hexes
  fixed-mid: HTML labels inside hexes, tracking correctly

351 unit tests / 18 e2e pass.
2026-06-21 11:09:12 -04:00
isaprettycoolguy@protonmail.com
5ce48af60d fix: grid expand/shrink preserves bg image alignment (1.4.1)
Adding or removing a row/column from the top or left of the grid used
to either visually bump the existing hexes (no compensation) or keep
the hexes in place but drift the background image away from them
(pan-only compensation). The fix pairs the pan shift with a matching
shift of the bg image's offsetX/Y in viewport coordinates, so the bg
and the hex grid both stay anchored in screen space after the click.

Also replaces the hex-height-based stride formula with a direct
measurement of the offsetTop/Left delta between two consecutive
rows/cols. The old formula `hex.offsetHeight * 0.75` ignored the
0.15em hex margin and drifted ~5 px per click; the new approach
captures everything that contributes to layout spacing.

Includes a sandbox + headless-Chromium test
(dev/bg-hex-alignment-sandbox.html + snapshot-bg-hex-alignment.mjs)
that verifies the originally-top hex AND a fixed bg-image feature
both stay within 0.6 px of their baseline screen position after one,
three, or repeated top-expand clicks.
2026-06-17 18:18:53 -04:00
isaprettycoolguy@protonmail.com
532df55342 feat: background image + grid calibration mode (1.4.0)
Per-map background image with full interactive calibration — pick or
drag-drop an image from the OS, drop straight into calibration mode,
align the hex grid to features in the image.

Calibration UX:
- Drag image body or grid body to move; corner/edge handles to resize
  (image is aspect-locked; grid has top/bottom edges for hex-aspect
  stretch). Anchor math: the side you grab moves, the opposite stays
  fixed — see topics/design/notes/resize-handle-anchor-rule in the KB
  for the derivation.
- Click an element to "focus" it; arrow keys nudge by 1 px (Shift = 10).
  Sequential nudges coalesce into one undo entry.
- Floating ✓ button bottom-right commits, Esc cancels. Wheel falls
  through to viewport zoom (precision alignment).
- Hex outlines drawn as an SVG overlay during calibration (CSS `border`
  and `drop-shadow` filter approaches both fail on clip-path-shaped
  hexes — the SVG overlay was chosen after sandbox iteration; see
  dev/hex-calibration-sandbox.html).
- Resize handles use `transform: scale(1/zoom)` so they stay constant
  screen size regardless of viewport zoom.
- Full undo/redo for every calibration mutation (drag, resize, nudge);
  Ctrl/Cmd+Z and Ctrl/Cmd+Shift+Z hotkeys wired at view scope.

Persistence + alignment:
- New MapData.savedViewport persists per-map zoom/pan/font-size across
  view close, so calibration values (sized to a specific font-size)
  don't drift when the view reopens.
- bakeZoom now scales calibration values by the bake factor so
  calibrated images stay aligned with the hex grid after wheel zoom.
  Suppressed entirely during calibration (and pending bake timers
  cancelled on entry) so the SVG outline doesn't drift mid-session.
- Path / faction / region overlay SVGs moved inside the gridContainer
  so they inherit the gridDisplay transform — previously they sat as
  siblings of the grid and drew at un-scaled coordinates, producing
  the "two grids" effect on calibrated maps.

Other UX:
- Top/left grid expand buttons now visually anchor — the existing grid
  stays put and the new row/column appears above/left, instead of the
  whole grid shifting down/right.
- New "Background image" section in both the MapModal Properties tab
  and the New map tab (with drop zone).
- Drag-and-drop OS images import to {hexFolder}/{mapName}/_bg/, with
  filename collision auto-rename.
- "No terrain" hexes become transparent when a bg image is set, so the
  image shows through.
- Calibration banner anchored to the view's contentEl (was body) so it
  can't survive across view-close; defensive sweep on open clears any
  banner left by a prior buggy build.

Dev infrastructure:
- dev/hex-calibration-sandbox.html — minimal hex grid that mirrors the
  plugin's CSS, used to iterate on calibration outline / overlay
  alignment approaches outside the live editor.
- dev/screenshot-approaches.mjs + snapshot-calibration-outline.mjs —
  runners against the shared frontend-testing tool that produce one
  PNG per CSS variant for LLM-direct visual review (see the
  frontend-testing-tools KB project).
2026-06-17 17:01:24 -04:00