Recipe: Multiplayer Canvas
Audience: users.
Goal: build a live canvas where strokes are broadcast instantly and persisted for late joiners.
Pattern
Section titled “Pattern”events: immediate stroke broadcast for low-latency renderingstate: persistent stroke historycursors: collaborator pointer visibility
Example (Planned API)
Section titled “Example (Planned API)”const room = createRoom(`canvas-${canvasId}`, { presence: { name: user.name, color: user.color },});
await room.connect();
const events = room.useEvents();const state = room.useState({ initialValue: { strokes: [] as Stroke[] }, strategy: 'crdt',});
events.on<Stroke>('stroke', (stroke) => { drawStroke(stroke);});
canvas.addEventListener('mouseup', () => { const stroke = captureStroke(); events.emit('stroke', stroke); state.patch({ strokes: [...state.get().strokes, stroke] });});- Keep stroke payload compact.
- Consider chunking for very long paths.
- Use relay mode for larger live sessions.