Sprites.Media.Map

The map media: a layered grid of tile indices drawn from a tile set. A document is { w, h, mode, tileset, layers }. The tile set is { tiles: [ { id }, … ] }, an ordered list of sprite references; a layer is { tiles: [ index | undefined, … ], visible }, its tiles a flat row-order array of indices into the tile set, or undefined for an empty cell that lets the layer below show through. Layers composite top down. The absent cell is undefined, never null. Drawing picks a tile from the tile set the way the sprite editor picks a colour; the layers and the tile set have their own floating windows. See the Map storage format.

The members below fall in groups: the document value functions that read and write the shape; the tile set helpers; the canvas render; and the windows and the editor. A window's example opens it from a button, so no window shows on the page until you ask.

Document

Tile set

Canvas

Constants

Canvas cells

Windows

Tools

Sprites.Media.Map.ClampSide Sprites.Reactive.Value

Sprites.Media.Map.ClampSide(n)

A side rounded to a whole number and held between MinSide (1) and MaxSide (1024). The argument may be a constant or a reactive value.

InputTypeDescription
nNumber or Sprites.Reactive.ValueThe side to clamp, in tiles.

Returns a read-only Sprites.Reactive.Value holding the clamped side.

const n = Sprites.Reactive.Value(5);
const side = Sprites.Media.Map.ClampSide(n);
Sprites.Ui.Input.Number(n, -10, 2000);
Sprites.Ui.Dom.Text(' clamped = ', side);
A side held between 1 and 1024.

Sprites.Media.Map.New Sprites.Reactive.Value

Sprites.Media.Map.New(w, h)

A blank tiles grid at the given size, or 32 by 32, every cell empty. The source of a fresh layer's tiles. Each argument may be a constant or a reactive value.

InputTypeDescription
wNumber or Sprites.Reactive.ValueThe columns across, or 32 when absent.
hNumber or Sprites.Reactive.ValueThe rows down, or 32 when absent.

Returns a read-only Sprites.Reactive.Value holding a blank { w, h, cells } grid.

const width = Sprites.Reactive.Value(4);
const grid = Sprites.Media.Map.New(width, 3);
Sprites.Ui.Input.Number(width, 1, 8);
const gridWidth = Sprites.Grid.Two.Width(grid);
const gridHeight = Sprites.Grid.Two.Height(grid);
Sprites.Ui.Dom.Text(' size = ', gridWidth, '×', gridHeight);
A blank grid, every cell empty, following the width.

Sprites.Media.Map.NewLayer Sprites.Reactive.Value

Sprites.Media.Map.NewLayer(w, h)

A new blank layer at the given size: one visible layer of empty tiles, { tiles, visible }. Passed as a fresh value the Layers window's Add commits.

InputTypeDescription
wNumber or Sprites.Reactive.ValueThe columns across.
hNumber or Sprites.Reactive.ValueThe rows down.

Returns a read-only Sprites.Reactive.Value holding a { tiles, visible } layer.

const layer = Sprites.Media.Map.NewLayer(3, 2);
const tiles = Sprites.Object.Field(layer, 'tiles');
const cellCount = Sprites.Array.Length(tiles);
const visible = Sprites.Object.Field(layer, 'visible');
Sprites.Ui.Dom.Text('cells = ', cellCount, ', visible = ', visible);
A fresh visible layer of six empty cells.

Sprites.Media.Map.NewDocument Object

Sprites.Media.Map.NewDocument(w, h, optionalMode)

A new tile document: the { w, h, mode, tileset, layers } shape the store keeps, an empty tile set and one blank layer. A boot factory a page hands to the store, so it returns plain data.

InputTypeDescription
wNumber or Sprites.Reactive.ValueThe columns across.
hNumber or Sprites.Reactive.ValueThe rows down.
optionalModeStringThe mode name, or absent.

Returns a plain { w, h, mode, tileset, layers } document.

const document = Sprites.Media.Map.NewDocument(4, 3, 'Nametable');
const doc = Sprites.Reactive.Binding(document);
const mode = Sprites.Object.Field(doc, 'mode');
const layers = Sprites.Object.Field(doc, 'layers');
const layerCount = Sprites.Array.Length(layers);
Sprites.Ui.Dom.Text('mode = ', mode, ', layers = ', layerCount);
A fresh document with one layer and an empty tile set.

Sprites.Media.Map.TileAt Sprites.Reactive.Value

Sprites.Media.Map.TileAt(data, layerIndex, col, row)

The tile index at a column and row of one layer, or undefined outside the map or where the cell is empty. Read only.

InputTypeDescription
dataObject or Sprites.Reactive.ValueThe map document.
layerIndexNumber or Sprites.Reactive.ValueWhich layer to read.
colNumber or Sprites.Reactive.ValueThe column across.
rowNumber or Sprites.Reactive.ValueThe row down.

Returns a read-only Sprites.Reactive.Value holding the tile index.

const doc = Sprites.Reactive.Binding{ w: 3, h: 1, mode: 'Nametable', tileset: { tiles: [] }, layers: [ { tiles: [7, 8, 9], visible: true } ] });
const col = Sprites.Reactive.Value(0);
const tile = Sprites.Media.Map.TileAt(doc, 0, col, 0);
Sprites.Ui.Input.Number(col, 0, 2);
Sprites.Ui.Dom.Text(' tile = ', tile);
The tile index at the column, on layer 0.

Sprites.Media.Map.Paint Sprites.Reactive.Value

