@mocanvas/wasm 4.13.0 → 4.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/ARCHITECTURE.md CHANGED
@@ -233,9 +233,13 @@ engine.selection_bounds(ptr_handles, len) -> ptr to 4 f32
233
233
  level-of-detail quads until a later frame reaches them.
234
234
  4. Append transformed vertices into the frame vertex buffer, batching by
235
235
  texture. Shapes flagged `OVERLAY` skip the mesh and go into the overlay list.
236
- 5. TS uploads the buffers (unless the engine reports them unchanged) and draws. Overlay list is diffed against the React
237
- overlay layer, which positions DOM shapes with `transform` and passes
238
- pointer events through except when editing.
236
+ 5. TS uploads the buffers (unless the engine reports them unchanged) and draws. The overlay list
237
+ gains the shapes that left the viewport recently (a bounded LRU,
238
+ `options.overlayRetainLimit`) and is diffed against the React overlay layer,
239
+ which positions DOM shapes with `transform`, hides the retained ones with
240
+ `content-visibility: hidden`, and passes pointer events through except when
241
+ editing. The camera is a transform on the layer, written by a signal
242
+ reaction: a pan or zoom frame is no React render at all.
239
243
 
240
244
  Stroke widths are in page units and scale with zoom, so meshes never need
241
245
  retessellation while zooming. Dash patterns (`dash` style word: 0 solid,
package/COMPAT.md CHANGED
@@ -98,7 +98,10 @@ work is**, not in the symbol tables above.
98
98
 
99
99
  `canCull` is absent from the class but honoured where it matters: a util that
100
100
  implements it and returns `false` keeps its shape in the DOM overlay while the
101
- shape is off screen (4.12.4), and out of `getCulledShapes()`.
101
+ shape is off screen (4.12.4), and out of `getCulledShapes()`. Every other overlay
102
+ shape that leaves the viewport stays mounted but hidden until
103
+ `options.overlayRetainLimit` newer ones displace it; the option is mocanvas's
104
+ own.
102
105
 
103
106
  You can measure a real application against this surface rather than trusting the
104
107
  tables: `scripts/compat-parity.mjs` type-checks a consumer app with `tldraw`
package/CUSTOM_SHAPES.md CHANGED
@@ -197,6 +197,40 @@ geometry bounds, with `pointerEvents: "none"` unless the shape is being edited.
197
197
  Render in shape-local space starting at `(0, 0)`; do not apply the camera or
198
198
  the shape transform yourself.
199
199
 
200
+ **When it re-renders.** The body is a function of the shape's `props` and
201
+ `meta`: it re-renders when either changes, and when a signal it read during its
202
+ last render changes (`useValue`, `editor.get*`). Moving, rotating or fading the
203
+ shape changes only the wrapper's transform and opacity, so a body that reads
204
+ `shape.x`, `shape.y`, `shape.rotation` or `shape.opacity` sees the value from its
205
+ last render. Read the position through a signal if you need it.
206
+ A pan or zoom re-renders nothing: the camera is a transform on the overlay layer.
207
+
208
+ **Off screen.** A body is mounted while its shape is on screen. When the shape
209
+ leaves the viewport it stays mounted, hidden with `content-visibility: hidden`,
210
+ until `options.overlayRetainLimit` (default 256) more recently culled shapes
211
+ push it out; coming back on screen then costs a style change, not a remount.
212
+ `0` unmounts at the viewport edge. A util whose `canCull()` returns `false` is
213
+ never unmounted and never hidden for being off screen.
214
+
215
+ **The zoom in your CSS.** `--mocanvas-zoom` and `--mocanvas-scale` are live on
216
+ the canvas container, but the overlay declares them as constants so that a zoom
217
+ does not restyle every node of every mounted shape — the single largest cost of
218
+ a zoom gesture on a board of DOM cards. A shape whose own CSS reads them says so:
219
+
220
+ ```ts
221
+ class CardUtil extends BaseBoxShapeUtil<CardShape> {
222
+ override usesCameraCssVars() {
223
+ return true // this card counter-scales its label
224
+ }
225
+ }
226
+ ```
227
+
228
+ That shape then gets the live values on its own wrapper, and its subtree is the
229
+ only one that restyles on a zoom. `options.overlayCameraCssVars: "inherit"`
230
+ turns the mechanism off altogether, for an app that would rather pay than name
231
+ its shapes. Everything outside the overlay — your own chrome, panels, menus —
232
+ reads the live values as before.
233
+
200
234
  ### `getIndicatorPath` — the selection outline
201
235
 
202
236
  ```ts
package/MIGRATION.md CHANGED
@@ -273,7 +273,7 @@ it. Two groups are worth knowing about:
273
273
 
274
274
  | tldraw token | What you get |
275
275
  | --- | --- |
276
- | `--tl-zoom`, `--tl-scale` | Real values. mocanvas now stamps `--mocanvas-zoom` and `--mocanvas-scale` on the canvas container and restamps them on zoom, so `calc()` rules that hold a constant on-screen size keep working. |
276
+ | `--tl-zoom`, `--tl-scale` | Real values. mocanvas stamps `--mocanvas-zoom` and `--mocanvas-scale` on the canvas container and restamps them on zoom, so `calc()` rules that hold a constant on-screen size keep working. Inside the DOM overlay they are constants unless the shape's util says `usesCameraCssVars()` — a tldraw shape whose CSS counter-scales with `--tl-scale` needs that line, or `options.overlayCameraCssVars: "inherit"`. |
277
277
  | `--tl-color-overlay`, `--tl-color-background-overlay`, `--tl-color-warn` | A static fallback. mocanvas has no equivalent, so these do not follow your theme — set them yourself if they matter. |
278
278
 
279
279
  Everything else maps onto a themed mocanvas variable and follows a theme swap
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mocanvas/wasm",
3
- "version": "4.13.0",
3
+ "version": "4.15.0",
4
4
  "description": "Typed loader and zero-copy bridge over the mocanvas Rust/WebAssembly engine.",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "author": "Symbio Digital",