Search documentation of Plushie

# Plushie.Canvas.Shape (Plushie v0.7.2)

Copy Markdown View Source

Pure builder functions returning typed canvas shape structs.

Every function returns a struct from `Plushie.Canvas.*` (element modules like `Plushie.Canvas.Rect`, `Plushie.Canvas.Circle`, etc.). Each element module has an `encode/1` function for wire-format conversion. These are plain functions, not macros; they can be called anywhere.

Structure macros (`group`, `layer`) live in `Plushie.UI` and are available inside canvas do-blocks. Inside those blocks, `text`, `image`, and `svg` calls resolve automatically to their canvas shape variants. For helper functions outside canvas blocks, import this module directly.

## When to import this module

Import `Plushie.Canvas.Shape` when you build shapes in standalone helper functions (defp) outside a `Plushie.UI` canvas block:

    import Plushie.Canvas.Shape

    defp draw_indicator(x, y, color) do
      [
        circle(x, y, 6, fill: color),
        circle(x, y, 3, fill: "#fff")
      ]
    end

Inside `Plushie.UI` canvas/layer/group blocks, all shape functions are already in scope via `import Plushie.UI`. No extra import needed.

## Basic shapes

    rect(10, 20, 100, 50, fill: "#ff0000")
    circle(50, 50, 25, stroke: stroke("#000", 2))
    line(0, 0, 100, 100, stroke: stroke("#333", 1, cap: "round"))
    text(10, 10, "Hello", fill: "#000", size: 16)

## Paths

    path([move_to(0, 0), line_to(100, 0), line_to(50, 80), close()],
      fill: "#0088ff",
      stroke: stroke("#000", 2)
    )

## Transforms

Transform commands are interleaved with shapes in a layer's shape list:

    [
      push_transform(),
      translate(100, 100),
      rotate(45),
      rect(0, 0, 50, 50, fill: "#f00"),
      pop_transform()
    ]

## Clipping

Clip regions restrict drawing to a rectangular area:

    [
      push_clip(10, 10, 100, 80),
      rect(0, 0, 200, 200, fill: "#ff0000"),
      pop_clip()
    ]

Clip regions nest: inner clips are intersected with outer clips.

## Per-shape opacity

All shapes (except SVG) accept an `:opacity` option (0.0-1.0) that multiplies into the fill and stroke color alpha channels:

    rect(0, 0, 100, 100, fill: "#ff0000", opacity: 0.5)
    circle(50, 50, 25, stroke: stroke("#000", 2), opacity: 0.3)

## Text alignment

The `text/4` builder accepts `:align_x` and `:align_y` options:

    text(100, 50, "Centered", fill: "#000", align_x: "center", align_y: "center")

Valid values for `:align_x`: `"left"`, `"center"`, `"right"`. Valid values for `:align_y`: `"top"`, `"center"`, `"bottom"`.

## Gradients

Use `linear_gradient/3` as a `fill` value:

    rect(0, 0, 200, 100,
      fill: linear_gradient({0, 0}, {200, 0}, [{0.0, "#ff0000"}, {1.0, "#0000ff"}])
    )

## Interactive shapes

Make shapes interactive with the `interactive` macro (requires a string id as the first argument):

    interactive "btn", on_click: true, cursor: "pointer" do
      rect(0, 0, 100, 40, fill: "#3498db")
    end

## Summary

### Functions

arc(cx, cy, r, start_angle, end_angle)

Arc path command (center, radius, start and end angles in degrees).

arc_to(x1, y1, x2, y2, radius)

Tangent arc path command.

bezier_to(cp1x, cp1y, cp2x, cp2y, x, y)

Cubic bezier curve path command.

circle(x, y, r, opts \\ [])

Builds a circle shape.

clip(x, y, w, h)

Create a clip rectangle for a group.

close()

Close path command.

ellipse(cx, cy, rx, ry, rotation, start_angle, end_angle)

Ellipse path command.

image(source, x, y, w, h, opts \\ [])

Draws a raster image on the canvas at the given position and size.

line(x1, y1, x2, y2, opts \\ [])

Builds a line shape.

line_to(x, y)

Line-to path command.

linear_gradient(arg1, arg2, stops)

Builds a linear gradient, usable as a `fill` value.

move_to(x, y)

Move-to path command.

path(commands, opts \\ [])

Builds an arbitrary path shape.

quadratic_to(cpx, cpy, x, y)

Quadratic bezier curve path command.

rect(x, y, w, h, opts \\ [])

Builds a rectangle shape.

rotate(angle)

Create a rotation transform.

rounded_rect(x, y, w, h, radius)

Rounded rectangle path command.

scale(factor)

Create a uniform scale transform.

scale(x, y)

Create a non-uniform scale transform.

stroke(color, width, opts \\ [])

Builds a stroke descriptor.

svg(source, x, y, w, h)

Draws an SVG on the canvas at the given position and size.

text(x, y, content, opts \\ [])

Builds a text shape.

translate(x, y)

Create a translation transform.

## Functions

# arc(cx, cy, r, start_angle, end_angle)

    @spec arc(
      cx :: number(),
      cy :: number(),
      r :: number(),
      start_angle :: Plushie.Canvas.Angle.t(),
      end_angle :: Plushie.Canvas.Angle.t()
    ) :: list()

Arc path command (center, radius, start and end angles in degrees).

# arc_to(x1, y1, x2, y2, radius)

    @spec arc_to(
      x1 :: number(),
      y1 :: number(),
      x2 :: number(),
      y2 :: number(),
      radius :: number()
    ) :: list()

