
NodyxCanvas — la feature qui m'a le plus excité à coder
L'idée : quand tu parles avec des gens dans un salon vocal, tu peux ouvrir une surface de dessin partagée. Tout le monde dessine, voit les curseurs des autres, synchronisé en temps réel — P2P, sans serveur.
CRDT LWWDataChannelsPNG Export
Le modèle CRDT — Last-Write-Wins par élément
Chaque tracé, sticky note ou forme est un CanvasElement avec un UUID et un timestamp. La règle de merge est simple :
type CanvasElement = {
id: string // UUID v4
ts: number // Date.now() — LWW : le plus grand gagne
author: string // userId
kind: 'path' | 'sticky' | 'rect' | 'circle'
data: PathData | StickyData | ShapeData
deleted?: boolean // soft delete pour l'effaceur
}
// Règle d'application
function apply(op: CanvasElement): boolean {
const existing = elements.get(op.id)
if (existing && existing.ts >= op.ts) return false // discard
elements.set(op.id, op)
return true // state changed → redraw
}Curseurs distants
Chaque
pointermove→ broadcastcanvas:cursor(throttle 50ms)Fade-out automatique après 3 secondes sans update
Halo violet
nodyx-pulsequand le peer parle (VAD actif)
Fin de session
Quand tu fermes le canvas avec des éléments : "Garder la table ?"
📥 Télécharger PNG —
canvas.toBlob('image/png')→ download📋 Résumé dans le chat —
socket.emit('chat:send', { content: '📋 Table de travail — N éléments...' })✕ Jeter — ferme sans trace
Session éphémère par défaut, mais avec une porte de sortie. Zéro backend. Zéro stockage.