Skip to main content

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.

Built-in shapes

Every shape renders identically in PDF and DOCX — same JSON, same output.

TierShapes
Tier 1 — primitivesrectangle, roundRectangle, circle, ellipse, line, arc
Tier 2 — polygonstriangle, diamond, pentagon, hexagon, octagon, plus, parallelogram, trapezoid
Tier 3 — directional arrowsrightArrow, leftArrow, upArrow, downArrow, chevron
Customfreeform — N-point closed polygon, auto-closed
Pathspath — arbitrary SVG path data (PDF only — DOCX parity pending), textPath — text flowed along an SVG path
Contenttext, 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": [ ... ]
}
}
PropertyTypeDefaultDescription
size[W, H]auto from commandsExplicit reservation in points. Omit to derive the tight bbox from commands.
paddingnumber0Padding in points added around the auto-computed bbox. Ignored when size is set.
pageNumbernumberSet this for page-level mode. Mutually exclusive with size/padding.
commandsarrayDrawing commands (see below).
stylestringDefault style applied to commands that don't carry their own.

Pick one mode: setting pageNumber triggers page-level mode (page-absolute coordinates on the named page). Otherwise the canvas is a flow block, auto-sized from commands unless size is 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 / textPath is 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.

PropertyTypeDescription
dstringSVG path data (same syntax as path)
textstringText to flow; supports inline tags ([b], [i], [color], [fontsize], [caps], [em], [strong], [mark], …)
alignmentstringstart (default) / middle / end — anchors the text along the path
startOffsetnumberDistance in points from path start before the first glyph
sidestringabove (default) — glyph baseline on path; below — glyph hangs below the path
stylestringCanvas 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 }]
}
PropertyTypeDescription
barcode.typestringSymbology — 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.codestringThe payload to encode. Supports $data.* and $item.* references.
barcode.width, barcode.heightnumberRender dimensions in points. For square 2D codes, set both equal. Omit to use per-symbology defaults.
pointsarraySingle { 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 examplesofficial-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.

PropertyApplies toDescription
fillColorshapesInterior fill.
strokeColorshapes, lines, pathsBorder / line / stroke color.
lineWidthshapes, lines, pathsStroke width in points.
strokeDasharrayshapes, lines, pathsDash 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.
strokeDashoffsetpathsStarting offset into the dash pattern (defaults to 0).
strokeLinecapshapes, lines, pathsbutt (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.
strokeLinejoinpathsmiter (default) / round / bevel — corner join style at polyline vertices.
miterLimitpathsPositive float — controls how long a miter spike can extend before being chopped to a bevel.
opacityall0.01.0 transparency.
fontColortext, textPathText fill color.
fontSizetext, textPathText size in points.
bold / italictext, textPathBoolean.
fonttext, textPathFont family for embedded custom fonts.
letterSpacingtext, textPathInter-character tracking in points (positive widens, negative tightens).
textRenderingModetext, textPathfill (default) / stroke / fillstroke / invisible / fillclip / strokeclip / fillstrokeclip / clip — PDF Tj operator Tr parameter. PDF only.
skewpaths[skewX] or [skewX, skewY] in degrees — applies a 2D skew transform. PDF only.
transformpaths6-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 caseMode
Architecture / flow / org diagrams inside a docsize: [W, H] flow-block
Charts (bars, lines, sparklines) embedded in a reportsize: [W, H] flow-block
Decorative corner brackets on a certificatepageNumber: 1 page-level
Logo + agency band at the top of a tax slippageNumber: 1 page-level
Seal or sigil at a fixed page locationpageNumber: 1 page-level

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."

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.