Canvas
The infinite canvas is a board without edges for planning, mapping and drawing together: sticky notes, shapes, text, images, frames and connectors that follow what they join. Pan and zoom with a mouse, a trackpad, a finger or the keyboard; drag, resize, turn, line things up, type straight onto the board, draw with a pen or a highlighter, vote on ideas, start from a template, undo anything.
It stays fast however big the board grows. Everything is indexed by where it sits and only what is in view is built; zoomed far out, the board is painted instead, so ten thousand items pan and zoom as smoothly as ten.
It is built for multiplayer. The drawing is kept apart from the data: every change comes out as a few lines of JSON for your server, socket or peer connection to pass on, and the other copies apply it and agree, whatever order the changes arrive in. Other people's cursors and selections are drawn for you. There is no server of ours in the loop, and nothing leaves the page unless you send it.
A planning board
A product launch laid out in three frames, with the flow of the work drawn between them. Drag a note, or a frame by its title to carry everything in it. Double-click the board for a new note, or pick a tool on the left. Hover over a note and drag from one of its dots to another item to connect them — or to empty space, for a new note joined to the first. Select something to recolour it, change a shape, restack, lock or vote on it, or turn it by the round handle above it (or with the full stop and comma keys); select several to group them or line them up. The pen draws by hand, the laser points without leaving a mark, and the templates button starts a retrospective, a kanban board, a SWOT analysis, a flowchart or a mind map. Drop a picture from your computer onto the board.
One tag, data in and events out. Give the board its items as nodes and
edges — plain objects, or JSON in the markup — and read it back with
await board.getSnapshot(). Notes, shapes, text, images, frames and connectors are all the
same shape of object: an id, a type, a box, and what to write in it.
Two people, one board
Two canvases on this page, joined through a pretend network that delays every message and delivers them out of order. Move, type or delete on either side and watch it reach the other; point at the board and a named cursor follows on the other side, with a coloured outline round what you have selected. Pick the laser (L) and press to point something out. Turn on the slow network to see both copies still end up the same, and let Bob follow Alice to see his view go wherever hers does.
Wiring it to your own server. Send what bmxCanvasStateChange gives you and
hand what arrives to applyRemote():
board.addEventListener('bmxCanvasStateChange', e => socket.send(JSON.stringify(e.detail.ops)))
and socket.onmessage = m => board.applyRemote(JSON.parse(m.data)). Every change carries a
clock and the id of the copy that made it, and each field keeps the latest; so two people moving the
same note see it land in the same place, and one recolouring it while the other types in it keeps both.
bmxNodeMove streams a drag while it happens, bmxCursorMove the pointer, and
getSyncState() brings someone who joins late up to date.
Open this page in a second tab
This board is shared with every other tab or window of this page in your browser, through nothing but
the browser: one attribute, channel. Open the page again beside this one and work on both.
Each tab sees the others' changes, cursors, selections and laser, a tab opened later catches up with
what is already there, and you can follow another tab's view.
Across machines, a relay is enough. board.joinRoom(transport) takes anything
with send(text) and subscribe(listener) — a WebSocket to a relay that
passes each message to everyone else in the room is a few lines of server code that knows nothing about
boards and keeps nothing. The canvas does the rest: changes, drags, cursors, selections, views, and
bringing a late joiner up to date.
Your own HTML on the board
A node of type html shows whatever element of the page carries its slot name — a
chart, a form, a video, a component from any framework — and it moves and zooms with the board.
Its buttons and fields work as they would anywhere else; drag it by any part that is not a control.
Ten thousand items
Press the button to fill a board with ten thousand notes and shapes and nearly as many connectors, then take the tour: a zoom from a single note out to the whole board and back, with the frame rate counted as it goes. Close in, the notes in view are real, sharp and editable; far out, the board is painted, and the paint is reused while it pans.