Sprites.Media.Map.Paint(data, layerIndex, col, row, tile)

The same document with one cell of one layer set to a tile index, keeping every other layer, the tile set, the size and the mode. Returns an equal document for an out of bounds cell. For a paint handler: compose it and Set the document.

InputTypeDescription
dataObject or Sprites.Reactive.ValueThe map document.
layerIndexNumber or Sprites.Reactive.ValueWhich layer to paint.
colNumber or Sprites.Reactive.ValueThe column across.
rowNumber or Sprites.Reactive.ValueThe row down.
tileNumber or Sprites.Reactive.ValueThe tile index to set, or undefined to clear.

Returns a read-only Sprites.Reactive.Value holding the document with the cell set.

const doc = Sprites.Reactive.Binding{ w: 3, h: 1, mode: 'Nametable', tileset: { tiles: [] }, layers: [ { tiles: [undefined, undefined, undefined], visible: true } ] });
const paint = Sprites.Reactive.Bindingundefined, () => {
  const next = Sprites.Media.Map.Paint(doc, 0, 1, 0, 5);
  Sprites.Reactive.Set(doc, next);
});
Sprites.Ui.Button.Act(paint, 'Paint tile 5 at (1,0)');
const layers = Sprites.Object.Field(doc, 'layers');
const layer = Sprites.Array.At(layers, 0);
const tiles = Sprites.Object.Field(layer, 'tiles');
const joined = Sprites.Text.Join(tiles, ', ');
Sprites.Ui.Dom.Text(' tiles = ', joined);
Paint sets one cell of layer 0.

Sprites.Media.Map.ResizeAll Sprites.Reactive.Value

Sprites.Media.Map.ResizeAll(data, width, height, pad)

The same document resized, cropping or padding every layer's tiles with pad, keeping the tile set, the mode and each layer's visible flag. Read only; Width and Height write a resize back.

InputTypeDescription
dataObject or Sprites.Reactive.ValueThe map document.
widthNumber or Sprites.Reactive.ValueThe new width.
heightNumber or Sprites.Reactive.ValueThe new height.
padAny or Sprites.Reactive.ValueThe cell for new area, usually undefined.

Returns a read-only Sprites.Reactive.Value holding the resized document.

const doc = Sprites.Reactive.Binding{ w: 2, h: 1, mode: 'Nametable', tileset: { tiles: [] }, layers: [ { tiles: [1, 2], visible: true } ] });
const width = Sprites.Reactive.Value(3);
const bigger = Sprites.Media.Map.ResizeAll(doc, width, 1, 0);
Sprites.Ui.Input.Number(width, 1, 5);
const layers = Sprites.Object.Field(bigger, 'layers');
const layer = Sprites.Array.At(layers, 0);
const tiles = Sprites.Object.Field(layer, 'tiles');
const joined = Sprites.Text.Join(tiles, ', ');
Sprites.Ui.Dom.Text(' tiles = ', joined);
Every layer cropped or padded to the new width, padding with zero.

Sprites.Media.Map.Width Sprites.Reactive.Value

Sprites.Media.Map.Width(data)

A two way view of a document's width, in tiles. Read, it is the columns across; set, it resizes every layer to that width and writes the whole document back.

InputTypeDescription
dataSprites.Reactive.ValueThe map document it reads and writes.

Returns a two-way Sprites.Reactive.Value over the document's width.

const doc = Sprites.Reactive.Binding{ w: 2, h: 1, mode: 'Nametable', tileset: { tiles: [] }, layers: [ { tiles: [1, 2], visible: true } ] });
const width = Sprites.Media.Map.Width(doc);
Sprites.Ui.Input.Number(width, 1, 6);
const layers = Sprites.Object.Field(doc, 'layers');
const layer = Sprites.Array.At(layers, 0);
const tiles = Sprites.Object.Field(layer, 'tiles');
const joined = Sprites.Text.Join(tiles, ', ');
Sprites.Ui.Dom.Text(' tiles = ', joined);
Set the width and every layer crops or pads with empty cells.

Sprites.Media.Map.Height Sprites.Reactive.Value

Sprites.Media.Map.Height(data)

A two way view of a document's height, in tiles. Read, it is the rows down; set, it resizes every layer to that height and writes the whole document back.

InputTypeDescription
dataSprites.Reactive.ValueThe map document it reads and writes.

Returns a two-way Sprites.Reactive.Value over the document's height.

const doc = Sprites.Reactive.Binding{ w: 2, h: 1, mode: 'Nametable', tileset: { tiles: [] }, layers: [ { tiles: [1, 2], visible: true } ] });
const height = Sprites.Media.Map.Height(doc);
Sprites.Ui.Input.Number(height, 1, 6);
const docWidth = Sprites.Object.Field(doc, 'w');
const docHeight = Sprites.Object.Field(doc, 'h');
Sprites.Ui.Dom.Text(' size = ', docWidth, '×', docHeight);
Set the height and every layer grows or shrinks with the map.

Sprites.Media.Map.Flatten Sprites.Reactive.Value

Sprites.Media.Map.Flatten(data)

The visible layers flattened to one { w, h, cells } grid of tile indices, bottom to top: for each cell the topmost shown layer with a tile there wins, and an empty cell lets the one below show through. The form the canvas draws.

InputTypeDescription
dataObject or Sprites.Reactive.ValueThe map document.

Returns a read-only Sprites.Reactive.Value holding the flattened { w, h, cells } grid.

