# RCWeb Whiteboard App

The **RCWeb Whiteboard App** (`app/whiteboard`) is a full-featured collaborative drawing canvas. Implementing the **Symmetric Pattern**, it synchronizes drawing tools, shapes, native text, and embedded images across all distributed users natively via WebSockets.

![icon](pwa-512x512.png "Whiteboard App Icon")

## Screenshot
![screenshot](screenshot.png "Whiteboard App")

## What it does

- **Live Vector Syncing**: Everything drawn—whether a freehand pen path, text block, arrow, or geometric shape—is constructed mathematically and synchronized endlessly to all users simultaneously.
- **Complete Editing Control**: Users can click directly on existing shapes or paths to edit them. Allows resizing, color swaps, stroke updates, text rewriting, and delete selections across clients.
- **Infinite Panning & Zooming**: Users can navigate the limitless canvas using middle-mouse drags or mobile multi-touch pinch commands independent of the other users.
- **Live Cursors**: Translates user mouse or touch actions into localized live pointers so participants can physically track where others are inspecting or drawing.
- **Image Stamping**: Users can drag and drop images directly into the Whiteboard interface, transferring the binary data peer-to-peer and permanently burning it into the canvas history stack.

## How it works

The engine in `script.js` converts an HTML5 Canvas into a complex scene-graph architecture synchronized instantly through WebSockets.

- **Scene Graph State**: Elements are given completely unique cryptographic IDs (`generateId()`) and stored in a shared `elements{}` ledger and stacked via a sequential `zIndexOrder[]` pipeline.
- **Reconciliation & Batching**: When shapes are modified or added, local state is immediately reconciled optimistically. Network pushes are aggressively batched via a temporal `setInterval(..., 100)` looping mechanism executing strings of queued `whiteboard.[commands]` remotely to dodge rate-limiting errors from flooding events.
- **Input Geometry Engine**: A vast array of event listeners (`onPointerDown`, `onTouchMove`, `onWheel`) translates screen coordinate matrices into virtual `camera` spaces utilizing affine transformations (`screenToWorld`, `worldToScreen`). The UI dynamically transforms CSS cursor stylings contextualized to whether a bounding box is hit (`getResizeHandleAt()`).
- **Symmetric Image Transfers**: Inherited from the Files applications, dropped image blobs enact proxy routes (`/x-file/`). Images are uploaded to peers incrementally using `rc.sendFileChunk` and fetched into cached native `Image()` objects rendered continually on the canvas loop.
