Canvas for drawing shapes, organized into named layers.
Layers are a map of layer names to shape lists. Each layer maps to an iced
Cache on the Rust side -- only changed layers are re-tessellated. This
prevents performance footguns when rendering thousands of shapes in a stable
layer.
Shape descriptors are plain maps with string keys. Use Plushie.Canvas.Shape
for convenience builders, or construct maps directly.
Do-block form
The canvas macro in Plushie.UI supports a do-block form that collects
layers declaratively:
import Plushie.UI
canvas "chart", width: 400, height: 300 do
layer "grid" do
rect(0, 0, 400, 300, stroke: "#eee")
end
layer "data" do
for bar <- bars do
rect(bar.x, bar.y, bar.w, bar.h, fill: bar.color)
end
end
endProps
layers(map of string => list of maps) -- named layers of shape descriptors. Each layer is independently cached. Shapes within a layer are drawn in order. Layers are drawn in alphabetical order by name.shapes(list of maps) -- flat list of shape descriptors. Convenience alternative tolayersfor canvases that don't need named layers.width(length) -- canvas width. Default: fill. SeePlushie.Type.Length.height(length) -- canvas height. Default: 200px.background(color) -- canvas background color. SeePlushie.Type.Color.interactive(boolean) -- enables all mouse event handlers. Default: false.on_press(boolean) -- enable mouse press events. Default: false.on_release(boolean) -- enable mouse release events. Default: false.on_move(boolean) -- enable mouse move events. Default: false.on_scroll(boolean) -- enable mouse scroll events. Default: false.alt(string) -- accessible label for the canvas. Sits outside thea11yobject. See "Widget-specific accessibility props" indocs/reference/accessibility.md.description(string) -- extended accessible description for the canvas. Sits outside thea11yobject.a11y(map) -- accessibility overrides. SeePlushie.Type.A11y.
Shape types
Shapes are plain maps. See Plushie.Canvas.Shape for builder functions.
%{type: "rect", x: x, y: y, w: w, h: h}-- rectangle.%{type: "circle", x: x, y: y, r: r}-- circle.%{type: "line", x1: x1, y1: y1, x2: x2, y2: y2}-- line.%{type: "text", x: x, y: y, content: text}-- text.%{type: "path", commands: [...]}-- arbitrary path.%{type: "image", source: path, x: x, y: y, w: w, h: h}-- image.%{type: "svg", source: path, x: x, y: y, w: w, h: h}-- SVG.
All shapes accept optional fill (hex color or gradient) and stroke fields.
Events
Canvas background events (coordinate-level, unified pointer types):
%WidgetEvent{type: :press, id: id, data: %{x: x, y: y, button: button, pointer: pointer, modifiers: mods}}%WidgetEvent{type: :release, id: id, data: %{x: x, y: y, button: button, pointer: pointer, modifiers: mods}}%WidgetEvent{type: :move, id: id, data: %{x: x, y: y, pointer: pointer, modifiers: mods}}%WidgetEvent{type: :scroll, id: id, data: %{x: x, y: y, delta_x: dx, delta_y: dy, pointer: pointer, modifiers: mods}}%WidgetEvent{type: :enter, id: id}%WidgetEvent{type: :exit, id: id}
Interactive shape events (semantic, from shapes with interactive field):
%WidgetEvent{type: :click, id: element_id, scope: [canvas_id | ...]}%WidgetEvent{type: :enter, id: id}%WidgetEvent{type: :exit, id: id}%WidgetEvent{type: :drag, id: id, data: %{x: x, y: y, delta_x: dx, delta_y: dy}}%WidgetEvent{type: :drag_end, id: id, data: %{x: x, y: y}}%WidgetEvent{type: :focused, id: id}%WidgetEvent{type: :blurred, id: id}%WidgetEvent{type: :key_press, id: id, data: %{key: key, modifiers: mods, text: text}}%WidgetEvent{type: :key_release, id: id, data: %{key: key, modifiers: mods}}
Canvas element clicks arrive as regular :click events with the element ID
as the event id and the canvas ID in the scope. Other element events use
standard generic event families.
Summary
Functions
Sets accessibility annotations.
Sets the accessible label for the canvas.
Sets the arrow key navigation mode ("wrap", "clamp", "linear", "none").
Sets the canvas background color. Accepts a hex string or named color atom.
Converts this canvas struct to a ui_node() map via the Plushie.Widget protocol.
Sets an extended accessible description for the canvas.
Sets the maximum event rate (events per second) for this widget's coalescable events.
Sets the canvas height.
Sets whether all mouse event handlers are enabled.
Adds a single named layer to the canvas. Merges with existing layers.
Sets the layers map (layer name => list of shape descriptors).
Creates a new canvas struct with optional keyword opts.
Sets whether mouse move events are enabled.
Sets whether mouse press events are enabled.
Sets whether mouse release events are enabled.
Sets whether mouse scroll events are enabled.
Sets the accessible role for the canvas (e.g. "radiogroup", "toolbar").
Sets a flat list of shapes (convenience shorthand for unlayered canvases).
Sets the canvas width.
Applies keyword options to an existing canvas struct.
Types
@type canvas_shape() :: Plushie.Canvas.Shape.Rect.t() | Plushie.Canvas.Shape.Circle.t() | Plushie.Canvas.Shape.Line.t() | Plushie.Canvas.Shape.CanvasText.t() | Plushie.Canvas.Shape.Path.t() | Plushie.Canvas.Shape.CanvasImage.t() | Plushie.Canvas.Shape.CanvasSvg.t() | Plushie.Canvas.Shape.Group.t() | Plushie.Canvas.Shape.Translate.t() | Plushie.Canvas.Shape.Rotate.t() | Plushie.Canvas.Shape.Scale.t() | Plushie.Canvas.Shape.Clip.t() | map()
A canvas shape descriptor (struct or plain map).
@type option() :: {:layers, %{required(String.t()) => [canvas_shape()]}} | {:shapes, [canvas_shape()]} | {:width, Plushie.Type.Length.t()} | {:height, Plushie.Type.Length.t()} | {:background, Plushie.Type.Color.input()} | {:interactive, boolean()} | {:on_press, boolean()} | {:on_release, boolean()} | {:on_move, boolean()} | {:on_scroll, boolean()} | {:alt, String.t()} | {:description, String.t()} | {:event_rate, pos_integer()} | {:a11y, Plushie.Type.A11y.t() | map() | keyword()}
@type t() :: %Plushie.Widget.Canvas{ a11y: Plushie.Type.A11y.t() | nil, alt: String.t() | nil, arrow_mode: String.t() | nil, background: Plushie.Type.Color.t() | nil, description: String.t() | nil, event_rate: pos_integer() | nil, height: Plushie.Type.Length.t() | nil, id: String.t(), interactive: boolean() | nil, layers: %{required(String.t()) => [canvas_shape()]} | nil, on_move: boolean() | nil, on_press: boolean() | nil, on_release: boolean() | nil, on_scroll: boolean() | nil, role: String.t() | nil, shapes: [canvas_shape()] | nil, width: Plushie.Type.Length.t() | nil }
Functions
@spec a11y(canvas :: t(), a11y :: Plushie.Type.A11y.t() | map() | keyword()) :: t()
Sets accessibility annotations.
Sets the accessible label for the canvas.
Sets the arrow key navigation mode ("wrap", "clamp", "linear", "none").
@spec background(canvas :: t(), background :: Plushie.Type.Color.input()) :: t()
Sets the canvas background color. Accepts a hex string or named color atom.
@spec build(canvas :: t()) :: Plushie.Widget.ui_node()
Converts this canvas struct to a ui_node() map via the Plushie.Widget protocol.
Sets an extended accessible description for the canvas.
@spec event_rate(canvas :: t(), rate :: pos_integer()) :: t()
Sets the maximum event rate (events per second) for this widget's coalescable events.
@spec height(canvas :: t(), height :: Plushie.Type.Length.t()) :: t()
Sets the canvas height.
Sets whether all mouse event handlers are enabled.
@spec layer(canvas :: t(), name :: String.t(), shapes :: [canvas_shape()]) :: t()
Adds a single named layer to the canvas. Merges with existing layers.
@spec layers(canvas :: t(), layers :: %{required(String.t()) => [canvas_shape()]}) :: t()
Sets the layers map (layer name => list of shape descriptors).
Creates a new canvas struct with optional keyword opts.
Sets whether mouse move events are enabled.
Sets whether mouse press events are enabled.
Sets whether mouse release events are enabled.
Sets whether mouse scroll events are enabled.
Sets the accessible role for the canvas (e.g. "radiogroup", "toolbar").
@spec shapes(canvas :: t(), shapes :: [canvas_shape()]) :: t()
Sets a flat list of shapes (convenience shorthand for unlayered canvases).
@spec width(canvas :: t(), width :: Plushie.Type.Length.t()) :: t()
Sets the canvas width.
Applies keyword options to an existing canvas struct.