> For the complete documentation index, see [llms.txt](https://osl.mistium.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://osl.mistium.com/commands/rendering/editing/canvas.md).

# Canvas

The OSL canvas commands are a set of commands that internally store images that can be easily written to and read from. The canvas element is primarily used in situations where the user will directly be interacting with an image, such as drawing programs or image editors.

A canvas can be initialized using one of two ways:

```js
// width - the width of the canvas, in pixels
// height - the height of the canvas, in pixels
// background - the background color of the canvas (ex. #fff)
canvas myCanvas @= canvas(width, height, background)

// url - a DataURI to load as the canvas content, stretched to fit
canvas myCanvas @= canvas.fromURL(url, width, height)
```

## Canvas Type

Canvases also have their own type, so using Typeof will give you "canvas"

```js
canvas myCanvas @= canvas(100, 100, "#fff")

// will log true
log typeof(myCanvas) == "canvas"
```

## Writing to the Canvas

OSL provides many methods for writing to the canvas. The most primitive of these write to a single pixel.

```js
// index starts at 1 in the top left, flowing left to right, top to bottom
myCanvas.setPixel(index, colour)

// (0, 0) is in the center of the canvas
myCanvas.setPixelAt(x, y, colour)
```

### Shapes

The canvas provides methods to draw lines, rectangles, and triangles. When drawing shapes, the cursor's color is used as the fill color (this can be set with the color/colour/c command). They use the same coordinate system as `setPixelAt`, where (0, 0) is in the center of the canvas. **It's worth noting that these methods are not pixel perfect; at smaller canvas sizes they may appear blurry.**

```js
// draws a dot at a position using the current draw cursor colour
myCanvas.dot(x, y, size)

// size - the stroke width of the line in pixels
// cap ("butt"/"round"/"square") - determines how the ends of the line are handled
myCanvas.line(x1, y1, x2, y2, {size: number, cap: "round" | "butt" | "square"})

// rounding - how smooth the corners appear, in pixels
// draws a filled rectangle
myCanvas.rect(x, y, width, height, rounding)

// draws an unfilled rectangle
myCanvas.square(x, y, width, height, rounding)

// each coordinate pair is one corner of the triangle
myCanvas.tri(x1, y1, x2, y2, x3, y3)
```

### Stamping

Canvases can also apply other images onto themselves using DataURIs. The image is stretched to fit the provided dimensions.

```js
myCanvas.image(dataURI, x, y, width, height)
```

## Reading the Canvas

OSL provides several methods for reading canvas data.

To get the entire canvas as a DataURI, use `toURL()`.

```js
myCanvas.toURL()

// returns the canvas as an array of integers
// equivalent to calling ctx.getImageData().data
myCanvas.toArr()
```

Methods can also be used to find the dimensions of the canvas.

```js
myCanvas.width()
myCanvas.height()

// total pixel count, i.e. width * height
myCanvas.pixels()
```

Finally, methods can be used to find the color of specific pixels. These serve as the inverses of `setPixel` and `setPixelAt`.

```js
myCanvas.getPixel(index)
myCanvas.getPixelAt(x, y)
```

## Managing Canvases

Most canvas management is handled internally; all stored canvases are deleted when the window is closed, and canvases are stored in such a way that prevents interference from other scripts. However, sometimes the need arises to handle these interactions manually. OSL exposes several commands for deleting and resizing canvases.

### Deleting/Clearing Canvases

The `delete` and `clear` methods function very similarly, with the key difference being that `delete` entirely removes the canvas from memory, while `clear` simply erases its content, while still allowing it to be written to.

The `fill` method allows you to clear a canvas with a specific colour

```js
// removes the canvas from memory, using the canvas variable after this may cause errors
myCanvas.delete()

// erases all content from the canvas
myCanvas.clear()

// erases all content and fills the canvas with a colour
myCanvas.fill(colour)
```

### Resizing Canvases

The stretch method will stretch the current content (hence the name) to fit the new canvas size specified in the stretch arguments.

```js
myCanvas.stretch(width, height)
```

## Example: Drawing a Checker Pattern

```js
canv @= Canvas(7, 7, #fff)

for i canv.pixels() (
	// check for every other pixel
    if i % 2 == 1 (
        canv.setPixel(i, #000)
    )
)

mainloop:
// canv.toURL() can be plugged directly into the image command
image canv.toURL() 256 256

import "win-buttons"
```


---

# 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, and the optional `goal` query parameter:

```
GET https://osl.mistium.com/commands/rendering/editing/canvas.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
