Plushie.Widget.Canvas (Plushie v0.6.0)

Copy Markdown View Source

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
end

Props

  • 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 to layers for canvases that don't need named layers.
  • width (length) -- canvas width. Default: fill. See Plushie.Type.Length.
  • height (length) -- canvas height. Default: 200px.
  • background (color) -- canvas background color. See Plushie.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 the a11y object. See "Widget-specific accessibility props" in docs/reference/accessibility.md.
  • description (string) -- extended accessible description for the canvas. Sits outside the a11y object.
  • a11y (map) -- accessibility overrides. See Plushie.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

Types

A canvas shape descriptor (struct or plain map).

t()

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

canvas_shape()

A canvas shape descriptor (struct or plain map).

option()

@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()}

t()

@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

a11y(canvas, a11y)

@spec a11y(canvas :: t(), a11y :: Plushie.Type.A11y.t() | map() | keyword()) :: t()

Sets accessibility annotations.

alt(canvas, alt)

@spec alt(canvas :: t(), alt :: String.t()) :: t()

Sets the accessible label for the canvas.

arrow_mode(canvas, mode)

@spec arrow_mode(canvas :: t(), mode :: String.t()) :: t()

Sets the arrow key navigation mode ("wrap", "clamp", "linear", "none").

background(canvas, background)

@spec background(canvas :: t(), background :: Plushie.Type.Color.input()) :: t()

Sets the canvas background color. Accepts a hex string or named color atom.

build(canvas)

@spec build(canvas :: t()) :: Plushie.Widget.ui_node()

Converts this canvas struct to a ui_node() map via the Plushie.Widget protocol.

description(canvas, description)

@spec description(canvas :: t(), description :: String.t()) :: t()

Sets an extended accessible description for the canvas.

event_rate(canvas, rate)

@spec event_rate(canvas :: t(), rate :: pos_integer()) :: t()

Sets the maximum event rate (events per second) for this widget's coalescable events.

height(canvas, height)

@spec height(canvas :: t(), height :: Plushie.Type.Length.t()) :: t()

Sets the canvas height.

interactive(canvas, v)

@spec interactive(canvas :: t(), interactive :: boolean()) :: t()

Sets whether all mouse event handlers are enabled.

layer(canvas, name, shapes)

@spec layer(canvas :: t(), name :: String.t(), shapes :: [canvas_shape()]) :: t()

Adds a single named layer to the canvas. Merges with existing layers.

layers(canvas, layers)

@spec layers(canvas :: t(), layers :: %{required(String.t()) => [canvas_shape()]}) ::
  t()

Sets the layers map (layer name => list of shape descriptors).

new(id, opts \\ [])

@spec new(id :: String.t(), opts :: [option()]) :: t()

Creates a new canvas struct with optional keyword opts.

on_move(canvas, v)

@spec on_move(canvas :: t(), on_move :: boolean()) :: t()

Sets whether mouse move events are enabled.

on_press(canvas, v)

@spec on_press(canvas :: t(), on_press :: boolean()) :: t()

Sets whether mouse press events are enabled.

on_release(canvas, v)

@spec on_release(canvas :: t(), on_release :: boolean()) :: t()

Sets whether mouse release events are enabled.

on_scroll(canvas, v)

@spec on_scroll(canvas :: t(), on_scroll :: boolean()) :: t()

Sets whether mouse scroll events are enabled.

role(canvas, role)

@spec role(canvas :: t(), role :: String.t()) :: t()

Sets the accessible role for the canvas (e.g. "radiogroup", "toolbar").

shapes(canvas, shapes)

@spec shapes(canvas :: t(), shapes :: [canvas_shape()]) :: t()

Sets a flat list of shapes (convenience shorthand for unlayered canvases).

width(canvas, width)

@spec width(canvas :: t(), width :: Plushie.Type.Length.t()) :: t()

Sets the canvas width.

with_options(canvas, opts)

@spec with_options(canvas :: t(), opts :: [option()]) :: t()

Applies keyword options to an existing canvas struct.