diff infinite_canvas/README.md @ 276:b55c22cff335

Add interactive infinite canvas prototype
author MrJuneJune <me@mrjunejune.com>
date Mon, 17 Aug 2026 16:57:56 -0700
parents
children 8d560f50ed4c
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/infinite_canvas/README.md	Mon Aug 17 16:57:56 2026 -0700
@@ -0,0 +1,108 @@
+# 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: 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 blue pin badge
+- Development toolbar: spawn/clear entities, reset the camera, or restore the
+  deterministic demo scene
+- `View camera context`: open a live, scrollable snapshot of entities
+  intersecting the camera viewport and their current semantic values
+- `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 have no simulated browser toolbar: drag their narrow outer edge to move
+them and drag the bottom-right handle to resize them. 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.
+
+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,
+Enter, and Backspace. Dragging still moves every primitive.
+
+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.
+
+## 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.