--- id: task-7 title: Real-time presence cursors status: Done assignee: [] created_date: '2026-01-02 16:08' updated_date: '2026-01-02 19:30' labels: - feature - collaboration - sync dependencies: [] priority: medium --- ## Description Show other users cursors and selections in real-time: - Broadcast cursor position via WebSocket presence messages - Display colored cursor with username label - Show selection highlight when user has shape selected - Fade out cursors after inactivity - Different cursor colors per user WebSocket already handles presence messages (see server/index.ts line 221-235), needs client-side rendering. ## Acceptance Criteria - [x] #1 Cursor position broadcasts on mousemove - [x] #2 Other users cursors visible with name labels - [x] #3 Selection state shared between users - [x] #4 Cursors fade after 5s inactivity ## Notes ### Implementation Complete **PresenceManager class** (`lib/presence.ts`): - Tracks remote users with cursor position, selection, username, color - Renders SVG cursor pointer with username label - 8 distinct colors assigned based on peer ID hash - Selection highlight shows which shape each user has selected - Auto-fade after 5 seconds of inactivity (opacity: 0.3) - Auto-remove after 15 seconds of inactivity - Helper function `generatePeerId()` creates unique peer IDs **CommunitySync integration** (`lib/community-sync.ts`): - Added `sendPresence()` method for broadcasting cursor/selection - Presence messages relayed through server to all clients **Canvas integration** (`website/canvas.html`): - Mousemove handler sends throttled presence updates (50ms) - Touch handler for mobile cursor position - Presence event handler updates remote cursor display - Username persisted in localStorage **Technical details**: - Cursor updates throttled to max 20/second - Position relative to canvas, not window - Peer IDs are 8-char UUIDs for uniqueness - Selection highlight uses outline with peer color