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 actionssuper().__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.
Content
Section titled “Content”| 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.
Inline runs
Section titled “Inline runs”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.
Layout
Section titled “Layout”| 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 |
Generic visual schemas
Section titled “Generic visual schemas”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.
State and morphing
Section titled “State and morphing”| 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_idThe target of a morph is a CanvasElement, not another builder call.
Camera and observation
Section titled “Camera and observation”| 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.
3D objects
Section titled “3D objects”| 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 |
Return values
Section titled “Return values”| 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.
Focus example
Section titled “Focus example”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,)Validation behavior
Section titled “Validation behavior”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.
Capability maturity
Section titled “Capability maturity”- 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-IDadd_object()world objects and morphs, andadd_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.
Internal API boundary
Section titled “Internal API boundary”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.
