Commit graph

48 commits

Author SHA1 Message Date
isaprettycoolguy@protonmail.com
852e178113 chore: bump to 1.4.4
Highlights since 1.4.3:
- feat: delta-aware + rAF-batched wheel zoom (no inertia tail)
- feat: coord labels render above paths/icons in their own z:10 layer
- feat: coord label size / font / color settings (defaults to white)
- fix: hex cell spacing slider shows current value + refreshes live

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-21 13:00:57 -04:00
isaprettycoolguy@protonmail.com
a247b43851 chore: bump to 1.4.3
Highlights since 1.4.2:
- feat: multi-GM-icon support per hex with hex-subgrid layout (closes hexmaker#28)
- feat: right-click in GM paint mode removes one icon; count badge anchors to icon
- fix: GM-only paint mode is additive across icon switches
- fix: HTML region labels with PCA rotation — no slip-on-zoom
- fix: HTML coord labels honor coordPlacement (top/middle/bottom)
- fix: removed SVG coord-label copies; rely on in-hex HTML labels
- fix: token layer centered in gridContainer, not viewportEl

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-21 11:45:07 -04:00
isaprettycoolguy@protonmail.com
18738729ee fix: address obsidianmd reviewer rules (1.4.2)
Five separate categories the upstream obsidianmd reviewer flagged on
the 1.4.x diff, plus enforcement to catch them earlier.

- **no-static-styles-assignment** (5 sites in HexMapView.ts):
  Replace every direct `transform`/`transform-origin`/`opacity` write
  with CSS custom properties on the relevant container. Static rules
  in styles.css now reference them via
  `transform: translate(var(--duckmage-bg-tx, 0px), …) scale(...)`
  with identity-default fallbacks. JS writes only the values via
  `setCssProps({ "--duckmage-bg-tx": ... })`. Applies to the bg image
  layer, the hex grid container, AND the viewport itself. Two small
  helpers `applyBgLayerVars` / `applyGridLayerVars` centralise the
  variable plumbing and replace ad-hoc transform-string assembly at
  the drag / wheel / arrow-key / bake / shiftForGridGrowth call sites.
- **document → activeDocument** (4 sites in overlayPatternControls.ts):
  swap for popout-window compatibility.
- **setDynamicTooltip removal** (5 sites): the API is deprecated; the
  value is shown inline now.
- **Lint enforcement**: `obsidianmd/no-static-styles-assignment`
  promoted from default to error, so a regression breaks the local
  lint instead of waiting for the upstream reviewer. The other two
  patterns aren't shipped as eslint rules upstream — documented in
  CLAUDE.md under "Obsidian reviewer-bot conventions" so the next
  pass-through audits them by hand.

Sandbox regression check (dev/snapshot-bg-hex-alignment.mjs) still
PASSes — the CSS-var refactor doesn't disturb the bg-image / grid
alignment math from 1.4.1.
2026-06-17 18:48:13 -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
isaprettycoolguy@protonmail.com
84bcd76bd5 fix: legend swatch shows pattern at readable density (1.3.1)
Bumps the faction-legend swatch and shrinks the pattern tile so the
pattern is legible at swatch-size rather than showing just 1-2 tile
repeats.

- On-screen legend: hex 28 → 32 px, pattern tile scaled by swatch/96
  with a 4 px floor — yields ~6 repeats across the swatch.
- PNG legend: swatch fontSize*1.1 → fontSize*1.7, lineHeight floored
  at swatch+4 so rows don't overlap; pattern shrunk by the same ratio.
- renderHexPreview gains an optional patternScaleMultiplier param so
  callers (legend, palette, future small-swatch contexts) can shrink
  the pattern without touching the user's scale slider value.

Also bundles the prior 1.3.0 follow-up fixes (hex-shaped on-map-scale
preview, palette tile refresh-on-save, thin outline default + slider)
since those were committed locally on top of 1.3.0.
2026-06-17 12:33:00 -04:00
isaprettycoolguy@protonmail.com
f9e292c5f0 feat: faction & region overlay patterns (1.3.0)
Adds per-overlay pattern fills so factions and regions can be visually
distinguished when they overlap (issue #25). Each faction note and each
region note now carries a pattern, scale, and opacity in its
frontmatter, edited via the existing FactionEditor / GeoRegionEditor
modals (dropdown + sliders + live preview swatch).

Pattern set (10 total): solid (the existing flat fill, default),
diagonal stripes ↗ / ↖, crosshatch, polka dots, grid, zigzag,
triangles, scales, checker.

On screen: SVG <pattern> defs are deduped per (key,color,scale) and
referenced from each overlay path's fill. Stroke stays solid color so
blob boundaries remain crisp. Per-overlay opacity replaces the
hardcoded 0.45 group opacity.

PNG export: mirrored via Canvas patterns built from an offscreen tile
per (key,color,scale), cached for the render pass.

Backwards compatible — overlays without the new frontmatter keys fall
back to solid + 0.45 opacity, matching pre-1.3.0 behavior.
2026-06-17 11:53:04 -04:00
isaprettycoolguy@protonmail.com
d12cf38ceb fix: pin HexEditorModal to viewport on open (1.2.3)
makeDraggable previously used position: absolute with top/left 50%, which
relies on the nearest positioned ancestor being .modal-container. Any
plugin or theme that establishes a CSS containing block on an ancestor
(via transform/will-change/filter/contain) silently re-roots the modal
against that inner element, so it opens partway off-screen — as
reported in hexmaker#26.

Switch to position: fixed and compute the centered top/left in JS
against window.innerWidth/innerHeight, clamped 8px inside the viewport.
position: fixed bypasses most ancestor-containing-block issues; the JS
clamp catches the remaining edge cases (transformed ancestors that also
hijack fixed positioning).

Drag listeners now bind to modalEl.ownerDocument so dragging works
correctly inside popout windows.
2026-06-17 10:26:30 -04:00
isaprettycoolguy@protonmail.com
ce869324fc feat: coord placement setting + terrain tables in onboarding (1.2.2)
Setup wizard now generates the terrain description/encounter tables and
roller-link preamble as part of Step 3, so freshly onboarded vaults have
the full table scaffolding ready to use.

New "Coordinate placement" setting (top/middle/bottom, default bottom)
controls where the x_y label sits inside each hex, addressing
hexmaker#22 — keeps the label from clashing with a centered terrain
icon.
2026-06-16 10:34:57 -04:00
isaprettycoolguy@protonmail.com
1fa2153bf1 chore: address obsidianmd lint and popout-window compat (1.2.1)
- Sentence-case: rephrase "GM" → "Game master"; remove disable comments;
  autofixer lowercases "🎲 Open tables view" / "← Back" to comply
- no-static-styles-assignment: dynamic colors now use CSS custom properties
  (--duckmage-bg / --duckmage-border-color / --duckmage-fg) consumed by
  existing classes; static positions moved to small modifier classes
  (duckmage-rt-roll-btn-spaced, duckmage-wf-steps-list, etc.); terrain
  toolbar uses is-terrain-preview / is-eyedropper-active toggles;
  createIconEl uses new duckmage-masked-icon class
- Popout-window compat: setTimeout / clearTimeout / requestAnimationFrame
  → window.X; document.X → activeDocument.X across all view/modal files
- Unnecessary `as ArrayBuffer`: replace `data.buffer.slice(...) as ArrayBuffer`
  with `new ArrayBuffer + Uint8Array.set` — gets a real ArrayBuffer without
  the assertion (also avoids ArrayBufferLike narrowing)
- Deprecated SettingTab.display(): extract body into private renderSettings();
  display() and post-action refresh both call it
- eslint.config: add activeDocument + activeWindow to globals so the renamed
  identifiers don't trip no-undef

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-05 23:04:11 -04:00
isaprettycoolguy@protonmail.com
6aa885b5b2 feat: export module — PDF/Markdown for notes, hexes, maps, tables, workflows (1.2.0)
Adds a unified export pipeline under src/export/ with exporters for single notes,
structured hexes, maps (with reference table), random tables, and workflows
(with rolled samples). PDF rendering reuses Obsidian's MarkdownRenderer + theme
CSS; map PNG/PDF goes through a dedicated canvas renderer.

UI surface:
- "Export" tab in MapModal (PNG/PDF with overlay + size options)
- "Export" link in HexEditorModal + HexExportModal
- "Export PDF/Markdown" links in RandomTableView header
- "Export…" button in WorkflowEditorModal + WorkflowExportModal
- Commands: export current note (PDF/MD), current hex, current workflow
- File-menu items on any .md file: Export to PDF / Markdown

Other:
- New `exportFolder` setting (defaults to {worldFolder}/exports)
- hexGeometry: add hexSize / hexCenter / hexPolygonPoints / gridBoundingBox
- HexTableView + HexEditorModal: first-wins on duplicate palette names
  (matches HexMapView's .find() behaviour)
- Tests: unit + integration suites for all exporters; sim-vault fixture

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-05 20:46:41 -04:00
isaprettycoolguy@protonmail.com
0f910233ee 1.1.15
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 09:16:19 -04:00
isaprettycoolguy@protonmail.com
62f65c741f 1.1.14
feat: Ctrl/Cmd+click hex to open submap in new tab

When no drawing tool is active, Ctrl+click (Cmd+click on Mac) on a hex
with a linked submap opens that submap in a new Obsidian tab. Regular
left-click navigation (same tab) is unchanged.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 19:59:48 -04:00
isaprettycoolguy@protonmail.com
910d425040 1.1.13
feat: tabbed Maps modal; faction hover tooltip; map starting coordinates; default map/submap sizes in settings

- Maps modal refactored into three tabs: Maps (switch/delete), Properties (rename, terrain theme), New map (labeled fields, size presets)
- Faction overlay hover shows each faction on its own line with color swatch via custom floating tooltip div
- New map and submap creation accept starting X/Y coordinates; hex filenames and labels both reflect the chosen origin (gridOffset initialized accordingly)
- Map switching via modal now goes through switchToMap so viewport save/restore applies correctly
- Added defaultNewMapCols/Rows and defaultSubmapCols/Rows settings; new-map forms pre-fill from these

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 19:43:50 -04:00
isaprettycoolguy@protonmail.com
64810344cb feat: open submap from context menu; auto-fit grid on first visit; fix back-nav viewport
- Right-click context menu shows "Open submap: <name>" when the hex has
  a duckmage-submap link; clicking calls navigateToMap so Back works.
- switchToMap now saves/restores per-map viewport (zoom, panX, panY,
  fontSize). First visit to a map fits the full grid into view via
  fitGridToView(); subsequent visits restore the last-known position.
- fitGridToView resets the baked font-size before measuring so the
  scale calculation is always relative to the base font size.
- Fix: navigating Back was landing off-map because bakeZoom() encodes
  the visual zoom into viewportEl.style.fontSize and resets this.zoom=1.
  Saving/restoring fontSize alongside zoom/pan prevents the submap's
  baked scale from bleeding into the parent map's viewport.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-26 18:33:26 -04:00
isaprettycoolguy@protonmail.com
6f9c759850 1.1.11 2026-05-25 16:09:43 -04:00
isaprettycoolguy@protonmail.com
bad258acc9 1.1.10 2026-05-25 15:58:36 -04:00
isaprettycoolguy@protonmail.com
8214294c5e 1.1.9
- folder tree view in link-table modal (collapsed by default, filter expands all)
- shared renderFolderTree utility; RandomTableView refactored to use it
- submap picker: filterable list replaces combo-dropdown; terrain theme swatch per map
- map terrain theme: per-map terrainType field drives submap center-dot color and swatch in switch-map list
- erase mode for paths/factions/regions: "Remove" tile + enters erase immediately
- submap link tool: blip animation on hex after linking
- hex map view header updates to active map name on switch
- fix: link-table modal scopes folder tree to tablesFolder only (was leaking vault-wide folders)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 12:49:41 -04:00
isaprettycoolguy@protonmail.com
244739d951 1.1.8
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 20:14:48 -04:00
isaprettycoolguy@protonmail.com
a6b18dec9f 1.1.7 2026-05-23 14:30:52 -04:00
isaprettycoolguy@protonmail.com
924c8629b6 bump version to 1.1.5
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 03:52:10 -04:00
isaprettycoolguy@protonmail.com
fb98acbbaf bump version to 1.1.4; fix zoom pixelation, brush size reset, shrink rows/cols, icon folder onboarding
- Fix map pixelation on zoom: bake CSS scale() into viewport font-size after
  scroll wheel settles so the DOM renders natively at the zoomed resolution
  instead of upscaling a compositor bitmap; redraw SVG overlays after bake
- Fix terrain brush size persisting when switching to icon tool: reset
  paintBrushSize to 1 on icon mode entry
- Add shrink (−) buttons paired with each expand (+) button: fade in on hover,
  positioned to the right for top/bottom and below for left/right; clicking a
  clean row/col shrinks immediately and trashes the hex notes; clicking a dirty
  row/col shows a red OK? confirm state (3 s timeout) before deleting
- Fix stale terrain showing after delete+re-expand: pass null terrain/icon
  overrides for newly-added edge hexes so cached frontmatter from deleted files
  cannot bleed through
- Add iconsFolder to onboarding wizard folder generation step

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 03:38:01 -04:00
isaprettycoolguy@protonmail.com
b5dd942dc7 add sync awareness: onExternalSettingsChange + auto-register maps from vault
- Override onExternalSettingsChange() so Obsidian Sync delivering a new
  data.json from another device immediately reloads settings and refreshes
  all open HexMapView and HexTableView instances — no manual restart needed
- Add autoRegisterMapsFromVault() on startup: scans hexFolder subfolders and
  registers any that are missing from settings.maps, inferring grid size and
  offset from the x_y.md filenames. Handles the case where data.json arrives
  stale or empty but the vault folders already exist (e.g. sync timing, first
  install on a new device)

Closes #4

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 18:35:38 -04:00
isaprettycoolguy@protonmail.com
469cc56894 refine map delete UX: always-visible X, block last-map deletion, no red wash
- Replace hover-fade "Delete" button with a fixed 20×20px ✕ button always
  visible in each map row
- Hide the ✕ entirely when only one map remains (deletion blocked)
- Remove red background from confirmation row; use muted text instead

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 17:00:02 -04:00
isaprettycoolguy@protonmail.com
8ad991dc11 bump version to 1.1.1
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 16:51:24 -04:00
isaprettycoolguy@protonmail.com
683ef17ec1 add first-install setup wizard; bump to 1.1.0
- New SetupWizardView (ItemView): 4-step welcome → folders → map → done
- Wizard auto-opens on first install (setupComplete/setupDismissed flags)
- Folder step creates all world subfolders and ensures hex template exists
- Map step creates the first hex grid; done step shows recommended next steps
- "Open hex map" from done step opens map with terrain picker + toolbar open
- Re-run wizard button added to settings tab
- Fix: loadAvailableIcons() now runs inside onLayoutReady (vault readiness)
- Fix: migrateHexFilesToDefaultRegion() no longer creates world/hexes/default
  on fresh installs — scans candidates first, early-returns if none found
- Fix: loadHexTemplate() falls back to built-in default instead of returning null
- Fix: terrain toolbar button re-opens picker when clicked while active

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 16:39:01 -04:00
isaprettycoolguy@protonmail.com
96eef77ffa fix Obsidian reviewer lint errors; add lint to rebuild flow; bump to 1.0.28
- Remove unnecessary type assertions in IconPickerModal (createEl("input") already returns HTMLInputElement)
- Fix sentence-case violation: "Remove GM icon" → "Remove icon" in HexEditorModal tooltip
- Annotate frontmatter["region"] accesses as unknown to satisfy no-unsafe-assignment
- Wire npm run lint into /rebuild command so issues are caught locally before submission
- Document no-unnecessary-type-assertion and mid-sentence acronym patterns in /lint guidance

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 08:49:51 -04:00
isaprettycoolguy@protonmail.com
e7019aaca4 bump version 2026-05-10 17:11:01 -04:00
isaprettycoolguy@protonmail.com
31a6730cd1 prevent duplicate terrain names on rename; hide system-table filter checkboxes; version bump to 1.0.26
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 10:09:24 -04:00
isaprettycoolguy@protonmail.com
c984e9014b fix linter sentence-case error in icon picker hint text, version bump to 1.0.25
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 08:58:53 -04:00
isaprettycoolguy@protonmail.com
dd0cafe273 rework sentence to fix linter issue 2026-04-23 20:32:27 -04:00
nyxsys
7233128eba update package json 2026-03-30 18:58:07 -04:00
nyxsys
bac34d1050 fix a bunch of linter issues 2026-03-30 17:57:01 -04:00
nyxsys
473520d107 autofix sentence case 2026-03-30 16:51:13 -04:00
nyxsys
700bb9de3b regen lockfiles 2026-03-29 11:24:16 -04:00
nyxsys
04223b1abf update dependcies and clean up 2026-03-29 11:06:59 -04:00
nyxsys
ba3e1a1d6e use tsx for testing 2026-03-28 23:09:38 -04:00
isaprettycoolguy@protonmail.com
305cc24e70 switch out test suite to fix deprecation warning 2026-03-28 22:42:39 -04:00
isaprettycoolguy@protonmail.com
b1da4c3115 remove deprecated 2026-03-27 16:53:23 -04:00
nyxsys
c688033dd9 fix: remove win32-x64 esbuild pin that broke Linux CI 2026-03-27 11:41:51 -04:00
isaprettycoolguy@protonmail.com
2091648b26 add actual edge pathing 2026-03-26 21:07:04 -04:00
isaprettycoolguy@protonmail.com
d9c4f85087 allow user to add path types, include undo/redo support for them 2026-03-25 13:18:24 -04:00
nyxsys
a68fc92233 chore: update esbuild to 0.27.4, sync lock file
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 16:04:47 -04:00
nyxsys
26871e247b chore: sync package-lock.json
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 15:52:46 -04:00
isaprettycoolguy@protonmail.com
5fd49558fb add tests and set up the picker tool to change on selection 2026-03-12 20:21:11 -04:00
isaprettycoolguy@protonmail.com
48f0aa0d0d ux improvements 2026-03-09 16:59:36 -04:00
isaprettycoolguy@protonmail.com
1c35bf1837 fix bugs with adding terrain, make smoother, sketch out landmark adding 2026-02-14 13:01:42 -05:00
isaprettycoolguy@protonmail.com
9a4b5d4254 init commit 2026-02-12 19:27:36 -05:00