const bottom = { tiles: [1, 1, 1, 1], visible: true };
const top = { tiles: [undefined, 2, 2, undefined], visible: true };
const doc = Sprites.Reactive.Binding{ w: 4, h: 1, mode: 'Nametable', tileset: { tiles: [] }, layers: [ bottom, top ] });
const flat = Sprites.Media.Map.Flatten(doc);
const cells = Sprites.Object.Field(flat, 'cells');
const joined = Sprites.Text.Join(cells, ', ');
Sprites.Ui.Dom.Text('cells = ', joined);
The top layer's set cells over the bottom; empties show the bottom through.

Sprites.Media.Map.Summary Sprites.Reactive.Value

Sprites.Media.Map.Summary(modeName, w, h)

The meta info summary for a map: its mode and size as one short string, dropping the mode when there is none. A composite over Sprites.Text.Concat and Sprites.Logic.Select.

InputTypeDescription
modeNameString or Sprites.Reactive.ValueThe mode name, or absent.
wNumber or Sprites.Reactive.ValueThe width in tiles.
hNumber or Sprites.Reactive.ValueThe height in tiles.

Returns a read-only Sprites.Reactive.Value holding the summary string.

const summary = Sprites.Media.Map.Summary('Nametable', 32, 30);
Sprites.Ui.Dom.Text('summary = ', summary);
The mode and size joined into one short string.

Sprites.Media.Map.Set Sprites.Reactive.Value

Sprites.Media.Map.Set(data)

The tile set of a document: the { tiles: [ { id } ] } object the layers index into. A field view over the document.

InputTypeDescription
dataObject or Sprites.Reactive.ValueThe map document.

Returns a Sprites.Reactive.Value over the tile set object.

const doc = Sprites.Reactive.Value({ w: 1, h: 1, mode: 'Nametable', tileset: { tiles: [ { id: 'a' } ] }, layers: [ { tiles: [0], visible: true } ] });
const set = Sprites.Media.Map.Set(doc);
const tiles = Sprites.Object.Field(set, 'tiles');
const tileCount = Sprites.Array.Length(tiles);
Sprites.Ui.Dom.Text('tiles in set = ', tileCount);
The document's tile set object.

Sprites.Media.Map.SetTiles Sprites.Reactive.Value

Sprites.Media.Map.SetTiles(data)

The tile set's tiles list: the ordered tiles, each a { id } sprite reference. Read only.

InputTypeDescription
dataObject or Sprites.Reactive.ValueThe map document.

Returns a read-only Sprites.Reactive.Value holding the tiles list.

const doc = Sprites.Reactive.Binding{ w: 1, h: 1, mode: 'Nametable', tileset: { tiles: [ { id: 'a' }, { id: 'b' } ] }, layers: [ { tiles: [0], visible: true } ] });
const tiles = Sprites.Media.Map.SetTiles(doc);
const tileCount = Sprites.Array.Length(tiles);
Sprites.Ui.Dom.Text('count = ', tileCount);
The ordered tiles of the set.

Sprites.Media.Map.TileCount Sprites.Reactive.Value

Sprites.Media.Map.TileCount(data)

The number of tiles in the tile set. Read only.

InputTypeDescription
dataObject or Sprites.Reactive.ValueThe map document.

Returns a read-only Sprites.Reactive.Value holding the tile count.

const doc = Sprites.Reactive.Binding{ w: 1, h: 1, mode: 'Nametable', tileset: { tiles: [ { id: 'a' }, { id: 'b' } ] }, layers: [ { tiles: [0], visible: true } ] });
const tileCount = Sprites.Media.Map.TileCount(doc);
Sprites.Ui.Dom.Text('tiles = ', tileCount);
How many tiles the set holds.

Sprites.Media.Map.AddTile Sprites.Reactive.Value

Sprites.Media.Map.AddTile(data, spriteId)

The same document with one tile added to the tile set: a { id } entry appended to the tile set's tiles. For the tile set window, so a pick appends a sprite reference.

InputTypeDescription
dataObject or Sprites.Reactive.ValueThe map document.
spriteIdString or Sprites.Reactive.ValueThe sprite id to reference as a new tile.

Returns a read-only Sprites.Reactive.Value holding the document with the tile added.

const doc = Sprites.Reactive.Binding{ w: 1, h: 1, mode: 'Nametable', tileset: { tiles: [] }, layers: [ { tiles: [0], visible: true } ] });
const add = Sprites.Reactive.Bindingundefined, () => {
  const next = Sprites.Media.Map.AddTile(doc, 'sprite-id');
  Sprites.Reactive.Set(doc, next);
});
Sprites.Ui.Button.Act(add, 'Add a tile');
const tileCount = Sprites.Media.Map.TileCount(doc);
Sprites.Ui.Dom.Text(' tiles = ', tileCount);
Each press appends a sprite reference to the tile set.

Sprites.Media.Map.AddTiles Sprites.Reactive.Value

Sprites.Media.Map.AddTiles(data, spriteIds)

The same document with a list of sprites added to the tile set: one { id } entry per sprite id appended in order. For the sprite picker, so a multi pick appends every chosen sprite reference at once.

InputTypeDescription
dataObject or Sprites.Reactive.ValueThe map document.
spriteIdsArray or Sprites.Reactive.ValueThe sprite ids to append as new tiles.

Returns a read-only Sprites.Reactive.Value holding the document with the tiles added.

