manual:scripting:canvas

Draw and animate a canvas

Use Canvas for diagrams, gauges, game-specific maps, and effects that standard widgets cannot express clearly. Prefer Text, ProgressBar, Table, and the form controls when they already provide the required structure or interaction.

An animated status canvas beside the TypeScript scene records that draw it

Draw a scene

A scene is an array of shape records. Shapes are painted in array order from back to front, except that canvas text is painted after non-text shapes.

import { createState } from "smudgy:core";
import { Canvas, createWidget } from "smudgy:widgets";
import type { CanvasShape } from "smudgy:widgets";
 
const hud = createState<{ scene: CanvasShape[] }>("manual-canvas");
hud.set({
  scene: [
    {
      kind: "rect",
      x: 4,
      y: 18,
      width: 92,
      height: 12,
      rx: 3,
      fill: {
        gradient: {
          from: [4, 0],
          to: [96, 0],
          stops: [[0, "#7a1f1f"], [1, "#d64541"]],
        },
      },
    },
    {
      kind: "circle",
      id: "warning-pulse",
      cx: 92,
      cy: 24,
      r: 4,
      stroke: { color: "#ffdd55", width: 2 },
      animate: {
        r: { from: 4, to: 10, duration: 800, ease: "in-out", repeat: "infinite" },
      },
    },
    { kind: "text", x: 4, y: 4, text: "Health", size: 11, color: "#ffffff" },
  ],
});
 
createWidget("status-canvas", (
  <Canvas
    width="fill"
    height={160}
    view_box={[0, 0, 100, 50]}
    fit="contain"
    scene={hud.bind("scene")}
  />
));

The available records include rectangles, circles, ellipses, lines, polylines, polygons, SVG-style paths, text, and transformed groups. A fill may be a CSS color or a linear gradient. A stroke may sp