Realtime canvasPro
Draw on the left and watch the model answer on the right as you draw: frames sent on change at a capped rate, images swapped without flicker, end to end latency with the last 24 frames, connection states, pause and save frame.
On this page
ProDraw on the left and the right answers as you draw, with end to end latency. The model is simulated in the browser as a clay render over a fake network.
Installation
Usage
import { RealtimeCanvas } from "@/components/ui/chatcn/pro/realtime-canvas"
<RealtimeCanvas
status={client.status}
output={latest}
onFrame={async (frame) => {
const image = await client.send(await frame.toBlob(), frame.prompt, frame.strength)
setLatest({ frameId: frame.id, src: image.url })
}}
onRetry={client.reconnect}
/>Bring any realtime client. The canvas sends a frame whenever the sketch, prompt or strength changes, at most maxFps times a second (the first change at once, the last always), and shows whatever you hand back on output. Tag each output with the frameId it answers: the latency readout is measured end to end from that, older answers than the one on screen are ignored, and decoding happens off screen so frames swap without flicker. The demo's model is simulated in the browser.
Examples
States
ProConnecting, a slow connection in amber, paused on the last frame, a dropped connection with Reconnect and disabled.
Props
| Prop | Type | Notes |
|---|---|---|
status | "connecting" | "live" | "reconnecting" | "error" | From your client. Default live |
error, onRetry | string, () => void | Say how to fix it; Reconnect calls onRetry |
onFrame | ({ id, canvas, prompt, strength, toDataURL, toBlob }) => void | The sketch at frameWidth, ink on white |
output | { frameId, src?, image? } | A URL, or an image, bitmap or canvas already decoded |
latencyMs | number | Use your client's own measure instead |
maxFps, frameWidth | number | Default 12 and 512 px |
prompt, defaultPrompt, onPromptChange | string | Changes send a frame |
strength, defaultStrength, onStrengthChange | number | How closely to follow the sketch, 0 to 1. Default 0.7 |
paused, defaultPaused, onPausedChange | boolean | Stops sending; the last image stays |
onSaveFrame | (blob: Blob) => void | Shows Save frame |
slowAfterMs | number | Latency above it reads amber. Default 400 |
aspectRatio, sketchProps, disabled | Both panes' shape, the sketch pad's props, lock |
Keyboard
| Key | Action |
|---|---|
| Sketch pad keys | B, X, R, C, F, 1 to 9, [, ], undo and redo |
Tab | Prompt, Follow sketch, Pause and Save frame |
Accessibility
- The output is an image named by the prompt. Connection changes are announced politely; frames and latency are not, so a screen reader is never flooded.
- Status pairs a dot with a word (Live, Paused, Off, Connecting, Disconnected); a slow connection turns the latency amber and its bars stand out, never color alone.
- Follow sketch is a slider that announces a percentage.
Motion
- Frames swap in one paint with no fade: a fade would make the image lag the sketch. Only the first frame fades in, 200 ms.
- Updating shows only when an answer is more than 600 ms late. Connecting shows after 300 ms and stays at least 400 ms.