Skip to content
FreshMagPublic

About

Web app to turn D&D battle-map images into printable PDF or ODT, split across pages so that every grid square prints at true miniature size (2.54 cm)

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

6 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 

Repository files navigation

Arranger

Turn a D&D battle-map image into a printable PDF or ODT, split across pages so every grid square prints at true miniature size (2.54 cm / 1″ by default).

Arranger is a static web app — there is no server and no upload. Your maps are read, tiled and exported entirely inside your browser, so nothing ever leaves your machine.

Run locally

cd frontend
npm install
npm run dev      # http://localhost:5173

To produce the deployable site:

npm run build    # writes frontend/dist/
npm run preview  # serve that build locally

The build uses relative asset paths, so dist/ works at any URL — GitHub Pages, a subdirectory, Netlify, or a plain python -m http.server.

Deployment

.github/workflows/pages.yml builds the site and deploys it to GitHub Pages on every push to main (and on manual dispatch). One-time setup: in the repo's Settings → Pages, set Source to GitHub Actions.

Workflow

  1. Upload one or more map images (drag & drop). Files named <name>_<width>_<height>.png get their grid preset automatically (width/height in cells).
  2. Calibrate the grid with the select a square tool: drag a box around exactly one grid square. A loupe magnifies the pixels under the cursor (adjustable — see Settings), the eight handles fine-tune the box, and the floating bar takes exact pixel width and height (□ makes it a perfect square). Press Use and the app derives the number of columns and rows; Delete, the ✕ on the bar, or the right-click menu removes the selection again. Or just type cols × rows manually — the 🔗 button between the two fields keeps them in step with the map's aspect ratio so cells stay square; click it to unlink and set the two independently.
  3. Grid: toggles an overlay — blue lines are the cells, orange dashed lines are where page cuts will fall. Changing the grid size switches the overlay on by itself and blinks the cell lines a few times, so you can see straight away whether they line up with the squares on the map; Blink in the toolbar replays that at any time.
  4. Export…: previews every page. Click pages to exclude them, pick PDF or ODT, download.

Tools and navigation

The dock on the canvas holds the three tools and two toggles, each with a shortcut: pan (V), select a square (S), crop (C), show grid (G) and focus square (F), which centres the view on the selected square and zooms in far enough to work on it. Esc returns to the pan tool.

Scroll to zoom around the pointer and drag to pan. Holding Space (or Alt) pans from any tool and snaps back when you let go, so you can nudge the view mid-calibration without switching tools. The zoom control sits in the corner of the canvas (− / + / Fit); Fit frames the printable area, so once the map is cropped it zooms to the crop rather than the whole image.

Undo / redo

⌘Z / Ctrl+Z undoes, ⇧⌘Z or Ctrl+Y redoes, and the arrows sit at the left of the toolbar. Grid size, crop, selection and the tiled region are all tracked; a whole gizmo drag collapses into a single step. History is per map and resets when you switch maps.

Cropping and partial tiling

Crop trims the printable area: drag out a rectangle, then move it by dragging inside it or resize it with the handles. Dragging outside the crop pans the view instead of redrawing it, so the area you set can't be lost by a stray click. Everything dimmed is left out of the export. With snapping off, the loupe follows the handle you are dragging so edges can be placed to the pixel.

Cropping preserves the calibration rather than undoing it. Edges snap to whole cells (the Snap to grid checkbox, on by default) and the cell counts follow the new size, so a square keeps exactly the same number of pixels — trimming two columns off a 30 × 20 map leaves 28 × 20 at the same scale. Reset crop restores the full image and scales the counts back up.

To print just a corner of a big map, select a square and right-click it: the menu tiles only a 3×3, 5×5, 7×7 or custom block of squares centred on it. The chosen block is framed and labelled on the canvas, and the page count updates immediately. Clear it from the region badge to go back to the whole map.

Maps live in the page for as long as the tab is open — the browser warns you before you leave, since reloading clears the library.

Settings

  • Paper size / margin / cell size — page geometry; cell size defaults to 2.54 cm (a 1″ square).
  • Never cut squares vertically / horizontally — page cut lines snap to cell boundaries on that axis, so no square is ever split across two sheets (enable both to keep every square intact).
  • Drop small chunks — a slider (up to the printable size of one page). Pages narrower or shorter than the threshold — the slivers left at the edges of a map — are dimmed on the canvas so you can see what is being discarded, and excluded from the export. They still show in the export preview marked SMALL and can be re-included by clicking.

Under Advanced settings:

  • Calibration loupe — magnification (1.5×–16×) and diameter of the magnifier shown while selecting a square. Lower magnification shows more of the map around the cursor; higher is for pinning an edge to the exact pixel.

Layout

frontend/src/
  App.jsx              state: map library, grid, crop, region, settings
  hooks/useHistory.js  undo/redo with drag coalescing
  components/
    MapViewer.jsx      canvas: pan/zoom, tool dock, loupe, gizmos, overlays
    Sidebar.jsx        upload + map library
    SettingsPanel.jsx  page geometry, splitting options, loupe controls
    ExportModal.jsx    per-page preview and export
    geometry.js        rect maths shared by the crop and selection gizmos
    icons.jsx          line icons for the tool dock and undo/redo
  engine/
    tiler.js           page-splitting math + canvas tile cropping
    api.js             in-browser image library, previews, PDF export
    odt.js             ODT (zip of XML + PNGs) writer

Built with React + Vite; PDF export uses jsPDF and ODT export uses JSZip.

About

Web app to turn D&D battle-map images into printable PDF or ODT, split across pages so that every grid square prints at true miniature size (2.54 cm)

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages