Skip to content

CanvasBuilder reference

CanvasBuilder collects content and timeline intent, then produces the internal representation consumed by CanvasScene.

This page documents implemented methods. Persistent parent-relative movement, generic traversal, surface-relative positioning, and arbitrary-surface geodesics are not current API promises. Matemium is evaluating those questions through real projects, and no candidate design has been accepted or rejected. See the open spatial-authoring discussion.

builder = CanvasBuilder(title="My Explanation")
builder.add_heading("A clear question") # root tape is automatic
# author more content and actions
super().__init__(dsl=builder.build(), **kwargs)

Most text, layout, camera, and timeline methods are chainable. The generic data visual methods and world-object placement methods return stable IDs because later actions address them.

Method Purpose
add_text(text, ...) General text, including styled inline runs
add_heading(text, ...) Short heading with non-wrapping defaults
add_body(text, ...) Explanatory text with wrapping defaults
add_observation(text, ...) Semantic explanatory alias
add_math(latex, ...) Typeset LaTeX content
add_3d(equation, ...) Mathematical 3D surface
add_solid(shape, ...) Generic volumetric solid
add_raw(element) Low-level escape hatch
add_data_path(points, ...) Sampled trajectory, contour, route, boundary, or vector
add_data_plot(series, markers=..., ...) Axes with named sampled series and markers
add_diagram(nodes, edges, ...) Named node-edge structure with explicit positions

Tape builders expose the corresponding content methods while binding elements to their tape.

add_data_path, add_data_plot, and add_diagram return the created element ID. Text and math methods return the builder.

builder.add_text([
"The ",
builder.run("active region", color="#8d82ff", highlight=True),
" remains searchable.",
])

Run style supports properties such as color, highlight, underline, bold, italic, font size, and opacity.

Method Purpose
add_tape(name) Create an additional tape and return a TapeBuilder
add_flex_row(items, ...) Lay independently addressable items in a row
add_flex_column(items, ...) Lay independently addressable items in a column
text_spec(...) Text item specification for flex
math_spec(...) Math item specification for flex
element_spec(...) Custom element specification for flex
last_flex_ids IDs produced by the most recent flex container

All coordinates contain two or three finite numbers.

Kind Required data Common options Semantic parts
DataPath points with at least two coordinates smooth, closed, arrow, color, stroke_width path
DataPlot non-empty series; each series has unique id and at least two points markers, x_range, y_range, width, height, tips, smooth axes, series:<id>, marker:<id>
Diagram non-empty unique-ID nodes; edges reference known node IDs node shape/size/style; edge direction/label/style node:<id>, edge:<id>, edge-label:<id>

For complete examples and field details, see Data visuals and transitions.

Method Purpose
add_state_transition(patches, run_time=..., lag_ratio=..., rate_func=...) Apply synchronized allowlisted changes to elements or semantic parts
add_element_morph(element_id, target, run_time=..., match_shapes=...) Recompile a target CanvasElement and replace a registered visual

A state patch uses:

{
"target_id": "control_loop::node:sensor",
"changes": {"fill_color": "#ffdd66", "scale": 1.08},
}

Allowlisted changes are color, fill_color, fill_opacity, stroke_color, stroke_opacity, stroke_width, opacity, scale, shift, and position.

Semantic target syntax is:

element_id::part_id

The target of a morph is a CanvasElement, not another builder call.

Method Purpose
add_camera_focus(id, ...) Isolate or overlay-focus an existing element
add_camera_move(dy, ...) Legacy explicit tape movement
scroll_tape(tape_id=..., local_y=...) Select and locally scroll one foreground tape
add_camera_keyframe(target=..., ...) General 3D observation keyframe
observe_object(target, ...) Experimental world-object observation
add_camera_inspect(id, path=..., ...) Inspect a 3D object along a path

Normal root-tape content scrolls and reveals automatically. scroll_tape() uses the serialized TapeScroll target to select an explicit camera-facing tape. The tape hides the free world and every other tape until a world camera action opens it.

Method Purpose
add_object(kind, ...) Experimental registered/free world object
add_solid(shape, ...) Place a built-in volumetric solid
add_solid_lift(id, ...) Raise a solid above its tape
solid_label(...) Create a camera-facing label specification
add_3d(equation, ...) Place a mathematical surface in tape flow
Methods Return
Text, math, flex, camera, state, morph, and solid actions CanvasBuilder
Corresponding tape-forwarded chainable actions underlying builder result
add_data_path, add_data_plot, add_diagram element ID string
add_tape TapeBuilder
add_object, add_world_object, add_relative object/element ID string
run and *_spec helpers serializable dict

add_solid() is chainable and does not return its ID. Pass an explicit id= when later actions need to address the solid.

builder.add_math(r"E = mc^2", id="energy")
builder.add_camera_focus(
"energy",
mode="isolate",
zoom=2.0,
dim_opacity=0.1,
run_time=1.1,
hold_time=1.2,
reset_zoom=True,
)

CanvasScene runs strict structural validation by default before rendering. Registered data schemas, semantic-part targets, state properties, and morph targets are checked. The desktop check_project command returns these errors as structured diagnostics.

strict_validation=False exists only for checking and engine debugging; it is not a production-authoring workaround.

Unknown visual kinds currently validate as warnings for extension compatibility. A warning is not evidence that the kind can render.

  • Production: root-tape content, style/flex, rich text, sampled paths/plots, semantic diagrams, state transitions, morphs, focus, and both orientations.
  • Specialized: equation surfaces and solid inspection; always preview them in the delivery orientation.
  • Production spatial composition: additional camera-facing tapes, curtain switching, scroll_tape(), stable-ID add_object() world objects and morphs, and add_camera_inspect() paths.
  • Experimental: add_world_object(), low-level camera keyframes, observe_object(), and relative world placement.
  • Not yet generic: timed traversal of sampled paths/plots, reactive shared clocks, arbitrary physical tape transforms, and timed audio/media.

SheetDSL, raw canvas elements, and JSON loading are intended for engine tests, debugging, and specialized escape hatches. New product authoring should remain reachable through CanvasBuilder.

For exact signatures in the current source, see canvas/builder.py. The repository also maintains a source-aligned AUTHORING_API.md.