Figures with CeTZ

Detailed CeTZ drawings, rendered to inline SVG and themed for day and night.

Doc no.
TN-004
Date
2026-02-14
GMT day
2026:045
Est. read
2 min

CeTZ draws through the regular @preview/cetz package. Import it from /utils/cetz.typ instead, and canvas renders the drawing as inline SVG in HTML export:

typst
#import "/utils/cetz.typ" as cetz

#cetz.canvas(length: 1pt, {
  import cetz.draw: *
  circle((0, 0), radius: 10)
})

Everything else in CeTZ (draw, vector, palette, …) is re-exported unchanged. Text inside the figure is set by Typst with the theme’s fonts, and the SVG scales down on narrow screens.

01Arcs, ellipses and curves#

A Hohmann transfer from Earth to Mars. The orbits are circles; the transfer and Mars’s motion are arcs, one of them elliptical; the event log and the budget bar are rect and content calls laid out in a loop.

02Grids and zooms#

The bit layout of a telemetry transfer frame header. A loop of rect calls draws the 48 bits, each field coloured by a lookup; dashed lines zoom from the frame into its header, and Bézier arrows route the frame by its channel id.

03Colours for both themes#

The figures take their colours from c in utils/figure.typ. The stylesheet swaps each of those colours for a night value, so a drawing in them needs no second version. The same module holds the helpers used here:

typst
#import "/utils/figure.typ": c, txt, tag, arrow, curve-arrow, pill, cells, seg, legend

#cetz.canvas(length: 1pt, {
  import cetz.draw: *
  pill((0, 0), "ground", name: "a")
  pill((120, 0), "craft", name: "b", tone: "orange")
  arrow("a.east", "b.west")
  seg(0, 160, -24, "blue1", body: "pass · 42 min")
})

A colour outside c keeps its day value at night. Add a mapping for it to the end of assets/styles/site.css if you need one.