Canvas
The canvas element draws shapes, text, and images at precise coordinates. It supports two positioning modes — pick the one that matches author intent.
Live example
A real-world architecture diagram authored entirely as a flow-block canvas: hexagon for the edge service, rounded rectangles for compute, ellipse-on-rectangle cylinders for databases, color-coded connectors. Open the Template tab to see the exact JSON.
- Output
- Template
- Data
Built-in shapes
Every shape renders identically in PDF and DOCX — same JSON, same output.
- Output
- Template
- Data
| Tier | Shapes |
|---|---|
| Tier 1 — primitives | rectangle, roundRectangle, circle, ellipse, line, arc |
| Tier 2 — polygons | triangle, diamond, pentagon, hexagon, octagon, plus, parallelogram, trapezoid |
| Tier 3 — directional arrows | rightArrow, leftArrow, upArrow, downArrow, chevron |
| Custom | freeform — N-point closed polygon, auto-closed |
| Paths | path — arbitrary SVG path data (PDF only — DOCX parity pending), textPath — text flowed along an SVG path |
| Content | text, image |
Each polygon and arrow fits inside the bounding box you supply via width × height; the renderer derives the vertex positions automatically. The path / textPath commands accept raw SVG d strings, which makes them the most flexible primitive — anything you can draw in SVG (Beziers, arcs, compound paths, decorative flourishes) renders directly. See the Canvas Patterns Gallery tutorial for a full reference of decorative compositions (mandala, sunburst, Greek key, Lissajous, guilloché).
Two modes
Flow-block canvas — auto-sized or explicit size
Recommended for diagrams, charts, and any visual that should sit inside the document flow alongside paragraphs and tables. The canvas reserves a W × H bounding box; surrounding content lays out around it on the page it lands on. Coordinates are box-relative top-left origin (x grows right, y grows down inside the box).
Auto-sized (default). Omit size and the renderer computes the bounding box from your commands — no need to track the right and bottom edges yourself.
{
"canvas": {
"commands": [ ... ]
}
}
Add padding (in points) to leave breathing room around the auto-computed bbox:
{
"canvas": {
"padding": 10,
"commands": [ ... ]
}
}
Commands with negative coordinates are shifted into the box automatically; authoring { "x": -20, "y": 0 } works without manual translation.
Explicit size. Set size: [W, H] when you need a specific reservation (e.g. a fixed-size diagram aligned to a column width). Commands rendered past the box are clipped at the right/bottom edges.
{
"canvas": {
"size": [480, 220],
"commands": [ ... ]
}
}
Page-level canvas — pageNumber
For decorative chrome that should overlay specific pages without affecting flow (corner brackets, watermark-like accents, page-number bars). Coordinates are page absolute, bottom-left origin — same as PDF native coordinates.
{
"canvas": {
"pageNumber": 1,
"commands": [ ... ]
}
}
| Property | Type | Default | Description |
|---|---|---|---|
size | [W, H] | auto from commands | Explicit reservation in points. Omit to derive the tight bbox from commands. |
padding | number | 0 | Padding in points added around the auto-computed bbox. Ignored when size is set. |
pageNumber | number | — | Set this for page-level mode. Mutually exclusive with size/padding. |
commands | array | — | Drawing commands (see below). |
style | string | — | Default style applied to commands that don't carry their own. |
Pick one mode: setting
pageNumbertriggers page-level mode (page-absolute coordinates on the named page). Otherwise the canvas is a flow block, auto-sized from commands unlesssizeis set explicitly.
Drawing commands
Every command has type, points, and type-specific properties. style references a named entry in document.styles.
Geometry primitives
Rectangle
{ "type": "rectangle", "points": [{ "x": 100, "y": 100 }], "width": 150, "height": 80, "style": "boxStyle" }
Round rectangle
{ "type": "roundRectangle", "points": [{ "x": 100, "y": 100 }], "width": 150, "height": 80, "radius": 6, "style": "cardStyle" }
Circle
{ "type": "circle", "points": [{ "x": 200, "y": 100 }], "radius": 30, "style": "circleStyle" }
Ellipse
{ "type": "ellipse", "points": [{ "x": 200, "y": 100 }], "width": 100, "height": 50, "style": "ellipseStyle" }
Tier 2 polygons
triangle, diamond, pentagon, hexagon, octagon, plus, parallelogram, trapezoid. All take a single anchor point + width and height; the polygon vertices fit inside that bounding box.
{ "type": "triangle", "points": [{ "x": 0, "y": 0 }], "width": 80, "height": 80, "style": "shape" }
{ "type": "diamond", "points": [{ "x": 110, "y": 0 }], "width": 80, "height": 80, "style": "shape" }
{ "type": "pentagon", "points": [{ "x": 220, "y": 0 }], "width": 80, "height": 80, "style": "shape" }
{ "type": "hexagon", "points": [{ "x": 330, "y": 0 }], "width": 80, "height": 80, "style": "shape" }
{ "type": "octagon", "points": [{ "x": 0, "y": 100 }], "width": 80, "height": 80, "style": "shape" }
{ "type": "plus", "points": [{ "x": 110, "y": 100 }], "width": 80, "height": 80, "style": "shape" }
{ "type": "parallelogram", "points": [{ "x": 220, "y": 100 }], "width": 80, "height": 80, "style": "shape" }
{ "type": "trapezoid", "points": [{ "x": 330, "y": 100 }], "width": 80, "height": 80, "style": "shape" }
Tier 3 arrows
rightArrow, leftArrow, upArrow, downArrow, chevron. The horizontal/vertical orientation is encoded in the type name; the renderer adjusts vertex math accordingly.
{ "type": "rightArrow", "points": [{ "x": 0, "y": 0 }], "width": 90, "height": 60 }
{ "type": "leftArrow", "points": [{ "x": 110, "y": 0 }], "width": 90, "height": 60 }
{ "type": "upArrow", "points": [{ "x": 220, "y": 0 }], "width": 60, "height": 90 }
{ "type": "downArrow", "points": [{ "x": 290, "y": 0 }], "width": 60, "height": 90 }
{ "type": "chevron", "points": [{ "x": 360, "y": 0 }], "width": 80, "height": 60 }
Freeform polygon
Closed polygon defined by N points. Useful for stars, badges, custom flowchart shapes.
{
"type": "freeform",
"style": "starStyle",
"points": [
{ "x": 100, "y": 10 },
{ "x": 140, "y": 40 },
{ "x": 125, "y": 90 },
{ "x": 75, "y": 90 },
{ "x": 60, "y": 40 }
]
}
Lines and arcs
Line
Two or more points.
{
"type": "line",
"points": [{ "x": 50, "y": 50 }, { "x": 200, "y": 150 }],
"style": "connector"
}
Arc
Sweep from startAngle to endAngle around a center point.
{ "type": "arc", "points": [{ "x": 200, "y": 200 }], "radius": 60, "startAngle": 0, "endAngle": 180, "style": "arcStyle" }
Paths & text on path
PDF only. DOCX parity for
path/textPathis pending — fixtures using these commands render the path in PDF but skip it in DOCX.
Path
Arbitrary SVG path data via the d attribute. Supports the standard SVG commands: M/m (moveto), L/l (lineto), H/h / V/v (horizontal/vertical lineto), C/c / S/s (cubic Bezier + smooth), Q/q / T/t (quadratic Bezier + smooth), A/a (elliptical arc), Z/z (close path). Strokes and/or fills based on which color properties the style supplies (strokeColor → stroke, fillColor → fill, both → fill+stroke).
{ "type": "path", "d": "M 0 50 Q 100 0 200 50 T 400 50", "style": "waveStroke" }
Full circle as two semicircular arcs (cleaner than the one-arc idiom which is geometrically ambiguous):
{ "type": "path", "d": "M 100 6 A 94 94 0 0 1 100 194 A 94 94 0 0 1 100 6", "style": "outerRing" }
textPath
Flows text along a path with per-glyph rotation. The path itself is not drawn — pair with a path command using the same d if you want a visible curve too.
| Property | Type | Description |
|---|---|---|
d | string | SVG path data (same syntax as path) |
text | string | Text to flow; supports inline tags ([b], [i], [color], [fontsize], [caps], [em], [strong], [mark], …) |
alignment | string | start (default) / middle / end — anchors the text along the path |
startOffset | number | Distance in points from path start before the first glyph |
side | string | above (default) — glyph baseline on path; below — glyph hangs below the path |
style | string | Canvas text style — flows font, fontSize, fontColor, letterSpacing |
{
"type": "textPath",
"d": "M 24 100 A 76 76 0 0 1 176 100",
"text": "OFFICIAL · [color, #7A1F2E]STATE CORPORATION COMMISSION[/color]",
"alignment": "middle",
"style": "sealTopText"
}
Content
Text
{ "type": "text", "text": "Section header", "points": [{ "x": 150, "y": 200 }], "style": "labelStyle" }
Image
{
"type": "image",
"image": { "src": "images/logos/acme.png", "width": 100, "height": 40 },
"points": [{ "x": 50, "y": 30 }]
}
Barcode
Place any supported barcode symbology at absolute canvas coordinates — including PDF417, DataMatrix, QR, Code128, Code39, MaxiCode, and the 2D specialty codes. The barcode encoder runs at render time, so the encoded value can be a $data.* reference.
{
"type": "barcode",
"barcode": { "type": "datamatrix", "code": "$data.credential.payload", "width": 40, "height": 40 },
"points": [{ "x": 80, "y": 56 }]
}
| Property | Type | Description |
|---|---|---|
barcode.type | string | Symbology — datamatrix, qrcode, pdf417, code128, code39, aztec, maxicode, microqr, rmqr, micropdf417, dotcode, hanxin, code16k, codablockf, ultracode, gridmatrix, upnqr, and all 1D linear types. See Symbologies. |
barcode.code | string | The payload to encode. Supports $data.* and $item.* references. |
barcode.width, barcode.height | number | Render dimensions in points. For square 2D codes, set both equal. Omit to use per-symbology defaults. |
points | array | Single { x, y } for the barcode's top-left corner in canvas coordinates. |
This is the canvas barcode primitive — distinct from the [barcode, …] inline tag which renders inline with text flow. Use canvas-mode when you need the barcode at a precise location alongside other canvas shapes (the center of a seal, a corner of a form, an edge sidebar).
Live examples — official-seal.json (PDF417 verification record next to control numbers), graduation-certificate.json and achievement-certificate.json (DataMatrix at the visual center of an academic seal), stock-certificate.json (DataMatrix verification badge), void-check.json (edge-mounted Code128 watermark).
Canvas styles
Canvas shapes use a different property schema than paragraph styles. Use the keys below — color/backgroundColor/border are paragraph properties and will be silently ignored.
Naming aligns with SVG presentation attributes. Authors fluent in SVG will recognize
strokeDasharray,strokeDashoffset,strokeLinecap,strokeLinejoin— same semantics, JSON-style camelCase.
| Property | Applies to | Description |
|---|---|---|
fillColor | shapes | Interior fill. |
strokeColor | shapes, lines, paths | Border / line / stroke color. |
lineWidth | shapes, lines, paths | Stroke width in points. |
strokeDasharray | shapes, lines, paths | Dash pattern as number array: [on, off] for simple dash, [a, b, c, d, …] for dash-dot, [0.5, 2.5] paired with strokeLinecap: "round" for dotted. Use [0] or [] to explicitly reset to solid — the PDF canvas state is sticky, so a dash pattern set earlier in the command stream persists until overridden. |
strokeDashoffset | paths | Starting offset into the dash pattern (defaults to 0). |
strokeLinecap | shapes, lines, paths | butt (default) / round / square — line-end shape. Applies to any stroked shape including arcs and circles. Combined with strokeDasharray, round turns tiny on-segments into round dots instead of square pixels. |
strokeLinejoin | paths | miter (default) / round / bevel — corner join style at polyline vertices. |
miterLimit | paths | Positive float — controls how long a miter spike can extend before being chopped to a bevel. |
opacity | all | 0.0–1.0 transparency. |
fontColor | text, textPath | Text fill color. |
fontSize | text, textPath | Text size in points. |
bold / italic | text, textPath | Boolean. |
font | text, textPath | Font family for embedded custom fonts. |
letterSpacing | text, textPath | Inter-character tracking in points (positive widens, negative tightens). |
textRenderingMode | text, textPath | fill (default) / stroke / fillstroke / invisible / fillclip / strokeclip / fillstrokeclip / clip — PDF Tj operator Tr parameter. PDF only. |
skew | paths | [skewX] or [skewX, skewY] in degrees — applies a 2D skew transform. PDF only. |
transform | paths | 6-element affine matrix [a, b, c, d, e, f] — raw ConcatMatrix. PDF only. |
{
"styles": {
"card": { "fillColor": "#1E40AF", "strokeColor": "#1E3A8A", "lineWidth": 0.5 },
"cardLabel": { "fontSize": 9, "bold": true, "fontColor": "#FFFFFF", "textAlign": "center" },
"connector": { "strokeColor": "#16A34A", "lineWidth": 1.5 }
}
}
When to use which mode
| Use case | Mode |
|---|---|
| Architecture / flow / org diagrams inside a doc | size: [W, H] flow-block |
| Charts (bars, lines, sparklines) embedded in a report | size: [W, H] flow-block |
| Decorative corner brackets on a certificate | pageNumber: 1 page-level |
| Logo + agency band at the top of a tax slip | pageNumber: 1 page-level |
| Seal or sigil at a fixed page location | pageNumber: 1 page-level |
Patterns gallery — paths, curves, and textPath
A second live example exercising the more decorative end of the canvas API: SVG path data, quadratic and cubic Bezier curves, arcs, textPath (text flowed along a curve), freeform polygons, and overlapping shape compositions. Useful as a reference when authoring seals, ornamental borders, math/geometry illustrations, or anything where the layout language is "place these curves exactly here."
- Output
- Template
- Data
What's next
- Watermarks — for translucent text/image overlays that repeat across all pages.
- Tables — for tabular layouts that flow with paragraphs.
- Columns — multi-column flow layouts.