const next = Sprites.Media.Map.AddTiles(doc, ['sprite-a', 'sprite-b']);
Sprites.Reactive.Set(doc, next);
A multi pick appends every chosen sprite to the tile set.

Sprites.Media.Map.SetTile Sprites.Reactive.Value

Sprites.Media.Map.SetTile(data, slot, spriteId)

The same document with the tile at one slot set to a sprite reference, keeping every other tile and the slot's place, so the map's placements keep their index. An out of range slot leaves the set unchanged. For the per slot sprite picker, so choosing a sprite fills that one tile the way the colour picker fills one palette slot.

InputTypeDescription
dataObject or Sprites.Reactive.ValueThe map document.
slotNumber or Sprites.Reactive.ValueThe tile index to set.
spriteIdString or Sprites.Reactive.ValueThe sprite id to reference at that slot.

Returns a read-only Sprites.Reactive.Value holding the document with the slot set.

const next = Sprites.Media.Map.SetTile(doc, 2, 'sprite-id');
Sprites.Reactive.Set(doc, next);
Choosing a sprite fills one tile slot, keeping its index.

Sprites.Media.Map.TileColour Sprites.Reactive.Value

Sprites.Media.Map.TileColour(index, palette)

The CSS colour a tile index is drawn in: the palette colour at the index wrapped by the palette length, a stand-in shown until the tile set's referenced sprites are loaded and drawn. Sprites.Media.Map.Palette is the default swatch palette.

InputTypeDescription
indexNumber or Sprites.Reactive.ValueThe tile index.
paletteArray or Sprites.Reactive.ValueThe packed colours to key off.

Returns a read-only Sprites.Reactive.Value holding a CSS colour string.

const index = Sprites.Reactive.Value(0);
const css = Sprites.Media.Map.TileColour(index, Sprites.Media.Map.Palette);
Sprites.Ui.Input.Number(index, 0, 20);
Sprites.Ui.Dom.Text(' css = ', css);
The placeholder colour for a tile index.

Sprites.Media.Map.View Void

Sprites.Media.Map.View(cells, width, height, pan, show, palette, optionalOverlay)

The map view: a checkerboard backdrop, then a Vector over it with the flattened tiles, a grid on the tile cells, a dark outline, and an optional overlay build last for tool feedback. One world unit is one tile. Builds interface and returns nothing. Companion pieces Tiles, TileColumn, TileRow and TileVisible build the cells; Tool.Draw.Cursor is the overlay.

InputTypeDescription
cellsArray or Sprites.Reactive.ValueThe flattened tile indices, from Flatten.
width, heightNumber or Sprites.Reactive.ValueThe map size in tiles.
pan, showSprites.Reactive.ValueThe view centre and units across.
paletteArrayThe swatch colours.
optionalOverlayFunctionA build run last inside the Vector, or absent.

Returns nothing; it builds the canvas.

const cells = Sprites.Reactive.Value([0, 1, undefined, 2]);
const pan = Sprites.Reactive.Value({ x: 1, y: 1 });
const show = Sprites.Reactive.Value(2.5);
Sprites.Media.Map.View(cells, 2, 2, pan, show, Sprites.Media.Map.Palette);
A tiny two by two map drawn on the canvas, one empty cell showing the checker.

Sprites.Media.Map.Tileset.Window Void

Sprites.Media.Map.Tileset.Window(visible, position, data, brush, palette)

The Tile set window: a resizable floating panel holding a grid of tile swatches over an Edit button. Clicking a swatch sets the brush; Edit will open the sprite picker to add a sprite to the set (a stand-in for now). Opened from the Draw window's tile swatch and the Tools window's Tile set button. Its parts are Tileset.Grid and Tileset.Swatch.

InputTypeDescription
visibleSprites.Reactive.ValueThe two-way show flag.
positionSprites.Reactive.ValueThe window's live rect.
dataSprites.Reactive.ValueThe map document, for its tile set.
brushSprites.Reactive.ValueThe two-way selected tile index.
paletteArrayThe swatch colours.

Returns nothing; it builds the window.

const data = Sprites.Reactive.Binding{ w: 1, h: 1, mode: 'Nametable', tileset: { tiles: [ { id: 'a' }, { id: 'b' }, { id: 'c' } ] }, layers: [ { tiles: [0], visible: true } ] });
const brush = Sprites.Reactive.Value(0);
const visible = Sprites.Reactive.Value(false);
const position = Sprites.Reactive.Value({ left: 40, top: 40, width: 220, height: 220 });
Sprites.Ui.Button.SetValue(visible, true, 'Open tile set');
Sprites.Ui.Dom.Text(' brush = ', brush);
Sprites.Media.Map.Tileset.Window(visible, position, data, brush, Sprites.Media.Map.Palette);
The button opens the window; pick a swatch and the brush follows.

Sprites.Media.Map.Layers.Window Void

Sprites.Media.Map.Layers.Window(visible, position, data, selectedLayer, layerIndex, width, height)

The Layers panel: a resizable floating panel with a scrolling list of layer cards over a row of buttons (Add, Clone, Up, Down, Delete). A card is a selectable label with a visible checkbox. Its parts are Layers.List, Layers.Card and Layers.Buttons.

InputTypeDescription
visibleSprites.Reactive.ValueThe two-way show flag.
positionSprites.Reactive.ValueThe window's live rect.
dataSprites.Reactive.ValueThe map document, for its layers.
selectedLayerSprites.Reactive.ValueThe two-way selected layer.
layerIndexSprites.Reactive.ValueThe clamped selected index.
width, heightSprites.Reactive.ValueThe map size, for new layers.

