# `LivePanels.Canvas.Placement`
[🔗](https://github.com/livepanels/livepanels/blob/v0.1.0/lib/livepanels/canvas/placement.ex#L1)

Public placement frame companion for the canvas API.

A placement frame is the canonical `{space, x, y, w, h, anchor}` shape used
by the canvas model. `:world` frames are transformed by the camera;
`:viewport` frames are fixed to the browser viewport layer and interpret
`x/y` as offsets from their placement anchor.

Application-facing APIs such as `LivePanels.Canvas.Item.place/3` and
`LivePanels.Canvas.Item.copy_to/3` accept `t:app_frame/0`: `:x`,
`:y`, `:w`, and `:h` are required, while `:space` and `:anchor` default to
`:world` and `:top_left` when omitted. Browser and persistence codecs use
the full `t:frame/0` at their boundaries.

# `anchor`

```elixir
@type anchor() ::
  :top_left
  | :top
  | :top_right
  | :right
  | :bottom_right
  | :bottom
  | :bottom_left
  | :left
  | :center
```

# `app_frame`

```elixir
@type app_frame() :: %{
  optional(:space) =&gt; space(),
  optional(:anchor) =&gt; anchor(),
  x: integer(),
  y: integer(),
  w: pos_integer(),
  h: pos_integer()
}
```

# `frame`

```elixir
@type frame() :: %{
  space: space(),
  x: integer(),
  y: integer(),
  w: pos_integer(),
  h: pos_integer(),
  anchor: anchor()
}
```

# `space`

```elixir
@type space() :: :world | :viewport
```

# `anchors`

```elixir
@spec anchors() :: [anchor()]
```

Returns the supported viewport anchoring positions.

# `default_anchor`

```elixir
@spec default_anchor() :: anchor()
```

Returns the placement anchor used when callers omit one.

# `default_space`

```elixir
@spec default_space() :: space()
```

Returns the placement space used when callers omit one.

# `from_item`

```elixir
@spec from_item(map()) :: frame()
```

Projects an item into a placement frame.

# `normalize_anchor`

```elixir
@spec normalize_anchor(term()) :: anchor() | nil
```

Normalizes a placement anchor from atom or string input.

# `normalize_anchor`

```elixir
@spec normalize_anchor(term(), anchor()) :: anchor()
```

Normalizes a placement anchor or returns the supplied fallback.

# `normalize_app_frame`

```elixir
@spec normalize_app_frame(map()) :: {:ok, frame()} | {:error, atom()}
```

Normalizes an app-facing placement frame.

Applications may omit `:space` and `:anchor`; they default to `:world` and
`:top_left`. Explicit malformed values still fail clearly.

# `normalize_space`

```elixir
@spec normalize_space(term()) :: space() | nil
```

Normalizes a placement space from atom or string input.

# `normalize_space`

```elixir
@spec normalize_space(term(), space()) :: space()
```

Normalizes a placement space or returns the supplied fallback.

# `serialize_anchor`

```elixir
@spec serialize_anchor(term()) :: String.t()
```

Serializes a placement anchor for browser and persistence payloads.

# `serialize_space`

```elixir
@spec serialize_space(term()) :: String.t()
```

Serializes a placement space for browser and persistence payloads.

# `spaces`

```elixir
@spec spaces() :: [space()]
```

Returns the placement spaces supported by canvas items.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