Tangent arc path command.

# bezier_to(cp1x, cp1y, cp2x, cp2y, x, y)

    @spec bezier_to(
      cp1x :: number(),
      cp1y :: number(),
      cp2x :: number(),
      cp2y :: number(),
      x :: number(),
      y :: number()
    ) :: list()

Cubic bezier curve path command.

# circle(x, y, r, opts \\ [])

    @spec circle(x :: number(), y :: number(), r :: number(), opts :: keyword()) ::
      Plushie.Canvas.Circle.t()

Builds a circle shape.

# clip(x, y, w, h)

    @spec clip(x :: number(), y :: number(), w :: number(), h :: number()) ::
      Plushie.Canvas.Clip.t()

Create a clip rectangle for a group.

# close()

    @spec close() :: String.t()

Close path command.

# ellipse(cx, cy, rx, ry, rotation, start_angle, end_angle)

    @spec ellipse(
      cx :: number(),
      cy :: number(),
      rx :: number(),
      ry :: number(),
      rotation :: Plushie.Canvas.Angle.t(),
      start_angle :: Plushie.Canvas.Angle.t(),
      end_angle :: Plushie.Canvas.Angle.t()
    ) :: list()

Ellipse path command.

# image(source, x, y, w, h, opts \\ [])

    @spec image(
      source :: String.t(),
      x :: number(),
      y :: number(),
      w :: number(),
      h :: number(),
      opts :: keyword()
    ) :: Plushie.Canvas.Image.t()

Draws a raster image on the canvas at the given position and size.

## Options

- `:rotation` - rotation angle in degrees (or `{value, :rad}` for radians).
- `:opacity` - opacity multiplier (0.0-1.0).

# line(x1, y1, x2, y2, opts \\ [])

    @spec line(
      x1 :: number(),
      y1 :: number(),
      x2 :: number(),
      y2 :: number(),
      opts :: keyword()
    ) :: Plushie.Canvas.Line.t()

Builds a line shape.

# line_to(x, y)

    @spec line_to(x :: number(), y :: number()) :: list()

Line-to path command.

# linear_gradient(arg1, arg2, stops)

    @spec linear_gradient(
      from :: {number(), number()},
      to :: {number(), number()},
      stops :: [{number(), String.t()}]
    ) :: Plushie.Canvas.Gradient.t()

Builds a linear gradient, usable as a `fill` value.

Stops are `{offset, color}` tuples where offset is 0.0..1.0.

# move_to(x, y)

    @spec move_to(x :: number(), y :: number()) :: list()

Move-to path command.

# path(commands, opts \\ [])

    @spec path(commands :: [map() | list() | String.t()], opts :: keyword()) ::
      Plushie.Canvas.Path.t()

Builds an arbitrary path shape.

Commands are produced by `move_to/2`, `line_to/2`, `bezier_to/6`, `quadratic_to/4`, `arc/5`, `arc_to/5`, `ellipse/7`, `rounded_rect/5`, and `close/0`.

# quadratic_to(cpx, cpy, x, y)

    @spec quadratic_to(cpx :: number(), cpy :: number(), x :: number(), y :: number()) ::
      list()

Quadratic bezier curve path command.

# rect(x, y, w, h, opts \\ [])

    @spec rect(
      x :: number(),
      y :: number(),
      w :: number(),
      h :: number(),
      opts :: keyword()
    ) ::
      Plushie.Canvas.Rect.t()

Builds a rectangle shape.

# rotate(angle)

    @spec rotate(angle :: Plushie.Canvas.Angle.t()) :: Plushie.Canvas.Transform.Rotate.t()

Create a rotation transform.

Accepts degrees by default, or explicit unit tuples:

    rotate(45)              # 45 degrees
    rotate({45, :deg})      # explicit degrees
    rotate({0.785, :rad})   # explicit radians

# rounded_rect(x, y, w, h, radius)

    @spec rounded_rect(
      x :: number(),
      y :: number(),
      w :: number(),
      h :: number(),
      radius :: number()
    ) :: list()

Rounded rectangle path command.

# scale(factor)

    @spec scale(factor :: number()) :: Plushie.Canvas.Transform.Scale.t()

Create a uniform scale transform.

# scale(x, y)

    @spec scale(x :: number(), y :: number()) :: Plushie.Canvas.Transform.Scale.t()

Create a non-uniform scale transform.

# stroke(color, width, opts \\ [])

    @spec stroke(color :: String.t(), width :: number(), opts :: keyword()) ::
      Plushie.Canvas.Stroke.t()

Builds a stroke descriptor.

## Options

- `:cap` - line cap: `"butt"`, `"round"`, or `"square"`. Default: `"butt"`.
- `:join` - line join: `"miter"`, `"round"`, or `"bevel"`. Default: `"miter"`.
- `:dash` - dash pattern as `{segments, offset}` where segments is a list of numbers and offset is the starting offset.

# svg(source, x, y, w, h)

    @spec svg(
      source :: String.t(),
      x :: number(),
      y :: number(),
      w :: number(),
      h :: number()
    ) :: Plushie.Canvas.Svg.t()

Draws an SVG on the canvas at the given position and size.

# text(x, y, content, opts \\ [])

    @spec text(x :: number(), y :: number(), content :: String.t(), opts :: keyword()) ::
      Plushie.Canvas.Text.t()

Builds a text shape.

# translate(x, y)

    @spec translate(x :: number(), y :: number()) ::
      Plushie.Canvas.Transform.Translate.t()

Create a translation transform.