Returns nothing; it builds the window.

const data = Sprites.Reactive.Binding{ w: 2, h: 1, mode: 'Nametable', tileset: { tiles: [] }, layers: [ { tiles: [undefined, undefined], visible: true } ] });
const selectedLayer = Sprites.Reactive.Value(0);
const layerIndex = Sprites.Reactive.Value(0);
const width = Sprites.Media.Map.Width(data);
const height = Sprites.Media.Map.Height(data);
const visible = Sprites.Reactive.Value(false);
const position = Sprites.Reactive.Value({ left: 40, top: 40, width: 220, height: 240 });
Sprites.Ui.Button.SetValue(visible, true, 'Open layers');
const layers = Sprites.Object.Field(data, 'layers');
const layerCount = Sprites.Array.Length(layers);
Sprites.Ui.Dom.Text(' layers = ', layerCount);
Sprites.Media.Map.Layers.Window(visible, position, data, selectedLayer, layerIndex, width, height);
The button opens the layers panel; Add and Delete change the stack.

Sprites.Media.Map.Editor Void

Sprites.Media.Map.Editor(data, thumb, info, optionalModes, optionalModeName)

The map editor: the canvas view, the pan and zoom overlay, the Tools window, the Move and Draw tool windows, the Tile set and Layers windows, and the Info panel. It builds interface and returns nothing; the doc fields are where the edits land. It reuses the Move and Info windows of Sprites.Media.Sprite. The Tools window (Tool.Window), the tool selector (Tool.Selector) and the Draw window (Tool.Draw.Window) are its own.

InputTypeDescription
dataSprites.Reactive.ValueThe map document, two way.
thumbSprites.Reactive.ValueThe doc's preview value. Reserved.
infoSprites.Reactive.ValueSet to the mode and size summary on a paint.
optionalModesArrayThe platform's map modes, each { name, tiles, … }.
optionalModeNameSprites.Reactive.ValueThe doc's stored mode name, two way.

Returns nothing; it builds the whole editor into the host.

const document = Sprites.Media.Map.NewDocument(8, 8, 'Nametable');
const doc = Sprites.Reactive.Binding(document);
const info = Sprites.Reactive.Value('');
const thumb = Sprites.Reactive.Value(undefined);
const open = Sprites.Reactive.Value(false);
Sprites.Ui.Button.SetValue(open, true, 'Open the editor');
Sprites.Reactive.If(open, () => {
  Sprites.Ui.Dom.Tag('div', () => {
    Sprites.Ui.Dom.Style('height', '320px');
    const mode = Sprites.Object.Field(doc, 'mode');
    Sprites.Media.Map.Editor(doc, thumb, info, undefined, mode);
  });
});
The button builds the whole editor, so its windows appear only on request.

Sprites.Media.Map.MinSide Number

The smallest a side may be, in tiles. It is 1. ClampSide holds a side at or above it.

Value 1.

Sprites.Ui.Dom.Text('MinSide = ', Sprites.Media.Map.MinSide);
The smallest side, in tiles.

Sprites.Media.Map.MaxSide Number

The largest a side may be, in tiles. It is 1024, generous so a scrolling level far bigger than one screen is one document. ClampSide holds a side at or below it.

Value 1024.

Sprites.Ui.Dom.Text('MaxSide = ', Sprites.Media.Map.MaxSide);
The largest side, in tiles.

Sprites.Media.Map.Empty Value

The empty cell: an absent value, undefined. A cell holds this where no tile is placed, so the layer below shows through, and a resize writes it into new cells.

Value undefined.

const cell = Sprites.Reactive.Value(Sprites.Media.Map.Empty);
const isEmpty = Sprites.Logic.Equals(cell, Sprites.Media.Map.Empty);
Sprites.Ui.Dom.Text('cell is empty = ', isEmpty);
The absent cell, matched with Logic.Equals.

Sprites.Media.Map.DefaultTile Number

The tile a fresh brush places, the first tile of the set. It is 0.

Value 0.

const brush = Sprites.Reactive.Value(Sprites.Media.Map.DefaultTile);
Sprites.Ui.Dom.Text('default brush = ', brush);
The first tile, the fresh brush.

Sprites.Media.Map.Palette Array

The tile swatch palette: a spread of distinct colours a tile index is drawn in, as packed 0xRRGGBBAA integers. A cell of tile t shows the colour at t wrapped by the palette length, a stand-in until the tile set's referenced sprites are loaded and drawn.

Value sixteen packed colours.

Sprites.Reactive.Each(Sprites.Media.Map.Palette, (colour) => {
  const css = Sprites.Colour.Css(colour);
  Sprites.Ui.Dom.Tag('span', () => {
    Sprites.Ui.Dom.Style('display', 'inline-block');
    Sprites.Ui.Dom.Style('width', '1.4rem');
    Sprites.Ui.Dom.Style('height', '1.4rem');
    Sprites.Ui.Dom.Style('background', css);
  });
});
The sixteen swatch colours a tile index is keyed to.

Sprites.Media.Map.GridLineWidth Number

The width of the tile grid lines the view draws, in world units. One unit is one tile.

Value 0.04.

Sprites.Ui.Dom.Text('GridLineWidth = ', Sprites.Media.Map.GridLineWidth);
The grid line width, in world units.

