Maps

A map is a zoomable, pinned image placed inside a diagram — built for game-guide and reference maps. Drop pins at coordinates and give each one a card of wdoc content. A diagram holding a map is automatically interactive (wheel to zoom, drag to pan, plus + / / controls) and loads the bundled map player; you don't need pan_zoom = true.

A single-image map

The common case: source is the whole map image, resolved relative to the build entry file. width / height set the map's coordinate space — a pin's x / y are pixel coordinates within it. Lift zoom_max on the diagram so the markers are readable up close. Scroll to zoom, drag to pan, then click a marker.

diagram {
  width    = 640
  height   = 320
  zoom_max = 8.0
  map "earth" {
    source = "assets/map/blue-marble.png"
    width  = 1280
    height = 640

    pin "newyork" {
      x = 377  y = 175
      icon  = "lucide.building-2"
      class = ["pin-city"]
      title = "New York"
      text { span "Financial capital on the US east coast." {} }
      callout "Tip" { class = ["tip"]  body = "Cards accept any wdoc content." }
    }
    pin "london" {
      x = 640  y = 137
      icon  = "lucide.landmark"
      class = ["pin-city"]
      title = "London"
      text { span "On the prime meridian (longitude 0)." {} }
    }
    // One-off colour, no class.
    pin "danger" {
      x = 1177  y = 440
      icon  = "lucide.triangle-alert"
      color = "#ef4444"
      size  = 30.0
      title = "Here be dragons"
      text { span "A quick one-off marker colour." {} }
    }
  }
}

Pins & cards

Each pin is an icon dropped at x / y in the map's coordinate space (its id is the inline label and must be unique on the page). Style the marker with a class (recommended — themable, supports dark / light) or the one-off color. A pin's child blocks become a floating card anchored to the marker: click to open, click the or outside to close. The card body is arbitrary wdoc content — text, lists, callouts, code, images.

PropertyTypeRequiredDescription
ididentifieryesPin id (the inline label) — links the pin to its card; page-unique.
xf64yesMarker x position, in the map's coordinate space.
yf64yesMarker y position, in the map's coordinate space.
iconutf8noIcon name (default lucide.map-pin); set.name or pair with set.
setidentifiernoIconset name for a bare icon.
sizef64noMarker size in map units (default 24).
classlist<utf8>noThemes the marker (fill / stroke / color, with dark / light).
card_classlist<utf8>noThemes the card popup (background / color / border).
colorutf8noOne-off inline marker colour (sugar for a class).
titleutf8noOptional card heading.

Child blocks

SlotAcceptsMultipleDescription
cardWdocBlockyesThe card body — any wdoc blocks.

Level-of-detail layers

Maps support different levels of detail. Omit layers entirely and the map's source is the only image. For large maps, supply several layers and the player shows the sharpest layer that suits the current zoom: a low-resolution whole image when zoomed out, a higher-resolution one once you magnify in.

A layer is a single image when cols / rows are 1 (the default), or a grid of tiles otherwise — source is then a folder and each tile's filename comes from pattern (default {x}_{y}.png, 0-based). Zoom in on the map below: at the fitted view it draws a 1024px image; magnify it and the player swaps in a 2048px layer assembled from eight 512px tiles, so detail sharpens instead of pixelating.

diagram {
  width    = 640
  height   = 320
  zoom_max = 6.0
  map "earth-detail" {
    width     = 2048
    height    = 1024
    tile_size = 512
    // Low-res whole image (zoomed-out view).
    layer { source = "assets/map/lod/low.jpg" }
    // 4x2 grid of 512px tiles (zoomed-in view).
    layer { source = "assets/map/lod"  cols = 4  rows = 2  pattern = "{x}_{y}.jpg" }

    pin "amazon" {
      x = 683  y = 540
      icon  = "lucide.trees"
      class = ["pin-city"]
      title = "Amazon basin"
      text { span "The world's largest rainforest." {} }
    }
    pin "sahara" {
      x = 1109  y = 381
      icon  = "lucide.sun"
      color = "#f59e0b"
      title = "Sahara"
      text { span "The largest hot desert." {} }
    }
  }
}

Each layer takes:

PropertyTypeRequiredDescription
sourceutf8yesImage file, or the tile folder when tiled.
colsi64noTiles across (default 1 = a single image).
rowsi64noTiles down (default 1).
patternutf8noTile filename pattern (default {x}_{y}.png, 0-based).
tile_sizei64noOverride the map's tile_size for this layer.

Fields

PropertyTypeRequiredDescription
nameidentifiernoOptional reference name (the inline label).
sourceutf8noSingle whole-map image (the common, layer-less case).
widthf64yesMap coordinate-space width — also the pin coordinate space.
heightf64yesMap coordinate-space height — also the pin coordinate space.
tile_sizei64noTile pixel size for tiled layers (default 256).
smoothboolnoimage-rendering: smooth (default) vs pixelated when false.
classlist<utf8>noThemes the map group.
ididentifiernoOptional explicit HTML id.
xf64noPlacement x within the enclosing diagram / container.
yf64noPlacement y within the enclosing diagram / container.
anchor_leftf64noDiagram anchor insets (left/right/top/bottom), like any SvgBlock.
connect_pointslist<AnchorSide>noDiagram edge-attach sides, like any SvgBlock.

Child blocks

SlotAcceptsMultipleDescription
layerslayeryesLevel-of-detail image layers (omit for a single source).
pinspinyesClickable markers with cards.

Theming

Maps ride the class system. A pin's class themes its marker (fill / stroke / color, with dark / light) and card_class themes its popup; the one-off color recolours a single marker without a class. The built-in look ships as bare-class defaults that read the --wdoc-* theme variables, so a site theme styles maps for free — no per-map CSS needed.