Export hex maps as clean SVG for use in documentation, PDFs, rulebooks, or other web projects. Two approaches: postMessage from an iframe embed, or direct JavaScript API in the same page.
The hexmaps engine can produce standalone SVG output from any generated map. SVGs are resolution-independent and work well in print/PDF contexts where Canvas output would pixelate.
Choose your approach based on context:
The generator interface includes an "Export SVG" button in the sidebar (Random tab). Clicking it downloads the current map as an SVG file named {game}-{size}r-{seed}.svg.
This produces SVG with linked image references (relative paths to img/tiles/). The SVG is self-contained for colour-only styles (classic) but requires the tile images to be accessible at the referenced paths for image styles.
Embed the generator in a hidden iframe and request SVG via the postMessage bridge. This is the recommended approach for external projects that need reproducible map output.
var iframe = document.createElement('iframe');
iframe.src = 'https://hex.moddable.games/generate/?game=talisman&size=4&seed=42&style=artistic&boardonly=1';
iframe.style.display = 'none';
document.body.appendChild(iframe);
iframe.onload = function() {
iframe.contentWindow.postMessage({ type: 'hexmap:exportSvg' }, '*');
};
window.addEventListener('message', function(event) {
if (event.data.type === 'hexmap:svgData') {
document.getElementById('map-container').innerHTML = event.data.svg;
}
});
The boardonly=1 parameter hides the UI chrome, reducing iframe load time. The seed ensures the same map is generated every time.
Available postMessage commands:
| Send | Receive | Purpose |
|---|---|---|
hexmap:exportSvg | hexmap:svgData | Get full SVG markup |
hexmap:getMap | hexmap:mapData | Get hex data as JSON |
hexmap:regenerate | — | Generate new random map |
hexmap:setStyle | — | Change visual style |
hexmap:setGame | — | Switch active game |
Import the engine modules and call HexSvg.toSVG() directly. This avoids the iframe overhead and gives full control over options.
<script type="module">
import { getGameConfig } from './js/game-registry.js';
import { HexSvg } from './js/hex-svg.js';
import './js/games/talisman.js';
var config = getGameConfig('talisman');
var hexes = config.generate(4, 0, '42');
var svg = HexSvg.toSVG(hexes, {
hexSize: 40,
flat: false,
colors: config.getColors(),
images: config.getImages('artistic'),
imageMode: 'link',
labels: true,
padding: 15
});
document.getElementById('output').innerHTML = svg;
</script>
The module system handles all dependencies automatically. You only need to import what you use directly.
Use HexSvg.toAnnotatedSVG() to add move highlights, player tokens, directional arrows, and legends on top of a base map. Useful for rulebooks and strategy guides.
var annotations = {
highlights: [
{ q: 0, r: 1, style: 'valid' },
{ q: 1, r: -1, style: 'blocked' },
{ q: -1, r: 0, style: 'selected' }
],
tokens: [
{ q: 0, r: 0, color: '#1c4a4a', label: 'P1', stroke: '#fff' }
],
arrows: [
{ from: { q: 0, r: 0 }, to: { q: 1, r: 0 }, color: '#2aaa10', style: 'solid' }
],
legend: [
{ style: 'valid', text: 'Legal move' },
{ style: 'blocked', text: 'Blocked' }
]
};
var svg = HexSvg.toAnnotatedSVG(hexes, annotations, {
hexSize: 40,
flat: false,
colors: config.getColors()
});
Available highlight styles:
| Style | Appearance |
|---|---|
valid | Green hex border |
blocked | Red X through hex |
selected | Gold hex border |
friendly | Gold hex border (alias) |
The imageMode option controls how tile artwork is referenced in the SVG output:
| Mode | Output | Use when |
|---|---|---|
'none' | Flat colour polygons only | Smallest file size, works everywhere, no external dependencies |
'link' | <image href="img/tiles/..."> | SVG will be served from same origin as tile images |
'embed' | Inline data URIs | Self-contained SVG, works offline, larger file size |
For most web use, 'link' keeps file sizes small. For PDF generation or offline contexts, use 'embed' so the SVG is fully self-contained.
SVG viewBox is auto-calculated from hex positions. Some PDF renderers (wkhtmltopdf, older Puppeteer) ignore viewBox and require explicit width/height attributes. These are included by default.
Tips for PDF output:
imageMode: 'embed' so tiles render without network accesshexSize for print DPI (e.g. 60 for 300dpi output vs 40 for screen)bgColor if you need an opaque background (default is transparent)width and height attributes in addition to viewBox for maximum renderer compatibilityvar svg = HexSvg.toSVG(hexes, {
hexSize: 60,
colors: config.getColors(),
images: config.getImages('artistic'),
imageMode: 'embed',
padding: 20,
bgColor: '#ffffff'
});
The Talisman Worlds rulebook project uses this workflow to produce reproducible map illustrations:
This gives map illustrations that automatically update when the generator improves. No manual re-export needed. The seed guarantees the same board layout every time.
// In the rulebook page
var maps = document.querySelectorAll('[data-hexmap]');
maps.forEach(function(container) {
var iframe = document.createElement('iframe');
iframe.src = container.dataset.hexmap + '&boardonly=1';
iframe.style.display = 'none';
document.body.appendChild(iframe);
iframe.onload = function() {
iframe.contentWindow.postMessage({ type: 'hexmap:exportSvg' }, '*');
};
window.addEventListener('message', function handler(event) {
if (event.data.type === 'hexmap:svgData' && event.source === iframe.contentWindow) {
container.innerHTML = event.data.svg;
iframe.remove();
window.removeEventListener('message', handler);
}
});
});
Usage in HTML:
<div data-hexmap="https://hex.moddable.games/generate/?game=talisman&size=4&seed=rulebook-map-1&style=artistic"></div>
| Option | Default | Description |
|---|---|---|
hexSize | 30 | Radius of each hex in SVG units |
flat | false | Flat-top (true) or pointy-top (false) orientation |
colors | {} | Map of terrain type → fill colour |
images | null | Map of terrain type → image path/URI |
imageMode | 'none' | 'none', 'link', or 'embed' |
strokeColor | 'rgba(0,0,0,0.3)' | Hex border colour |
strokeWidth | 1 | Hex border width |
labels | false | Show hex labels |
padding | 15 | Padding around the map in SVG units |
bgColor | null | Background colour (null = transparent) |
scaleFactor | 0.95 | Hex polygon scale (gap between hexes) |