Mercurial
comparison infinite_canvas/docs/rendering.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 | |
| children |
comparison
equal
deleted
inserted
replaced
| 277:1d99147f520c | 278:8d560f50ed4c |
|---|---|
| 1 # Rendering Surfaces | |
| 2 | |
| 3 ## Choose the renderer by content | |
| 4 | |
| 5 | Content | Entity type | Native | WebAssembly | | |
| 6 | --- | --- | --- | --- | | |
| 7 | Shapes, text, controls | regular `CANVAS_ENTITY_*` | Raylib | Raylib/WASM | | |
| 8 | Lucide icons | `CANVAS_ENTITY_LUCIDE_GALLERY` | Raylib line segments | Raylib/WASM line segments | | |
| 9 | Image URL or file | `CANVAS_ENTITY_IMAGE` | CEF off-screen pixels uploaded to a Raylib texture | positioned `<img>` overlay | | |
| 10 | Live web page | `CANVAS_ENTITY_WEB_CONTENT` | CEF off-screen pixels uploaded to a Raylib texture | positioned `<iframe>` overlay | | |
| 11 | |
| 12 Do not route vector icons or ordinary components through CEF. They belong in | |
| 13 `Canvas_Draw_Entity()` so they inherit camera transforms, theme colors, | |
| 14 selection, dragging, pinning, and context behavior without another rendering | |
| 15 runtime. | |
| 16 | |
| 17 ## Raylib entities | |
| 18 | |
| 19 `Canvas_Draw_World()` opens one `BeginMode2D()` camera and draws every retained | |
| 20 entity through `Canvas_Draw_Entity()`. Components such as buttons, dropdowns, | |
| 21 cards, calendars, tables, and switches are immediate Raylib draw calls backed | |
| 22 by state in `Canvas_Entity`. | |
| 23 | |
| 24 The scene-array order is the z-order. The main frame interleaves each Raylib | |
| 25 entity layer with its native CEF/image texture, so a later button can genuinely | |
| 26 draw over and receive input ahead of an earlier browser surface. Picking and | |
| 27 native browser input both resolve the same reverse scene order. | |
| 28 | |
| 29 The Lucide gallery follows the same path. The generator | |
| 30 `tools/generate_lucide_data.mjs` downloads pinned Lucide 1.31.0 definitions, | |
| 31 flattens SVG paths and primitives into line segments, and writes | |
| 32 `generated/lucide_data.h`. The gallery virtualizes rows: only cards fully inside | |
| 33 its visible body issue Raylib draw calls. Its Raylib search field filters icon | |
| 34 names case-insensitively and resets the internal scroll offset when edited. | |
| 35 | |
| 36 Regenerate after changing the pinned icon version: | |
| 37 | |
| 38 ```bash | |
| 39 node infinite_canvas/tools/generate_lucide_data.mjs | |
| 40 ``` | |
| 41 | |
| 42 ## Native image and web surfaces | |
| 43 | |
| 44 `web_surface_native.cc` maintains a pool of at most `CANVAS_MAX_WEB_VIEWS` | |
| 45 off-screen CEF browsers. Visible image and web entities are reconciled by stable | |
| 46 entity ID. CEF paint callbacks fill arena-owned RGBA buffers; `Sync()` creates or | |
| 47 updates Raylib textures; `Draw()` composites those textures into the | |
| 48 camera-derived screen bounds. | |
| 49 | |
| 50 Resolution follows displayed size in stable buckets and is capped. Off-screen | |
| 51 entities release their active pool slot, small background views receive lower | |
| 52 frame rates, and the focused view receives the largest frame budget. | |
| 53 | |
| 54 When a web entity is selected, C reserves a fixed-screen-height toolbar above | |
| 55 the page viewport. The reserved height and toolbar clip animate together so | |
| 56 selection pushes the page down like an opening accordion and deselection pulls | |
| 57 it back up. Raylib draws the themed editable address field and Lucide | |
| 58 navigation icons after that entity's CEF texture, preserving scene z-order. | |
| 59 The URL editor retains its own draft, caret, selection, horizontal scroll, and | |
| 60 clipboard focus; committing updates the entity URL, which triggers backend | |
| 61 navigation. CEF reports main-frame address changes and history availability | |
| 62 back to the toolbar. | |
| 63 CEF emulates the canvas `prefers-color-scheme` value and updates the page | |
| 64 `color-scheme` when the canvas theme changes. | |
| 65 | |
| 66 Images use a bundled `image-view.html` wrapper for `object-fit: contain`. | |
| 67 Filesystem paths are resolved to `file://`; URLs remain URLs. | |
| 68 | |
| 69 ## WebAssembly image and web surfaces | |
| 70 | |
| 71 `web_surface_web.c` cannot composite cross-origin page pixels into WebGL, so it | |
| 72 positions DOM overlays over the Raylib canvas. It creates `<img>` elements for | |
| 73 images and sandboxed `<iframe>` elements for live pages, converts Raylib screen | |
| 74 coordinates to CSS coordinates, and removes overlays that are no longer | |
| 75 visible. | |
| 76 | |
| 77 Selected iframe entities use the same Raylib toolbar geometry and move the DOM | |
| 78 viewport below it. The iframe element receives the canvas `color-scheme`. | |
| 79 History navigation is best-effort because cross-origin iframe history and | |
| 80 address inspection remain browser-controlled; the displayed URL falls back to | |
| 81 the entity's configured URL. | |
| 82 | |
| 83 This is intentionally different from native. Shared scene semantics live in C; | |
| 84 the platform backend owns only presentation and input details. |