Hakushi.Kits.Shapes (Hakushi v0.6.0)

Copy Markdown View Source

The kit of plain shapes: rectangles, ellipses, diamonds, triangles, text and lines, for diagrams, wireframes and whiteboards with no :node slot of the app's.

<.canvas id="board" graph={@graph} kits={[Hakushi.Kits.Shapes]} on_change={&save/2} />

The canvas gets a bar of the kit's tools (Hakushi.Kit.tools/1): a shape is drawn by dragging on the paper with its tool (Shift for a square or a circle; R, O, D), text by a click (T), and a line from a point to a point (A, for an arrow). A line from a shape to a shape is an edge between them, which follows them; a line elsewhere is a node of its own.

A shape is a node of type "shape", which resizes by its corners and sides, rotates by its knob, takes text on a double click (centred, and wrapped), and has a handle on each side for edges. Its data is its kind, its text and its style:

%{
  "kind" => "rect",       # "rect", "ellipse", "diamond", "triangle" or "text"
  "text" => "Ship it",
  "fill" => "blue",       # a colour of colors/0, or "none"
  "stroke" => "ink",
  "width" => 2,           # the width of the stroke: 1, 2 or 4
  "dash" => false,
  "radius" => 8,          # a rectangle's corners: 0 or 8
  "size" => "m",          # the text's: "s", "m" or "l"
  "align" => "center",    # the text's: "left", "center" or "right"
  "rotation" => 0         # in degrees
}

A line is a node of type "shape-line", whose data is its ends, relative to its box, and its style ("stroke", "width", "dash", and "arrow": "end", "both" or "none"):

%{"from" => [8, 8], "to" => [180, 64], "stroke" => "ink", "width" => 2, "arrow" => "end"}

The style of the shapes selected changes from a panel over them (Hakushi.Kit.styles/1), in one change.

The colours

The colours are the theme's (--hakushi-shape-<name>, see the Theming guide): a fill is a tint of its colour, a stroke the colour itself. An app adds its own, by name, with their custom properties:

config :hakushi, Hakushi.Kits.Shapes, colors: ["brand"]

.hakushi { --hakushi-shape-brand: #e84a1c; }

Markdown

The shapes are a Mermaid flowchart: a rectangle a box (["..."], or ("...") with round corners), an ellipse a circle ((("..."))), a diamond a rhombus ({"..."}), a triangle a trapezoid ([/"..."\]), text a box of the class text, with the edges between them. The style and the place of each are kept in comments, so that the canvas comes back as it was. Lines of their own are not in it.

Summary

Functions

The colours of shapes: the theme's, then the app's (config :hakushi, Hakushi.Kits.Shapes, colors: [...]).

The kinds of shapes.

A line's node, from a point of the canvas to another, with its style ("stroke", "width", "dash", "arrow"). Gives {:ok, node}.

A shape's node, at a box of the canvas ([x, y, width, height]; a box smaller than a few pixels gets the kind's size), with its style (the keys of the moduledoc; the kind's own unless given) and its "text".

Functions

colors()

@spec colors() :: [String.t()]

The colours of shapes: the theme's, then the app's (config :hakushi, Hakushi.Kits.Shapes, colors: [...]).

kinds()

@spec kinds() :: [String.t()]

The kinds of shapes.

line(arg1, arg2, style \\ %{})

@spec line({number(), number()}, {number(), number()}, map()) :: {:ok, map()}

A line's node, from a point of the canvas to another, with its style ("stroke", "width", "dash", "arrow"). Gives {:ok, node}.

shape(kind, list, style)

@spec shape(String.t(), [number()], map() | nil) :: map()

A shape's node, at a box of the canvas ([x, y, width, height]; a box smaller than a few pixels gets the kind's size), with its style (the keys of the moduledoc; the kind's own unless given) and its "text".

Hakushi.Kits.Shapes.shape("diamond", [0, 0, 140, 112], %{"text" => "Paid?"})