Sprites.Media.Map.GridColour String

The colour of the tile grid lines the view draws, a faint black.

Value 'rgba(0, 0, 0, 0.25)'.

Sprites.Ui.Dom.Tag('span', () => {
  Sprites.Ui.Dom.Style('display', 'inline-block');
  Sprites.Ui.Dom.Style('width', '3rem');
  Sprites.Ui.Dom.Style('height', '1.4rem');
  Sprites.Ui.Dom.Style('background', Sprites.Media.Map.GridColour);
});
Sprites.Ui.Dom.Text(' ', Sprites.Media.Map.GridColour);
The grid line colour as a swatch.

Sprites.Media.Map.OutlineWidth Number

The width of the dark outline the view draws around the map, in world units.

Value 0.18.

Sprites.Ui.Dom.Text('OutlineWidth = ', Sprites.Media.Map.OutlineWidth);
The map outline width, in world units.

Sprites.Media.Map.OutlineColour String

The colour of the dark outline the view draws around the map.

Value '#020d02'.

Sprites.Ui.Dom.Tag('span', () => {
  Sprites.Ui.Dom.Style('display', 'inline-block');
  Sprites.Ui.Dom.Style('width', '3rem');
  Sprites.Ui.Dom.Style('height', '1.4rem');
  Sprites.Ui.Dom.Style('background', Sprites.Media.Map.OutlineColour);
});
Sprites.Ui.Dom.Text(' ', Sprites.Media.Map.OutlineColour);
The outline colour as a swatch.

Sprites.Media.Map.CursorWidth Number

The width of the Draw tool's cursor outline, drawn around the tile under the pointer, in world units.

Value 0.12.

Sprites.Ui.Dom.Text('CursorWidth = ', Sprites.Media.Map.CursorWidth);
The draw cursor width, in world units.

Sprites.Media.Map.CursorColour String

The colour of the Draw tool's cursor outline, a bright red.

Value '#ff3b30'.

Sprites.Ui.Dom.Tag('span', () => {
  Sprites.Ui.Dom.Style('display', 'inline-block');
  Sprites.Ui.Dom.Style('width', '3rem');
  Sprites.Ui.Dom.Style('height', '1.4rem');
  Sprites.Ui.Dom.Style('background', Sprites.Media.Map.CursorColour);
});
Sprites.Ui.Dom.Text(' ', Sprites.Media.Map.CursorColour);
The draw cursor colour as a swatch.

Sprites.Media.Map.TileColumn Sprites.Reactive.Value

Sprites.Media.Map.TileColumn(i, width)

The column of cell i on a grid of a width: i wrapped by the width. A companion the canvas uses to place a flat cell.

InputTypeDescription
iNumber or Sprites.Reactive.ValueThe flat cell index.
widthNumber or Sprites.Reactive.ValueThe grid width in tiles.

Returns a read-only Sprites.Reactive.Value holding the column.

const i = Sprites.Reactive.Value(5);
const col = Sprites.Media.Map.TileColumn(i, 4);
Sprites.Ui.Input.Number(i, 0, 15);
Sprites.Ui.Dom.Text(' column = ', col);
Cell index wrapped by the width gives the column.

Sprites.Media.Map.TileRow Sprites.Reactive.Value

Sprites.Media.Map.TileRow(i, width)

The row of cell i: i over the width, rounded down. A companion the canvas uses to place a flat cell.

InputTypeDescription
iNumber or Sprites.Reactive.ValueThe flat cell index.
widthNumber or Sprites.Reactive.ValueThe grid width in tiles.

Returns a read-only Sprites.Reactive.Value holding the row.

const i = Sprites.Reactive.Value(5);
const row = Sprites.Media.Map.TileRow(i, 4);
Sprites.Ui.Input.Number(i, 0, 15);
Sprites.Ui.Dom.Text(' row = ', row);
Cell index over the width, rounded down, gives the row.

Sprites.Media.Map.TileVisible Sprites.Reactive.Value

Sprites.Media.Map.TileVisible(cells, i)

True when cell i of the flattened grid holds a tile: its value is not the empty undefined. The canvas draws a square only where this is true.

InputTypeDescription
cellsArray or Sprites.Reactive.ValueThe flattened tile indices.
iNumber or Sprites.Reactive.ValueThe flat cell index.

Returns a read-only Sprites.Reactive.Value holding the boolean.

const cells = Sprites.Reactive.Value([0, undefined, 2]);
const i = Sprites.Reactive.Value(0);
const shown = Sprites.Media.Map.TileVisible(cells, i);
Sprites.Ui.Input.Number(i, 0, 2);
Sprites.Ui.Dom.Text(' holds a tile = ', shown);
Cell 1 is empty, so it reads false.

Sprites.Media.Map.Tiles Void

Sprites.Media.Map.Tiles(cells, width, palette)

The tiles: one filled square per placed cell of the flattened grid, in its index colour. A composite over Repeat and If, built inside a Vector by View. Builds drawing and returns nothing.

InputTypeDescription
cellsArray or Sprites.Reactive.ValueThe flattened tile indices.
widthNumber or Sprites.Reactive.ValueThe grid width in tiles.
paletteArrayThe swatch colours.

Returns nothing; it draws the placed cells.

