Custom Assets
For browser-loadable SVG files, declare a local id and path in YAML:
header:
assetBaseUrl: ./assets
assets:
- id: database
path: custom/database-node
anchor: [0.5, 1]
The compiler emits ./assets/custom/database-node.svg, and the browser loads it
with an SVG <image> element.
anchor is optional. It defaults to [0.5, 1], meaning the bottom-center of
the normalized square runtime asset viewport sits on the element’s grid
footprint anchor. Set it when imported SVGs have their real ground contact point
intentionally off-center.
For shared asset catalogs, declare anchor explicitly on every asset so review
can distinguish “checked and centered” from “not checked yet”.
Runtime integration is unchanged: import the compiled bundle and pass it to
mountScene. Asset loading is fully described by the compiled bundle URLs.
import { mountScene } from '@sebastianwessel/isostate';
import scene from './scene.isostate.js';
mountScene(document.querySelector('#scene'), scene);
Plain labels do not need custom SVG assets. Use the reserved built-in
asset: text with a text.value payload instead.
Simple underlays and markers also do not need custom SVG assets. Use reserved
built-in primitive assets such as asset: rectangle with a matching
primitive.rectangle payload.
This also works with path-style libraries such as draw.io SVG sets: set
assetBaseUrl to the library root, then use paths like
mscae/Active_Directory or azure2/Virtual_Machine. Asset files must be
standalone SVG documents with an SVG namespace and a valid viewBox.
Do not pass raw SVG strings to the browser runtime. Keep asset customization in the SVG files themselves, with fixed viewBox sizing and CSS variables or classes inside the file.
Asset Blueprint
Use a 64 x 64 viewBox for one-cell assets. The renderer places every external
SVG into a square runtime image viewport, preserves aspect ratio with
xMidYMax meet, and places the declared anchor point on the projected footprint
anchor. A reusable starter file is
available at assets/blueprints/isometric-one-cell.svg.
<svg viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Database">
<g id="asset" stroke="#202020" stroke-width="1.25" stroke-linejoin="round">
<!-- Top diamond: keep the object centered around x=32. -->
<path d="M16 24 32 16 48 24 32 32Z" fill="var(--iso-top, #f4f4f4)" />
<!-- Left/front face. -->
<path d="M16 24v20l16 10V32Z" fill="var(--iso-front, #d4d4d4)" />
<!-- Right/side face. -->
<path d="M48 24v20L32 54V32Z" fill="var(--iso-side, #a8a8a8)" />
</g>
<!-- Optional authoring guide only; remove before publishing the asset. -->
<circle cx="32" cy="64" r="2" fill="#ef4444" />
</svg>
Matching YAML:
header:
assetBaseUrl: ./assets
assets:
- id: database
path: database
anchor: [0.5, 1]
Anchor Rules
anchor: [0.5, 1]means the visual ground contact is centered at the bottom of the square runtime viewport. This is the normal case for one-cell assets.anchor: [0, 1]places the left bottom corner on the grid footprint anchor.anchor: [1, 1]places the right bottom corner on the grid footprint anchor.- Values between
0and1are allowed. Use them for imported assets whose visible base is off-center inside the viewBox. - The anchor is not a CSS transform origin. It is a geometry contract between the asset catalog and the renderer, and the renderer does not infer it from SVG path geometry.
- Do not enlarge imported composite SVGs with
sizeunless the SVG was intentionally authored for that multi-cell footprint. If it contains independent objects, split it into two asset files or two elements so each object owns its own grid footprint and connector ports. If splitting is not practical, keep the source asset atsize: 1and declare the anchor that matches its real ground contact.
Authoring Checklist
- Use a standalone SVG file with an explicit
viewBox. - Prefer
viewBox="0 0 64 64"for a one-cell asset. - Draw the object so its bottom visual contact point matches the declared
anchor. - Keep empty padding out of the SVG. If padding is unavoidable in an imported
set, compensate with
anchor. - Use consistent stroke width across the asset set. The AWS 3D example uses
approximately
1.25to2viewBox units depending on source asset scale. - Keep colors inside the SVG or expose CSS variables such as
--iso-top,--iso-front, and--iso-side. - Do not use one asset for long arrows or connections. Use first-class connections; stretched SVG arrows distort dash patterns and arrowheads.
<svg viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
<path d="M8 18 32 6l24 12-24 12z" fill="var(--color-top, #e2e8f0)" />
<path d="M8 18v28l24 12V30z" fill="var(--color-front, #94a3b8)" />
<path d="M56 18v28L32 58V30z" fill="var(--color-side, #64748b)" />
</svg>