Mercurial
view infinite_canvas/README.md @ 278:8d560f50ed4c
Improve infinite canvas interactions and browser chrome
Render Lucide icons directly with Raylib, add searchable icon browsing, robust text editing, entity lifecycle animations, z-order-safe input, semantic themes, and animated editable browser controls. Document rendering, pinning, context, and component extension for future agents.
Co-authored-by: Copilot <[email protected]>
Copilot-Session: f68442b1-fa8f-46a0-9689-81710613bbd4
| author | MrJuneJune <me@mrjunejune.com> |
|---|---|
| date | Mon, 17 Aug 2026 22:16:14 -0700 |
| parents | b55c22cff335 |
| children | 49e9e591c9bb |
line wrap: on
line source
# Infinite Canvas Native and WebAssembly Raylib 6 prototype for a world-space, immediate-mode infinite canvas. ## Build and run ```bash # Native development build with Raygui controls bazel run //infinite_canvas:dev # Start directly in the ten-browser stress scene INFINITE_CANVAS_BROWSER_STRESS=1 bazel run //infinite_canvas:dev # Native build without development UI bazel run //infinite_canvas:app # Browser build and local server bazel build //infinite_canvas:infinite_canvas_wasm bazel run //infinite_canvas:serve ``` Open `http://127.0.0.1:4343/index.html` after starting the server. Pass a different port as an argument only when needed. The native development target opens at 1920x1200 and starts with a gallery layout containing one non-overlapping example of every entity type. Theme mode defaults to `auto`, which follows the OS light/dark preference at startup. Rendering consumes a shared semantic `Canvas_Theme` palette for the canvas, developer controls, and camera-pinned notifications. Until the planned config file lands, `INFINITE_CANVAS_THEME=light|dark|auto` provides an explicit override. The developer panel also includes a live light/dark mode toggle. ## Controls - Middle-mouse drag, or Space + left-mouse drag: pan - Mouse wheel: scroll vertically - Ctrl/Cmd + mouse wheel: zoom around the cursor - WASD or arrow keys: pan (disabled while a text area has keyboard focus) - Left-mouse drag on an entity: select and move it - `P`: pin or unpin the selected entity in screen space so it remains visible while the camera pans and zooms; pinned entities show a Lucide pin glyph - `Delete`/`Backspace`: fade out and remove the selected entity - Development toolbar: spawn/clear entities, reset the camera, or restore the deterministic demo scene; spawned entities fade in and Clear fades all entities out before removal - `View camera context`: open a live, scrollable snapshot of entities intersecting the camera viewport and their current semantic values - `Lucide icon gallery`: create or revisit a dedicated canvas region containing the complete searchable, scrollable Lucide 1.31.0 icon set and fit the camera to it - `10 browser stress scene`: lay out ten compact independent browser views for performance testing - `White`/`Grid`: toggle the optional grid; the default canvas is pure white Canvas primitives include shapes, lines, text, buttons, editable text areas, dropdowns, accordions, cards, calendars, switches, tables, notifications, scrollable areas, images, and web content. Accordions expand with eased height, chevron, divider, and content transitions; cards toggle emphasis, calendars select dates, and switches animate their track color and thumb position when toggled. The default browser build embeds `https://mrjunejune.com` in a camera-tracked iframe. Native builds open `https://www.google.com` in a CEF off-screen browser whose pixel buffer is uploaded into a Raylib texture. It remains inside the canvas and participates in pan, zoom, clipping, and entity dragging on Windows, macOS, and Linux. Web views show a Raylib-rendered Lucide back/forward toolbar and current URL only while selected. The toolbar eases open by pushing the page viewport downward and reverses the transition when deselected. Click the URL field to edit it; Enter navigates, Escape cancels, and standard Ctrl/Cmd clipboard and selection shortcuts work. Drag the remaining outer edge to move the view and drag the bottom-right handle to resize it. Embedded pages inherit the selected canvas light or dark color scheme where the browser backend supports it. Multiple web entities have independent browser instances, URLs, focus, input, and rendering. Browser resources are assigned only to visible entities, off-screen views are suspended, and the native CEF pool supports up to twelve live browsers. Small background views render at a reduced frame rate, larger views receive a moderate frame budget, and the focused view runs at 30 FPS so scenes with ten compact browsers remain responsive without giving every page the maximum rendering budget. Native browser viewport and texture resolution follow the displayed view size in 64-pixel buckets, capped at 1280x800, so resized views become sharper without reallocating continuously during a drag. The Lucide gallery is one scalable Raylib-rendered canvas entity rather than thousands of individual scene entities or an embedded browser. Reopening it reuses the existing entity and moves the camera back to its fitted bounds. Its ISC-licensed vector data is generated from Lucide 1.31.0 and the visible grid rows are drawn directly with Raylib primitives. Tables support row selection, and notifications behave as bottom-right toast cards: multiple toasts overlap compactly, fan into a spaced stack on hover, and slide/fade away from either Undo or close. Position, size, stack expansion, and dismissal all use eased frame-rate-independent transitions. Scrollable areas consume the mouse wheel without zooming the camera. Image entities render HTTPS URLs or native filesystem paths through CEF; browser builds render URLs or paths available in the Emscripten filesystem. Override the demo image in native development with `INFINITE_CANVAS_IMAGE_SOURCE=/path/to/image.png`. The first native build downloads the platform CEF 151 minimal distribution. Linux stages its runtime once under `~/.cache/zenbu/infinite-canvas/cef-151`; application state and the RGBA paint buffer remain owned by the Dowa arena, while CEF owns its browser internals. Buttons animate on hover/press and toggle when clicked. Dropdowns open a real option menu with hover and selection states. Selected text areas accept typing, wrap text, support click/drag selection and scrolling, and provide Ctrl/Cmd+A/C/X/V clipboard shortcuts plus Shift selection, word navigation, Home/End, Backspace, and Delete. Drag a text area's narrow outer padding to move it without changing the selection. Camera context is derived from the visible world rather than a hidden conversation store. Panning entities outside the viewport removes them; zooming out includes and concatenates newly visible entities. Each entry contains identity, type, placement, pin state, and type-specific state such as text content, dropdown selection, switch value, selected calendar date or table row, scroll position, image source, and browser URL. The current text format is intentionally provisional so it can later be replaced by the final API contract. The prototype uses the Inter variable font under the SIL Open Font License. Agent-oriented architecture and extension notes live in [`docs/README.md`](docs/README.md). ## Memory ownership The application creates one Dowa arena. Application state and the fixed-capacity entity array are arena-owned, there are no per-frame first-party allocations, and the arena is released once during native shutdown. Browser lifetime memory is reclaimed with the WebAssembly runtime when the page closes.