const cells = Sprites.Reactive.Value([0, 1, undefined, 2]);
const pan = Sprites.Reactive.Value({ x: 1, y: 1 });
const show = Sprites.Reactive.Value(2.5);
Sprites.Ui.Image.Vector(pan, show, () => {
  Sprites.Media.Map.Tiles(cells, 2, Sprites.Media.Map.Palette);
});
One filled square per placed cell, in its index colour.

Sprites.Media.Map.Tileset.Swatch Void

Sprites.Media.Map.Tileset.Swatch(index, palette)

One tile swatch: a fixed square in the tile's index colour with its index shown, a stand-in until the referenced sprite is loaded and drawn. Builds interface and returns nothing.

InputTypeDescription
indexNumber or Sprites.Reactive.ValueThe tile index.
paletteArrayThe swatch colours.

Returns nothing; it builds one swatch.

const index = Sprites.Reactive.Value(3);
Sprites.Ui.Input.Number(index, 0, 15);
Sprites.Media.Map.Tileset.Swatch(index, Sprites.Media.Map.Palette);
A square in the index colour with its index shown.

Sprites.Media.Map.Tileset.Grid Void

Sprites.Media.Map.Tileset.Grid(data, brush, palette)

The grid of tile swatches: one selectable option per tile of the set, over the brush, so the picked tile darkens. An empty tile set shows a note. The body of the Tile set window. Builds interface and returns nothing.

InputTypeDescription
dataSprites.Reactive.ValueThe map document, for its tile set.
brushSprites.Reactive.ValueThe two-way selected tile index.
paletteArrayThe swatch colours.

Returns nothing; it builds the swatch grid.

const data = Sprites.Reactive.Binding{ w: 1, h: 1, mode: 'Nametable', tileset: { tiles: [ { id: 'a' }, { id: 'b' }, { id: 'c' } ] }, layers: [ { tiles: [0], visible: true } ] });
const brush = Sprites.Reactive.Value(0);
Sprites.Media.Map.Tileset.Grid(data, brush, Sprites.Media.Map.Palette);
Sprites.Ui.Dom.Text('brush = ', brush);
Pick a swatch and the brush follows.

Sprites.Media.Map.Layers.Card Void

Sprites.Media.Map.Layers.Card(data, layer, index)

One layer card: a selectable label over the frame's stack and a visible checkbox. The label is an Option so a click selects the layer the editor draws into; the checkbox is a two way flag written back through the layers list, so hiding a layer drops it from the flattened view. Builds interface and returns nothing.

InputTypeDescription
dataSprites.Reactive.ValueThe map document.
layerSprites.Reactive.ValueThe layer this card shows.
indexNumber or Sprites.Reactive.ValueThe layer's place in the stack.

Returns nothing; it builds one card.

const data = Sprites.Reactive.Binding{ w: 1, h: 1, mode: 'Nametable', tileset: { tiles: [] }, layers: [ { tiles: [0], visible: true } ] });
const selectedLayer = Sprites.Reactive.Value(0);
const layers = Sprites.Object.Field(data, 'layers');
const layer = Sprites.Array.At(layers, 0);
Sprites.Ui.Button.Select(selectedLayer, () => {
  Sprites.Media.Map.Layers.Card(data, layer, 0);
});
const visible = Sprites.Object.Field(layer, 'visible');
Sprites.Ui.Dom.Text('visible = ', visible);
A layer label with its visible checkbox.

Sprites.Media.Map.Layers.List Void

Sprites.Media.Map.Layers.List(data, selectedLayer)

The scrolling list of layer cards: a Select over the selected layer so one card darkens, an Each over the layers, and column-reverse so the top layer sits at the top of the list. Builds interface and returns nothing.

InputTypeDescription
dataSprites.Reactive.ValueThe map document, for its layers.
selectedLayerSprites.Reactive.ValueThe two-way selected layer.

Returns nothing; it builds the card list.

const data = Sprites.Reactive.Binding{ w: 1, h: 1, mode: 'Nametable', tileset: { tiles: [] }, layers: [ { tiles: [0], visible: true }, { tiles: [undefined], visible: true } ] });
const selectedLayer = Sprites.Reactive.Value(0);
Sprites.Media.Map.Layers.List(data, selectedLayer);
Sprites.Ui.Dom.Text('selected = ', selectedLayer);
Two cards, top layer at the top; click to select.

Sprites.Media.Map.Layers.Buttons Void

Sprites.Media.Map.Layers.Buttons(data, selectedLayer, layerIndex, width, height)

The layer buttons: Add and Clone a layer just above the selected one and select it, Up and Down swap the selected layer with its neighbour and follow it, and Delete removes it unless it is the last. Each composes a new layers list and Sets the document. Builds interface and returns nothing.

InputTypeDescription
dataSprites.Reactive.ValueThe map document.
selectedLayerSprites.Reactive.ValueThe two-way selected layer.
layerIndexSprites.Reactive.ValueThe clamped selected index.
width, heightSprites.Reactive.ValueThe map size, for new layers.

Returns nothing; it builds the button row.

const data = Sprites.Reactive.Binding{ w: 2, h: 1, mode: 'Nametable', tileset: { tiles: [] }, layers: [ { tiles: [undefined, undefined], visible: true } ] });
const selectedLayer = Sprites.Reactive.Value(0);
const layerIndex = Sprites.Reactive.Value(0);
const width = Sprites.Media.Map.Width(data);
const height = Sprites.Media.Map.Height(data);
Sprites.Media.Map.Layers.Buttons(data, selectedLayer, layerIndex, width, height);
const layers = Sprites.Object.Field(data, 'layers');
const layerCount = Sprites.Array.Length(layers);
Sprites.Ui.Dom.Text('layers = ', layerCount);
Add, Clone, Up, Down and Delete over the layer stack.

