Builtin Library
README.md
canvas
Immediate-mode 2D-paint widget. The body is a sequence of paint
commands (line, bezier, polyline, rect, circle, text)
drawn in widget-local coordinates with origin at the top-left and +y
going down (egui-standard, opposite of plot). Wires through pointer,
drag, double-click, key, and scroll handlers, and forwards role /
tag / aria* props for accessibility.
Exports
canvas(id: string?, opts: CanvasOpts?) -> WidgetNode— build a canvas widget node from a list of paint commands plus optional interaction handlers.
Types:
CanvasOpts = { commands?, width?, height?, onClick?, onPointerDown?, onPointerUp?, onPointerMove?, onDrag?, onDoubleClick?, onKey?, onScroll?, role?, tag?, style?, class?, classes? }
Usage
local canvas = require("@builtin::modules.zui.widget.canvas")
canvas("my-canvas", {
commands = {
{ kind = "line", a = {10,10}, b = {200,150}, color = "#7AA8FF", width = 2 },
{ kind = "circle", center = {100,100}, radius = 30, fill = "#FF8855" },
{ kind = "text", pos = {10,180}, text = "hello", color = "#fff", fontSize = 14 },
},
onClick = "canvas:click",
style = { width = 600, height = 400, background = "#161B22" },
})
Notes
- Pointer events surface widget-local cursor coords as either a
"x,y"string (legacy) or a structured Luau table (modern handlers). onClick/onPointerDown/onPointerUpcarrydata.button(0 = left, 1 = right, 2 = middle) identifying which mouse button triggered the event.onKeyfires only while the canvas has keyboard focus;onScrollfires while it is hovered.- Any
opts.aria*key passes through verbatim — no wrapper-side allowlist needed. - Command kinds and per-kind fields are defined in
crates/zero_ui_protocol/src/canvas.rs.