> For the complete documentation index, see [llms.txt](https://viridian-games.gitbook.io/pixel-palette/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://viridian-games.gitbook.io/pixel-palette/core-components/drawable-canvas.md).

# Drawable Canvas

**DrawableCanvas** is the heart of the whole system. It owns the canvas texture, manages compositing, and coordinates all the other parts (layers, brushes, undo, selection, animation).

#### What it owns

| Thing                         | What it is                                                                           |
| ----------------------------- | ------------------------------------------------------------------------------------ |
| `canvasWidth`, `canvasHeight` | The pixel dimensions of your canvas (16×16, 32×32, 64×64, etc.)                      |
| `compositeTexture`            | The final picture you see on screen — all layers blended together into one Texture2D |
| `canvasImage`                 | The RawImage that displays the composite texture on the UI                           |
| `inputRect`                   | The RectTransform used to convert screen clicks into pixel coordinates               |
| `Background color`            | The clear color behind everything (default: white with 0 alpha = transparent)        |
| `PenColor`                    | The currently selected drawing color                                                 |

#### Stroke pipeline

When you draw, three things happen in sequence:

```
1. StartStroke(position, pressure)
   └─ Tells the active brush a stroke is starting
   └─ Begins undo capture (saves the area before you modify it)

2. ContinueStroke(position, pressure)  
   └─ Tells the brush to keep painting as you drag
   └─ Brush writes directly into the active layer's RawPixels array
   └─ Brush calls QueueCompositeRefresh(dirtyRect) to mark what changed

3. EndStroke()
   └─ Tells the brush the stroke is done
   └─ Finalizes the undo step
```

#### Compositing (building the final picture)

Whenever pixels change, `RefreshComposite(dirtyRect)` rebuilds only the area that was modified:

1. **Fast path** — if there's exactly one visible, fully-opaque layer, copy it straight to the composite. No math needed.
2. **General path** — for each pixel in the dirty area, walk every visible layer bottom-to-top and alpha-blend them together.
3. **Overlays** — stamp the floating selection content, marching ants outline, and onion skin ghost on top.
4. **Upload** — send the finished pixels to the GPU via `SetPixels32` + `Apply`.

#### What it connects to

DrawableCanvas is the hub that everything plugs into:

| System                   | How DrawableCanvas talks to it                                                             |
| ------------------------ | ------------------------------------------------------------------------------------------ |
| **BrushSystem**          | Creates brushes, passes them strokes (`StartStroke` → brush paints on layer → `EndStroke`) |
| **LayerManager**         | Reads layer pixels for compositing, writes brush changes to active layer                   |
| **UndoManager**          | Captures pixel state before changes (`BeginStroke` / `CaptureBeforeChange` / `EndStroke`)  |
| **SelectionManager**     | Stamps floating selection and outline onto the composite                                   |
| **AnimationManager**     | Reads composite for frame previews, applies onion skin during compositing                  |
| **CanvasViewController** | Gets the canvas RectTransform for zoom/pan                                                 |
| **CanvasInputHandler**   | Calls `TryScreenToPixel()` and the stroke methods each frame                               |
| **GridOverlay**          | Gets `OnCanvasResized` event to rebuild the grid                                           |

#### Public helpers

| Method                                              | What it does                                                                                                       |
| --------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
| `TryScreenToPixel(camera, screenPos, out pixelPos)` | Converts where you click on screen to a pixel coordinate on the canvas. Returns false if you're outside the canvas |
| `SetCanvasSize(w, h)`                               | Resizes everything — tears down layers, creates new textures, clears undo, resets view                             |
| `CompositeAllLayers()`                              | Forces a full re-composite of the entire canvas                                                                    |
| `QueueCompositeRefresh(rect)`                       | Marks a region as dirty so it gets re-drawn next frame                                                             |
| `GetCompositeTexture()`                             | Returns the final blended Texture2D (for PNG export)                                                               |
| `ClampRect(rect)`                                   | Snaps a rectangle to stay within canvas bounds                                                                     |
| `BeginDirectLayerChange` / `EndDirectLayerChange`   | Manual undo capture for operations outside the normal stroke pipeline (like fill tool or layer merge)              |


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://viridian-games.gitbook.io/pixel-palette/core-components/drawable-canvas.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