Sprites.Media.Map.Tool.Selector Void

Sprites.Media.Map.Tool.Selector(selectedToolName)

The canvas tool selector: Move pans and zooms, Draw paints. Picking sets selectedToolName. Builds interface and returns nothing.

InputTypeDescription
selectedToolNameSprites.Reactive.ValueThe two-way tool name, 'move' or 'draw'.

Returns nothing; it builds the tool buttons.

const selectedToolName = Sprites.Reactive.Value('draw');
Sprites.Media.Map.Tool.Selector(selectedToolName);
Sprites.Ui.Dom.Text('tool = ', selectedToolName);
Move and Draw; the pick sets the tool name.

Sprites.Media.Map.Tool.Windows Void

Sprites.Media.Map.Tool.Windows(tilesetVisible, layersVisible)

The Windows buttons: Tile set and Layers, each opening its window on a click by setting its flag true. A window carries its own close button, so these turn nothing off. Builds interface and returns nothing.

InputTypeDescription
tilesetVisibleSprites.Reactive.ValueThe Tile set window's show flag.
layersVisibleSprites.Reactive.ValueThe Layers window's show flag.

Returns nothing; it builds the two buttons.

const tilesetVisible = Sprites.Reactive.Value(false);
const layersVisible = Sprites.Reactive.Value(false);
Sprites.Media.Map.Tool.Windows(tilesetVisible, layersVisible);
Sprites.Ui.Dom.Text('tile set = ', tilesetVisible, ', layers = ', layersVisible);
Each button sets its window's flag true.

Sprites.Media.Map.Tool.Window Void

Sprites.Media.Map.Tool.Window(selectedToolName, tilesetVisible, layersVisible)

The Tools window: a slim floating window docked to the stage's top left, holding the tool selector over the Windows buttons. Always shown, no close button. Its parts are Tool.Selector and Tool.Windows. Builds interface and returns nothing.

InputTypeDescription
selectedToolNameSprites.Reactive.ValueThe two-way tool name.
tilesetVisibleSprites.Reactive.ValueThe Tile set window's show flag.
layersVisibleSprites.Reactive.ValueThe Layers window's show flag.

Returns nothing; it builds the Tools window.

const selectedToolName = Sprites.Reactive.Value('draw');
const tilesetVisible = Sprites.Reactive.Value(false);
const layersVisible = Sprites.Reactive.Value(false);
Sprites.Media.Map.Tool.Window(selectedToolName, tilesetVisible, layersVisible);
Sprites.Ui.Dom.Text('tool = ', selectedToolName);
The Tools window, the selector over the Windows buttons.

Sprites.Media.Map.Tool.Draw.Window Void

Sprites.Media.Map.Tool.Draw.Window(visible, position, selectedDrawMode, brush, tilesetVisible, palette)

The Draw tool's window: a Pencil and Eraser selector over the selected tile swatch. Clicking the swatch opens the Tile set window to pick another tile. Shown while the Draw tool is selected, no close button. Builds interface and returns nothing.

InputTypeDescription
visibleSprites.Reactive.ValueShown while true, the Draw tool active.
positionSprites.Reactive.ValueThe window's live rect.
selectedDrawModeSprites.Reactive.ValueThe two-way mode, 'pencil' or 'eraser'.
brushSprites.Reactive.ValueThe selected tile index, shown as the swatch.
tilesetVisibleSprites.Reactive.ValueThe Tile set window's show flag.
paletteArrayThe swatch colours.

Returns nothing; it builds the Draw window.

const visible = Sprites.Reactive.Value(true);
const position = Sprites.Reactive.Value({ left: 12, top: 12 });
const selectedDrawMode = Sprites.Reactive.Value('pencil');
const brush = Sprites.Reactive.Value(3);
const tilesetVisible = Sprites.Reactive.Value(false);
Sprites.Media.Map.Tool.Draw.Window(visible, position, selectedDrawMode, brush, tilesetVisible, Sprites.Media.Map.Palette);
Sprites.Ui.Dom.Text('mode = ', selectedDrawMode);
Pencil and Eraser over the brush swatch.

Sprites.Media.Map.Tool.Draw.Cursor Void

Sprites.Media.Map.Tool.Draw.Cursor(active, over, at)

The draw cursor: a square outline around the tile under the pointer, shown while the Draw tool is active and the pointer is over the map. Built as the view's overlay. Builds drawing and returns nothing.

InputTypeDescription
activeSprites.Reactive.ValueTrue while the Draw tool paints.
overSprites.Reactive.ValueTrue while the pointer is over the map.
atSprites.Reactive.ValueThe pointer point, { x, y } in world units.

Returns nothing; it draws the cursor outline.

const cells = Sprites.Reactive.Value([0, 1, 2, 3]);
const pan = Sprites.Reactive.Value({ x: 1, y: 1 });
const show = Sprites.Reactive.Value(2.5);
const over = Sprites.Reactive.Value(true);
const at = Sprites.Reactive.Value({ x: 0.5, y: 0.5 });
Sprites.Media.Map.View(cells, 2, 2, pan, show, Sprites.Media.Map.Palette, () => {
  return Sprites.Media.Map.Tool.Draw.Cursor(true, over, at);
});
A red outline around the tile at the pointer.