Sprites.Media.Sprite
The sprite editor, its state and its windows, over an integer pixel grid. The pixel grid is drawn by Sprites.Media.Sprite.Canvas, and the editor's tools live in Sprites.Media.Sprite.Tool.
- Sprites.Media.Sprite.ClampSide
- Sprites.Media.Sprite.CloneFrame
- Sprites.Media.Sprite.CloneLayer
- Sprites.Media.Sprite.ColourPicker
- Sprites.Media.Sprite.Editor
- Sprites.Media.Sprite.New (empty cells)
- Sprites.Media.Sprite.FitPan
- Sprites.Media.Sprite.FitShow
- Sprites.Media.Sprite.FrameThumbnail
- Sprites.Image.Draw.Grid (canvas grid)
- Sprites.Maths.Multiply (grid column x)
- Sprites.Maths.Increment (grid rows)
- Sprites.Media.Sprite.Info
- Sprites.Media.Sprite.LayerThumbnail
- Sprites.Media.Sprite.MaxSide
- Sprites.Media.Sprite.MinSide
- Sprites.Media.Sprite.ModeFitSize
- Sprites.Media.Sprite.New
- Sprites.Media.Sprite.NewDocument
- Sprites.Media.Sprite.NewFrame
- Sprites.Media.Sprite.NewLayer
- Sprites.Grid.Two.Set (paint cell)
- Sprites.Grid.Two.FillRect (paint brush)
- Sprites.Media.Sprite.Palette
- Sprites.Media.Sprite.PalettePicker
- Sprites.Media.Sprite.PixelsToRGBA
- Sprites.Grid.Two.Resize (resize grid)
- Sprites.Media.Sprite.ResizeAll
- Sprites.Media.Sprite.SelectedGrid
- Sprites.Media.Sprite.StageTop
- Sprites.Media.Sprite.Summary
- Sprites.Media.Sprite.Thumbnail
- Sprites.Media.Sprite.Transparent
- Sprites.Media.Sprite.White
- Sprites.Media.Sprite.WithLayers
- Sprites.Media.Sprite.WrapColours
Sprites.Media.Sprite.ClampSide Number
Sprites.Media.Sprite.ClampSide(n)
Clamp a side to the allowed range, as a whole number, between MinSide and MaxSide.
| Input | Type | Description |
|---|---|---|
n | Number | A requested side length. |
Returns the clamped whole number.
const side = Sprites.Media.Sprite.ClampSide(1000);
Sprites.Ui.Dom.Text('ClampSide(1000) = ', side);
Sprites.Media.Sprite.CloneFrame Sprites.Reactive.Value
Sprites.Media.Sprite.CloneFrame(frame)
A copy of a frame: a fresh frame object whose layers are each cloned, so the copy is independent of the original. A composite over Array.Map and CloneLayer.
| Input | Type | Description |
|---|---|---|
frame | Object or Sprites.Reactive.Value | A { layers } frame to copy. |
Returns a Sprites.Reactive.Value holding the cloned { layers } frame.
const frame = Sprites.Media.Sprite.NewFrame(4, 4);
const copy = Sprites.Media.Sprite.CloneFrame(frame);
const layers = Sprites.Object.Field(copy, 'layers');
const count = Sprites.Array.Length(layers);
Sprites.Ui.Dom.Text('layers = ', count);
Sprites.Media.Sprite.CloneLayer Sprites.Reactive.Value
Sprites.Media.Sprite.CloneLayer(layer)
A copy of a layer: a fresh layer object holding the same pixels and visible flag. Rebuilding the object keeps the copy independent, so editing one leaves the other be, since a paint replaces the pixels rather than changing them in place.
| Input | Type | Description |
|---|---|---|
layer | Object or Sprites.Reactive.Value | A { pixels, visible } layer to copy. |
Returns a Sprites.Reactive.Value holding the cloned { pixels, visible } layer.
const layer = Sprites.Media.Sprite.NewLayer(4, 4);
const copy = Sprites.Media.Sprite.CloneLayer(layer);
const pixels = Sprites.Object.Field(copy, 'pixels');
const count = Sprites.Array.Length(pixels);
const visible = Sprites.Object.Field(copy, 'visible');
Sprites.Ui.Dom.Text('pixels = ', count, ', visible = ', visible);
Sprites.Media.Sprite.ColourPicker Void
Sprites.Media.Sprite.ColourPicker(visible, colour, bits, allowAlpha)
A modal wrapping Sprites.Colour.Picker. It edits a temp seeded from colour on open, so Select commits the temp to colour and Close discards it.
| Input | Type | Description |
|---|---|---|
visible | Sprites.Reactive.Value | Shows the modal while true. |
colour | Sprites.Reactive.Value | The packed colour Select writes. |
bits | Number | The bits per channel the sliders step over. |
allowAlpha | Boolean | Adds an alpha row. |
Returns nothing.
const orange = 0xff8000ff;
const colour = Sprites.Reactive.Value(orange);
const visible = Sprites.Reactive.Value(false);
Sprites.Ui.Button.SetValue(visible, true, 'Edit colour');
Sprites.Media.Sprite.ColourPicker(visible, colour, 8, true);
const css = Sprites.Colour.Css(colour);
Sprites.Ui.Dom.Text('css = ', css);
Sprites.Media.Sprite.Editor Void
Sprites.Media.Sprite.Editor(data, thumb, info, optionalModes, optionalModeName, optionalSelectedColours, optionalAllColours)
The sprite editor. Builds the view on the host, the pan and zoom overlay, the Tools window, each canvas tool's own window, the four panel windows, and the Palette and Info windows. It builds interface and returns nothing; the doc fields it is given are where the edits land. data is the whole stored document, a two way { w, h, mode, frames }; the editor holds its own selected frame and layer, edits into the selected layer, and draws the current frame's visible layers flattened. On every edit it writes a fresh PNG preview to thumb and a short mode and size summary string to info. optionalSelectedColours makes an indexed editor; left out, it is freeform. optionalModes lists the machine's sprite modes, each with a colour count, a pixel aspect and a size rule; the Info window picks the mode and the size. optionalModeName is a two way value of the current mode's name. A mode with fewer colours wraps the pixels and the brush into range and shows a shorter palette.
| Input | Type | Description |
|---|---|---|
data | Sprites.Reactive.Value | The whole stored document, a two way { w, h, mode, frames } of frames of layers of pixels. The editor edits the selected layer and shows the current frame's visible layers flattened. |
thumb | Sprites.Reactive.Value | The editor Sets a fresh PNG data URL of the pixels here on every edit. |
info | Sprites.Reactive.Value | The editor Sets a short mode and size summary string here on every edit, for the meta record a listing reads. |
optionalModes | Array | Optional. The machine's sprite modes; left out, one free-size mode is used. |
optionalModeName | Sprites.Reactive.Value | Optional. A two way value of the current mode's name. |
optionalSelectedColours | Array | Optional. Slot colours as packed integers; makes the editor indexed. |
optionalAllColours | Object | Optional. Where a slot edit draws from: { palette } or { bitsPerChannel }. |
Each mode in optionalModes is { name, colours, pixelAspect } plus one size rule: allowedWidths and allowedHeights for two dropdowns, allowedSizes (an array of [width, height]) for one dropdown, or neither for typed width and height, bounded by minWidth, maxWidth, minHeight and maxHeight.
Returns nothing.
const on = Sprites.Reactive.Value(false);
Sprites.Ui.Button.SetValue(on, true, 'Launch editor');
Sprites.Reactive.If(on, () => {
Sprites.Ui.Dom.Tag('div', () => {
Sprites.Ui.Dom.Style('height', '260px');
const fresh = Sprites.Media.Sprite.New(16, 16);
const blank = Sprites.Reactive.read(fresh);
const data = Sprites.Reactive.Value(blank);
const thumb = Sprites.Reactive.Value(undefined);
const info = Sprites.Reactive.Value(undefined);
Sprites.Media.Sprite.Editor(data, thumb, info);
});
});
Sprites.Media.Sprite.New Object
Sprites.Media.Sprite.New(w, h)
A fresh grid, its cells all transparent. New builds a { w, h, cells } grid whose cells are a flat list in row order, length w times h, every cell the transparent value.
| Input | Type | Description |
|---|---|---|
w | Number | The width in pixels. |
h | Number | The height in pixels. |
Returns the new grid, all cells transparent.
const grid = Sprites.Media.Sprite.New(4, 4);
const cells = Sprites.Object.Field(grid, 'cells');
const first = Sprites.Array.At(cells, 0);
const empty = Sprites.Logic.Equals(first, Sprites.Media.Sprite.Transparent);
const count = Sprites.Array.Length(cells);
Sprites.Ui.Dom.Text(count, ' cells, first transparent = ', empty);
Sprites.Media.Sprite.FitPan Sprites.Reactive.Value
Sprites.Media.Sprite.FitPan(width, height, aspect)
The pan that centres the whole sprite: half its drawn width and half its height, with the width stretched by the pixel aspect. A calculation helper, so the view follows the size and aspect on its own.
| Input | Type | Description |
|---|---|---|
width | Number or Sprites.Reactive.Value | The sprite width in pixels. |
height | Number or Sprites.Reactive.Value | The sprite height in pixels. |
aspect | Number or Sprites.Reactive.Value | The pixel aspect the width is stretched by. |
Returns a read-only Sprites.Reactive.Value holding the centre { x, y } point.
const pan = Sprites.Media.Sprite.FitPan(16, 8, 2);
const x = Sprites.Object.Field(pan, 'x');
const y = Sprites.Object.Field(pan, 'y');
Sprites.Ui.Dom.Text('x = ', x, ', y = ', y);
Sprites.Media.Sprite.FitShow Sprites.Reactive.Value
Sprites.Media.Sprite.FitShow(width, height, aspect)
The show that spans the wider of the two drawn axes, with a small margin, so the whole sprite stays in view. A calculation helper.
| Input | Type | Description |
|---|---|---|
width | Number or Sprites.Reactive.Value | The sprite width in pixels. |
height | Number or Sprites.Reactive.Value | The sprite height in pixels. |
aspect | Number or Sprites.Reactive.Value | The pixel aspect the width is stretched by. |
Returns a read-only Sprites.Reactive.Value holding the units to show across.
const show = Sprites.Media.Sprite.FitShow(16, 8, 2);
Sprites.Ui.Dom.Text('FitShow(16, 8, 2) = ', show);
Sprites.Media.Sprite.FrameThumbnail Sprites.Reactive.Value
Sprites.Media.Sprite.FrameThumbnail(frame, width, height, optionalPaletteSlots, aspect)
A PNG data URL of one frame, its visible layers flattened and drawn through the palette and pixel aspect, as a reactive value that follows the frame, for a frame card's preview. A composite over Grid.Two.Flatten and Thumbnail.
| Input | Type | Description |
|---|---|---|
frame | Object or Sprites.Reactive.Value | A { layers } frame, its layers over the width and height. |
width | Number or Sprites.Reactive.Value | The document width, shared by every layer. |
height | Number or Sprites.Reactive.Value | The document height, shared by every layer. |
optionalPaletteSlots | Array or Sprites.Reactive.Value | Optional. The slot colours when the sprite is indexed; left out, a cell is a packed colour already. |
aspect | Number or Sprites.Reactive.Value | The pixel aspect baked into the image. |
Returns a read-only Sprites.Reactive.Value holding a PNG data URL string.
const bottom = { pixels: [0xff4444ff, 0xff4444ff, 0xff4444ff, 0xff4444ff], visible: true };
const top = { pixels: [undefined, 0x4444ffff, undefined, undefined], visible: true };
const frame = { layers: [bottom, top] };
const url = Sprites.Media.Sprite.FrameThumbnail(frame, 2, 2, undefined, 1);
Sprites.Ui.Dom.Tag('img', () => {
Sprites.Ui.Dom.Attribute('src', url);
Sprites.Ui.Dom.Style('width', '64px');
Sprites.Ui.Dom.Style('height', '64px');
Sprites.Ui.Dom.Style('image-rendering', 'pixelated');
});
Sprites.Image.Draw.Grid Void
Sprites.Image.Draw.Grid(x1, y1, x2, y2, xDivisions, yDivisions)
A thin line around every pixel of the sprite, drawn inside a Vector. The sprite editor's canvas draws its pixel grid this way, styling the lines with Sprites.Image.Draw.LineStyle over a Sprites.Image.Draw.Grid across the sprite bounds.
| Input | Type | Description |
|---|---|---|
x1, y1 | Number or Sprites.Reactive.Value | The top left of the grid. |
x2, y2 | Number or Sprites.Reactive.Value | The bottom right of the grid. |
xDivisions, yDivisions | Number or Sprites.Reactive.Value | The cells across and down. |
Returns nothing.
const pan = Sprites.Reactive.Value({ x: 4, y: 4 });
const show = Sprites.Reactive.Value(10);
Sprites.Ui.Dom.Tag('div', () => {
Sprites.Ui.Dom.Style('height', '160px');
Sprites.Ui.Image.Vector(pan, show, () => {
Sprites.Image.Draw.LineStyle(0.04, 'rgba(0, 0, 0, 0.5)', () => {
Sprites.Image.Draw.Grid(0, 0, 8, 8, 8, 8);
});
});
});
Sprites.Maths.Multiply Sprites.Reactive.Value
Sprites.Maths.Multiply(k, aspect)
The drawn x of grid line k: its column stretched by the pixel aspect. The canvas grid places each vertical line by multiplying the column index by the aspect, so a wide-pixel mode spreads the columns apart.
| Input | Type | Description |
|---|---|---|
k | Number or Sprites.Reactive.Value | The grid line index across the width. |
aspect | Number or Sprites.Reactive.Value | The pixel aspect the column is stretched by. |
Returns a read-only Sprites.Reactive.Value, the drawn x of the line.
const x = Sprites.Maths.Multiply(3, 2);
Sprites.Ui.Dom.Text('column 3 at aspect 2 draws at x = ', x);
Sprites.Maths.Increment Sprites.Reactive.Value
Sprites.Maths.Increment(height)
The count of grid lines down the height, one past each row. The canvas grid draws one line above the first row and one below each row, so an h-row sprite needs h plus one lines, the height incremented.
| Input | Type | Description |
|---|---|---|
height | Number or Sprites.Reactive.Value | The sprite height in cells. |
Returns a read-only Sprites.Reactive.Value, the grid line count down.
const rows = Sprites.Maths.Increment(8);
Sprites.Ui.Dom.Text('an 8-row sprite needs ', rows, ' lines down');
Sprites.Media.Sprite.Info Void
Sprites.Media.Sprite.Info(modes, modeIndex, state, width, height)
The Info window: an always-present floating panel docked to the stage's bottom right. It holds a Mode dropdown and, below it, the size controls for the current mode. Picking a mode sets the colour count and the pixel aspect, and resets the size when the current one falls outside the mode.
| Input | Type | Description |
|---|---|---|
modes | Array | The sprite modes to choose from. |
modeIndex | Sprites.Reactive.Value | The index of the current mode, set by the dropdown. |
state | Sprites.Reactive.Value | The sprite state, resized by the size controls. |
width, height | Sprites.Reactive.Value | The size in pixels, for the free and dropdown controls. |
Returns nothing.
const modes = [
{ name: 'High-res', colours: 2, pixelAspect: 1, allowedSizes: [[24, 21]] },
{ name: 'Multicolour', colours: 4, pixelAspect: 2, allowedSizes: [[12, 21]] },
];
const modeIndex = Sprites.Reactive.Value(0);
const sprite = Sprites.Media.Sprite.New(24, 21);
const state = Sprites.Reactive.Value(sprite);
const width = Sprites.Object.Field(state, 'w');
const height = Sprites.Object.Field(state, 'h');
Sprites.Media.Sprite.Info(modes, modeIndex, state, width, height);
Sprites.Ui.Dom.Text('mode = ', modeIndex);
Sprites.Media.Sprite.LayerThumbnail Sprites.Reactive.Value
Sprites.Media.Sprite.LayerThumbnail(layer, width, height, optionalPaletteSlots, aspect)
A PNG data URL of one layer, drawn at the document size through the palette and pixel aspect, as a reactive value that follows the layer's pixels, for a layer card's preview. A composite over Thumbnail.
| Input | Type | Description |
|---|---|---|
layer | Object or Sprites.Reactive.Value | A { pixels, visible } layer over the width and height. |
width | Number or Sprites.Reactive.Value | The document width. |
height | Number or Sprites.Reactive.Value | The document height. |
optionalPaletteSlots | Array or Sprites.Reactive.Value | Optional. The slot colours when the sprite is indexed; left out, a cell is a packed colour already. |
aspect | Number or Sprites.Reactive.Value | The pixel aspect baked into the image. |
Returns a read-only Sprites.Reactive.Value holding a PNG data URL string.
const layer = { pixels: [0xff4444ff, undefined, undefined, 0x4444ffff], visible: true };
const url = Sprites.Media.Sprite.LayerThumbnail(layer, 2, 2, undefined, 1);
Sprites.Ui.Dom.Tag('img', () => {
Sprites.Ui.Dom.Attribute('src', url);
Sprites.Ui.Dom.Style('width', '64px');
Sprites.Ui.Dom.Style('height', '64px');
Sprites.Ui.Dom.Style('image-rendering', 'pixelated');
});
Sprites.Media.Sprite.MaxSide Number
Sprites.Media.Sprite.MaxSide
The largest a sprite side may be. A constant, not a function, used with MinSide to clamp a requested width or height.
Value 256.
Sprites.Ui.Dom.Text('MaxSide = ', Sprites.Media.Sprite.MaxSide);
Sprites.Media.Sprite.MinSide Number
Sprites.Media.Sprite.MinSide
The smallest a sprite side may be. A constant, not a function, used with MaxSide to clamp a requested width or height.
Value 1.
Sprites.Ui.Dom.Text('MinSide = ', Sprites.Media.Sprite.MinSide);
Sprites.Media.Sprite.ModeFitSize Sprites.Reactive.Value
Sprites.Media.Sprite.ModeFitSize(mode, width, height)
The size a mode allows, given the current width and height: a reactive { w, h }. A mode with allowedSizes keeps the current pair when it is one of them, else the first pair; a mode with allowedWidths or allowedHeights keeps the current side when it is allowed, else the first allowed value; a mode with none keeps the current size. A composite, reading the same in the mode lens as it does going forward.
| Input | Type | Description |
|---|---|---|
mode | Object or Sprites.Reactive.Value | The mode, with allowedSizes, or allowedWidths and allowedHeights, or none. |
width | Number or Sprites.Reactive.Value | The current width in pixels. |
height | Number or Sprites.Reactive.Value | The current height in pixels. |
Returns a read-only Sprites.Reactive.Value holding the allowed { w, h } size.
const mode = { allowedSizes: [[24, 21], [12, 21]] };
const size = Sprites.Media.Sprite.ModeFitSize(mode, 40, 40);
const w = Sprites.Object.Field(size, 'w');
const h = Sprites.Object.Field(size, 'h');
Sprites.Ui.Dom.Text('w = ', w, ', h = ', h);
Sprites.Media.Sprite.New Object
Sprites.Media.Sprite.New(w, h)
A new sprite state at the given size, or 32 by 32, empty. The state is { w, h, cells }.
| Input | Type | Description |
|---|---|---|
w | Number | The width, clamped. Defaults to 32. |
h | Number | The height, clamped. Defaults to 32. |
Returns the new sprite state.
const sprite = Sprites.Media.Sprite.New(8, 8);
const line = Sprites.Reactive.Calculate(() => {
const s = Sprites.Reactive.Calculate.Get(sprite);
return 'New(8, 8): ' + s.w + ' by ' + s.h + ', ' + s.cells.length + ' cells';
});
Sprites.Ui.Dom.Text(line);
Sprites.Media.Sprite.NewDocument Object
Sprites.Media.Sprite.NewDocument(w, h, optionalMode)
A new sprite document at the given size in the given mode: the { w, h, mode, frames } shape the store keeps, its one frame holding one visible layer of the blank pixels. A boot factory a page hands to the store, so it snapshots the blank grid plain here rather than staying a live reactive.
| Input | Type | Description |
|---|---|---|
w | Number | The width, clamped. Defaults to 32. |
h | Number | The height, clamped. Defaults to 32. |
optionalMode | String or undefined | Optional. The mode name stored on the document. |
Returns the new { w, h, mode, frames } document.
const doc = Sprites.Media.Sprite.NewDocument(8, 8, 'High-res');
const w = Sprites.Object.Field(doc, 'w');
const h = Sprites.Object.Field(doc, 'h');
const frames = Sprites.Object.Field(doc, 'frames');
const mode = Sprites.Object.Field(doc, 'mode');
const frameCount = Sprites.Array.Length(frames);
Sprites.Ui.Dom.Text(w, ' by ', h, ', ', frameCount, ' frame, mode ', mode);
Sprites.Media.Sprite.NewFrame Sprites.Reactive.Value
Sprites.Media.Sprite.NewFrame(width, height)
A new blank frame at the given size: one background layer, blank and visible. A composite, for a click that adds or seeds a frame.
| Input | Type | Description |
|---|---|---|
width | Number or Sprites.Reactive.Value | The width in pixels. |
height | Number or Sprites.Reactive.Value | The height in pixels. |
Returns a Sprites.Reactive.Value holding a { layers } frame with one blank layer.
const frame = Sprites.Media.Sprite.NewFrame(8, 8);
const layers = Sprites.Object.Field(frame, 'layers');
const count = Sprites.Array.Length(layers);
Sprites.Ui.Dom.Text('layers = ', count);
Sprites.Media.Sprite.NewLayer Sprites.Reactive.Value
Sprites.Media.Sprite.NewLayer(width, height)
A new blank layer at the given size: one visible layer of transparent pixels, its grid built with the grid primitive. A composite, so a click that adds a layer passes it as a fresh reactive value the array insert commits.
| Input | Type | Description |
|---|---|---|
width | Number or Sprites.Reactive.Value | The width in pixels. |
height | Number or Sprites.Reactive.Value | The height in pixels. |
Returns a Sprites.Reactive.Value holding a { pixels, visible } layer.
const layer = Sprites.Media.Sprite.NewLayer(8, 8);
const pixels = Sprites.Object.Field(layer, 'pixels');
const count = Sprites.Array.Length(pixels);
const visible = Sprites.Object.Field(layer, 'visible');
Sprites.Ui.Dom.Text('pixels = ', count, ', visible = ', visible);
Sprites.Grid.Two.Set Sprites.Reactive.Value
Sprites.Grid.Two.Set(grid, col, row, colour)
Paint one cell to a colour. A sprite is a Sprites.Grid.Two, so a single-cell paint is Sprites.Grid.Two.Set: it returns a new grid, or the same one when the cell falls outside the grid or already holds that colour, so an unchanged paint sets nothing.
| Input | Type | Description |
|---|---|---|
grid | Object or Sprites.Reactive.Value | The { w, h, cells } sprite. |
col | Number | The column. |
row | Number | The row. |
colour | Number or undefined | A cell value, or the transparent value to clear. |
Returns the new or unchanged grid.
const blank = Sprites.Media.Sprite.New(8, 8);
const painted = Sprites.Grid.Two.Set(blank, 2, 3, Sprites.Media.Sprite.White);
const cell = Sprites.Grid.Two.At(painted, 2, 3);
Sprites.Ui.Dom.Text('cell (2,3) = ', cell);
Sprites.Grid.Two.FillRect Sprites.Reactive.Value
Sprites.Grid.Two.FillRect(grid, col, row, rectWidth, rectHeight, colour)
Paint every cell a brush covers to a colour, or the transparent value to erase. The editor's brush is a square of Sprites.Grid.Two.FillRect: a radius one brush is a three by three rect from one cell up and left of the centre. Cells outside the grid are clipped. Returns a new grid, or the same one when nothing changes.
| Input | Type | Description |
|---|---|---|
grid | Object or Sprites.Reactive.Value | The { w, h, cells } sprite. |
col | Number | The top left column. |
row | Number | The top left row. |
rectWidth | Number | The cells across. |
rectHeight | Number | The cells down. |
colour | Number or undefined | A cell value, or the transparent value to erase. |
Returns the new or unchanged grid.
const blank = Sprites.Media.Sprite.New(8, 8);
const painted = Sprites.Grid.Two.FillRect(blank, 2, 2, 3, 3, Sprites.Media.Sprite.White);
const centre = Sprites.Grid.Two.At(painted, 3, 3);
Sprites.Ui.Dom.Text('brush centre (3,3) = ', centre);
Sprites.Media.Sprite.Palette Void
Sprites.Media.Sprite.Palette(indexed, slots, brush, visible, edit)
The Palette window: a floating panel docked to the stage's bottom left. Indexed, it holds a Sprites.Colour.Palette of the slot colours and an Edit button; freeform, it holds a Sprites.Colour.Picker inline.
| Input | Type | Description |
|---|---|---|
indexed | Boolean | Show slots (true) or the inline picker (false). |
slots | Sprites.Reactive.Value | The slot colours, when indexed. |
brush | Sprites.Reactive.Value | The painted value: a slot index, or a packed colour. |
visible | Sprites.Reactive.Value | Shows the window while true. |
edit | Function or undefined | Opens the slot editor when given. |
Returns nothing.
const colours = [0xff4444ff, 0x44ff44ff, 0x4444ffff, 0xffff44ff];
const slots = Sprites.Reactive.Value(colours);
const brush = Sprites.Reactive.Value(0);
const visible = Sprites.Reactive.Value(false);
Sprites.Ui.Button.SetValue(visible, true, 'Show palette window');
Sprites.Media.Sprite.Palette(true, slots, brush, visible);
Sprites.Ui.Dom.Text('brush index = ', brush);
Sprites.Media.Sprite.PalettePicker Void
Sprites.Media.Sprite.PalettePicker(visible, index, palette)
A modal wrapping Sprites.Colour.Palette. index is a binding it sets, on Select, to the position of the chosen colour in palette; Close leaves it.
| Input | Type | Description |
|---|---|---|
visible | Sprites.Reactive.Value | Shows the modal while true. |
index | Sprites.Reactive.Value | The position Select writes. |
palette | Array | The packed colours to choose from. |
Returns nothing.
const index = Sprites.Reactive.Value(0);
const palette = [0xff4444ff, 0x44ff44ff, 0x4444ffff, 0xffff44ff];
const visible = Sprites.Reactive.Value(false);
Sprites.Ui.Button.SetValue(visible, true, 'Pick a colour');
Sprites.Media.Sprite.PalettePicker(visible, index, palette);
Sprites.Ui.Dom.Text('index = ', index);
Sprites.Media.Sprite.PixelsToRGBA Sprites.Reactive.Value
Sprites.Media.Sprite.PixelsToRGBA(pixels, optionalPalette)
The sprite as a grid of packed RGBA colours. With no palette the sprite is freeform: a cell is the packed colour already and a transparent cell is already undefined, so the pixels stand as they are. With a palette the sprite is indexed: a cell is a slot index, so each cell resolves to the slot's packed colour, keeping a transparent cell transparent. The view and the thumbnail both draw from this, so a packed colour is the one pixel form everything reads.
| Input | Type | Description |
|---|---|---|
pixels | Grid or Sprites.Reactive.Value | The sprite's pixels grid, packed colours or slot indices. |
optionalPalette | Array or Sprites.Reactive.Value | Optional. The slot colours for an indexed sprite; left out, a cell is a packed colour already. |
Returns a Sprites.Reactive.Value holding the grid of packed RGBA colours.
const palette = [0xff4444ff, 0x4444ffff];
const pixels = { w: 2, h: 1, cells: [0, 1] };
const rgba = Sprites.Media.Sprite.PixelsToRGBA(pixels, palette);
const cell00 = Sprites.Grid.Two.At(rgba, 0, 0);
const cell10 = Sprites.Grid.Two.At(rgba, 1, 0);
Sprites.Ui.Dom.Text('cell (0,0) = ', cell00, ', cell (1,0) = ', cell10);
Sprites.Grid.Two.Resize Sprites.Reactive.Value
Sprites.Grid.Two.Resize(grid, nw, nh, pad)
Resize the grid to nw by nh, keeping the cells that still fit and filling new area with pad. A sprite is a Sprites.Grid.Two, so one layer resizes with Sprites.Grid.Two.Resize, padding new area with the transparent value; ResizeAll runs it over every layer of the document.
| Input | Type | Description |
|---|---|---|
grid | Object or Sprites.Reactive.Value | The { w, h, cells } sprite. |
nw | Number | The new width. |
nh | Number | The new height. |
pad | Any | The cell for new area, the transparent value here. |
Returns the resized grid.
const blank = Sprites.Media.Sprite.New(8, 8);
const resized = Sprites.Grid.Two.Resize(blank, 4, 16, Sprites.Media.Sprite.Transparent);
const width = Sprites.Grid.Two.Width(resized);
const height = Sprites.Grid.Two.Height(resized);
Sprites.Ui.Dom.Text('resized to ', width, ' by ', height);
Sprites.Media.Sprite.ResizeAll Sprites.Reactive.Value
Sprites.Media.Sprite.ResizeAll(data, width, height, pad)
The same document resized so every layer of every frame is the new width and height, cropping or padding each layer's pixels with pad. Width and height live on the document, shared by every layer, so a size or mode change resizes them all together. A composite over Array.Map, Grid.Two.Resize and ReadOnly, keeping the mode and each layer's visible flag.
| Input | Type | Description |
|---|---|---|
data | Object or Sprites.Reactive.Value | The { w, h, mode, frames } document. |
width | Number or Sprites.Reactive.Value | The new width for every layer. |
height | Number or Sprites.Reactive.Value | The new height for every layer. |
pad | Any or Sprites.Reactive.Value | The pixel for the new area when growing. |
Returns a Sprites.Reactive.Value holding the resized document.
const doc = Sprites.Media.Sprite.NewDocument(8, 8);
const resized = Sprites.Media.Sprite.ResizeAll(doc, 4, 16, undefined);
const w = Sprites.Object.Field(resized, 'w');
const h = Sprites.Object.Field(resized, 'h');
Sprites.Ui.Dom.Text('size = ', w, ' by ', h);
Sprites.Media.Sprite.SelectedGrid Sprites.Reactive.Value
Sprites.Media.Sprite.SelectedGrid(data, frameIndex, layerIndex)
A two way { w, h, cells } grid over the layer at layerIndex of the frame at frameIndex. data is the two way stored { w, h, mode, frames } value; frameIndex and layerIndex are the editor's selection. Reading composes the grid from the width, height and that layer's pixels, so the editor edits one flat layer. Writing lays the edited pixels back into that one layer through the frames list, keeping the layer's visible flag and every other frame, layer, the size and the mode, so a paint touches only the selected layer.
| Input | Type | Description |
|---|---|---|
data | Sprites.Reactive.Value | The two way { w, h, mode, frames } document it reads and writes. |
frameIndex | Number or Sprites.Reactive.Value | The selected frame. |
layerIndex | Number or Sprites.Reactive.Value | The selected layer within the frame. |
Returns a two-way Sprites.Reactive.Value over the selected layer's { w, h, cells } grid.
const pixels = Array(64).fill(Sprites.Media.Sprite.Transparent);
pixels[3 * 8 + 2] = Sprites.Media.Sprite.White;
const layer = { pixels: pixels, visible: true };
const frame = { layers: [layer] };
const blank = { w: 8, h: 8, mode: undefined, frames: [frame] };
const data = Sprites.Reactive.Value(blank);
const grid = Sprites.Media.Sprite.SelectedGrid(data, 0, 0);
const width = Sprites.Grid.Two.Width(grid);
const height = Sprites.Grid.Two.Height(grid);
const cell23 = Sprites.Grid.Two.At(grid, 2, 3);
Sprites.Ui.Dom.Text('size = ', width, ' by ', height, ', cell (2,3) = ', cell23);
Sprites.Media.Sprite.StageTop Number
Sprites.Media.Sprite.StageTop
The top edge, in viewport pixels, where the editor's top-docked windows open: a little below where the sprite stage begins, so the Tools window and each tool window open inside the stage rather than over the title and name rows above it. A starting corner only; the windows drag from there. A constant, not a function.
Value 163.
Sprites.Ui.Dom.Text('StageTop = ', Sprites.Media.Sprite.StageTop);
Sprites.Media.Sprite.Summary String
Sprites.Media.Sprite.Summary(modeName, grid)
The meta info summary for a sprite: its mode and size as one short string, for the meta record a listing reads. A plain reader for use inside a reverse handler: it reads the mode name and the grid's sides and joins them, dropping the mode when there is none.
| Input | Type | Description |
|---|---|---|
modeName | String or Sprites.Reactive.Value | The mode name, or empty for no mode. |
grid | Object | A snapshot { w, h } grid. |
Returns the summary string, like "High-res · 24×21".
const summary = Sprites.Media.Sprite.Summary('High-res', { w: 24, h: 21 });
Sprites.Ui.Dom.Text('summary = ', summary);
Sprites.Media.Sprite.Thumbnail String
Sprites.Media.Sprite.Thumbnail(sprite, optionalPaletteSlots, optionalAspectRatio)
A PNG data URL of the sprite's pixels, one image pixel per sprite pixel, transparent where a cell is empty. optionalPaletteSlots maps indexed pixels through a palette to packed colours, and is omitted when the pixels already hold packed colours. optionalAspectRatio stretches the pixels to match a wide or tall pixel mode. A plain value helper over a snapshot, so it can run in a save handler to keep a stored thumbnail current with the pixels.
| Input | Type | Description |
|---|---|---|
sprite | Grid | The sprite's pixels grid, a Sprites.Grid.Two of packed colours or palette indices. |
optionalPaletteSlots | Array | Optional. A palette mapping pixel indices to packed colours, for indexed modes; omit when the pixels are already packed colours. |
optionalAspectRatio | Number | Optional, default 1. The pixel aspect: above 1 draws each pixel wider, below 1 taller. |
Returns a PNG data URL string.
const red = 0xff4444ff;
const blue = 0x4444ffff;
const blank = Sprites.Media.Sprite.New(4, 4);
const withRed = Sprites.Grid.Two.Set(blank, 1, 1, red);
const painted = Sprites.Grid.Two.Set(withRed, 2, 2, blue);
const url = Sprites.Media.Sprite.Thumbnail(painted, undefined, 1);
Sprites.Ui.Dom.Tag('img', () => {
Sprites.Ui.Dom.Attribute('src', url);
Sprites.Ui.Dom.Style('width', '64px');
Sprites.Ui.Dom.Style('height', '64px');
Sprites.Ui.Dom.Style('image-rendering', 'pixelated');
});
Sprites.Media.Sprite.Transparent Number
Sprites.Media.Sprite.Transparent
The transparent cell: an absent value, undefined. A cell holds this where nothing is painted, and a resize or an erase writes it. Naming it keeps the absent value intentional and reads as transparent at every use. A constant, not a function.
Value undefined.
const empty = Sprites.Logic.Equals(Sprites.Media.Sprite.Transparent, undefined);
Sprites.Ui.Dom.Text('Transparent is undefined = ', empty);
Sprites.Media.Sprite.White Number
Sprites.Media.Sprite.White
Opaque white as a packed colour, the freeform brush default. A constant, not a function.
Value the packed colour Sprites.Colour.Pack(255, 255, 255, 255).
Sprites.Ui.Dom.Text('White = ', Sprites.Media.Sprite.White);
Sprites.Media.Sprite.WithLayers Sprites.Reactive.Value
Sprites.Media.Sprite.WithLayers(frames, frameIndex, layers)
A frames list with the frame at frameIndex given a new layers list. A composite, for a layer edit: the layers of a frame past the first are only reachable through the frames list, so a layer change lays a new frames list a Set of frames commits.
| Input | Type | Description |
|---|---|---|
frames | Array or Sprites.Reactive.Value | The frames list, each a { layers } frame. |
frameIndex | Number or Sprites.Reactive.Value | The frame whose layers are replaced. |
layers | Array or Sprites.Reactive.Value | The new layers list for that frame. |
Returns a Sprites.Reactive.Value holding the frames list with the one frame's layers replaced.
const base = { pixels: Array(16).fill(Sprites.Media.Sprite.Transparent), visible: true };
const extra = { pixels: Array(16).fill(Sprites.Media.Sprite.Transparent), visible: true };
const frames = [{ layers: [base] }];
const layers = [base, extra];
const updated = Sprites.Media.Sprite.WithLayers(frames, 0, layers);
const frame = Sprites.Array.At(updated, 0);
const frameLayers = Sprites.Object.Field(frame, 'layers');
const count = Sprites.Array.Length(frameLayers);
Sprites.Ui.Dom.Text('layers = ', count);
Sprites.Media.Sprite.WrapColours Sprites.Reactive.Value
Sprites.Media.Sprite.WrapColours(data, count)
The same document with every pixel of every layer folded into a colour count, a transparent pixel staying transparent, so a mode with fewer colours wraps the pixels of all the layers into range at once. A composite over Array.Map, Sprites.Maths.Modulo and Sprites.Logic.Select, keeping the size, the mode and each layer's visible flag.
| Input | Type | Description |
|---|---|---|
data | Object or Sprites.Reactive.Value | The { w, h, mode, frames } document. |
count | Number or Sprites.Reactive.Value | The colour count each pixel index is folded into, 0 to count minus one. |
Returns a Sprites.Reactive.Value holding the document with every pixel wrapped into range.
const layer = { pixels: [0, 5, 6, 7], visible: true };
const doc = { w: 2, h: 2, mode: undefined, frames: [{ layers: [layer] }] };
const wrapped = Sprites.Media.Sprite.WrapColours(doc, 4);
const line = Sprites.Reactive.Calculate(() => {
const d = Sprites.Reactive.Calculate.Get(wrapped);
return d.frames[0].layers[0].pixels.join(', ');
});
Sprites.Ui.Dom.Text('pixels = ', line);