# Erase, Select, Move, And Resize

Committed vector items are canvas items.

That is why vector items can be selected, moved, resized, erased, copied,
pasted, undone, redone, persisted, and shared without a second document model.

## Selection

Use ordinary selection controls:

```heex
<button {clear_selection_attrs()}>Clear</button>
<button {remove_selected_attrs()}>Remove selected</button>
```

Use drawing queries when an inspector should show only selected vector items:

```elixir
defp selected_vector_items(items, selection) do
  items
  |> Map.values()
  |> Enum.filter(&LivePanels.Canvas.Selection.selected_item?(selection, &1.id))
  |> Enum.flat_map(fn item ->
    case LivePanels.Drawing.vector_state(item) do
      {:ok, draw} -> [%{item: item, draw: draw}]
      :error -> []
    end
  end)
end
```

Selection is actor-scoped in the same way as item selection.

## Move And Resize

The standard runtime attaches drag and resize behavior to committed vector
vector items. Users can move and resize vector items in `:drag` mode just as they move and
resize ordinary items.

Server code can use normal item placement commands:

```elixir
socket =
  LivePanels.Canvas.Item.place!(socket, item, %{
    x: 240,
    y: 160,
    w: item.w,
    h: item.h
  })
```

Use application policy when a product needs to constrain placement, lock a layer, or
prevent resizing certain vector item kinds.

## Erase Mode

Set erase mode from the toolbar:

```heex
<button phx-click={set_cursor_mode_js(@livepanels.canvas_id, :erase)}>
  Erase
</button>
```

The built-in vector item renderer includes erase hit targets.

If you render custom SVG, add erase target attrs to the geometry you want erase
mode to recognize:

```heex
<path
  d={@path}
  {erase_vector_item_target_attrs(@item)}
/>
```

The browser sends a drawing-owned removal command. The server still verifies
that the target is a committed vector item.

## Remove One Vector Item

Use drawing removal attrs for vector item-specific controls:

```heex
<button {erase_attrs(@item)}>
  Remove vector item
</button>
```

Server equivalent:

```elixir
socket = LivePanels.Drawing.erase!(socket, item)
```

Use `erase_attrs/2` when the UI is specifically removing a vector item.
Use `remove_selected_attrs/0` when the user is removing a mixed selection of
vector items, items, and connectors.

## Copy, Paste, Undo, And Redo

Committed vector items use the normal canvas helpers:

```heex
<button {copy_selection_attrs()}>Copy</button>
<button {paste_selection_attrs()}>Paste</button>
<button {undo_attrs()}>Undo</button>
<button {redo_attrs()}>Redo</button>
```

Drafts are not copied or undone because drafts are not canvas state yet.

## Removing Mixed Selections

In a drawing app that also has content items or graph connectors, prefer the normal
remove-selected command for the toolbar:

```heex
<button {remove_selected_attrs()}>
  Remove selected
</button>
```

It lets the canvas remove each selected thing through the appropriate command
path. Use vector item-specific removal only in vector item-specific inspectors.

## Placement Locks

Toolbar items, palettes, rulers, and inspectors are often viewport items with
placement locks:

```elixir
[
  drawing_tools:
    {MyAppWeb.DrawingToolsLive,
     label: "Drawing tools",
     placement_space: :viewport,
     placement_anchor: :top,
     placement_lock: true,
     frame: :content,
     persistent: false,
     interaction: %{presentable: false, removable: false}}
]
```

Keep product chrome as items when it should travel with the canvas runtime.
Keep it outside the canvas when it is ordinary page chrome.
