Repository navigation
Releases
0.4.4
A cleaner inside, same API. Every export, option and type is the same as 0.4.3, and rendering is pixel for pixel the same.
- The GPU and DOM backends now share one base for the surface, nodes, camera, input and queries, instead of two copies.
- One geometry module, one packing routine for pages and the atlas, and snapshot capture in its own file.
- Comments that only repeated the code are gone.
Fixes:
- When the GPU path fails to start in
automode, the DOM fallback starts from a clean surface and the GPU device is released. - An effect whose shader fails to compile no longer redraws the canvas every frame.
destroy()clears the timers it left running.- The DOM backend drops removed nodes from the selection.
- Pages that empty out no longer stay in memory.
0.4.3
Clicks and typing work again in Chrome 157.
Chrome 157 changed getElementTransform: it now takes only the element and returns the canvas transform set by updateElementGeometry, instead of turning a draw matrix into a CSS transform. The live node's hit area stayed at the page origin, so clicks and typing on the GPU path missed the node under the pointer.
- Chrome 157 places the live node with
updateElementGeometry(el, { canvasTransform }), in CSS pixels. - Chrome 156 keeps the CSS transform from
getElementTransform(el, drawMatrix). - The README's Chrome findings describe both.
0.4.2
Touch. gpucanvas now works on phones and tablets:
- A two-finger pinch zooms and pans the camera, wherever the fingers land, nodes included.
- Taps reach the nodes on the GPU path. Touch has no hover, so the node under a tap was never live and the tap hit the canvas. The press now makes the node live, and a click that missed it is handed to the element under the finger. An editor that takes the press still gets it first.
The demo works on phones too: fewer screens so the tab is not killed for memory (1,000 on the GPU path, 250 as DOM), a compact toolbar, touch hints, and every button in the screens does something in Interact mode.
0.4.1
Fix: typing in edit mode. With trigger: 'click', every press selected, so inputs on the canvas could never take focus. Now:
- Double-click a text field (input, textarea, select or contenteditable) to start typing in it.
- Clicks inside that field move the caret and select text.
- Escape, or a click elsewhere, ends typing.
The demo's hint bar says so too: "Double-click to go deeper or type".
0.4.0
Four additions for tools built on the canvas, and for AI agents working in them.
Snapshots. canvas.snapshot(node, { scale }) returns any node as an image, drawn fresh, whether or not it is in view.
toBlobturns a snapshot into a PNG.diffImagesshows where two snapshots differ.recordFilmstripkeeps a snapshot after each change.
Agent view. createAgentView(canvas) is how an agent reads the canvas.
describe()returns what is in view as a short JSON tree: roles, names, text, values and checkbox state, each with an id. A sign-in screen comes out as about 35 entries.capture(id or rect)returns an image of any element or region.
Marks. createMarks(canvas) draws above the nodes, following the camera and the elements it is attached to:
- arrows between elements, with labels
- comment pins
- notes around an element
- named cursors that glide
Marks work with both backends.
Transitions. New fade and wipe effects. animateEffect runs any progress effect, such as dissolve, fade or wipe, over time. swapNodes takes one node out while another comes in.
Fix. Snapshots at a scale above 1 now fill the whole image.
In the demo, select a screen and press D to dissolve it, W to wipe it or S to save it. The console has agentView and marks.
0.3.1
0.3.0: editor and shader effects
gpucanvas is now more than pan and zoom.
Editor. bindEditor (or useEditor in React) turns the canvas into an editor:
- Click selects a whole node. Each double-click goes one layer deeper, down to any element or React component.
- Enter, Tab and Escape walk the layers.
- Drag to move and use the handles to resize, both snapping to neighbors with guides.
- Box-select works inside the layer you are in.
- Names and sizes label the selection.
- Moves arrive as
onTransformevents, so your app owns the document and undo.
Shader effects. canvas.setEffect(node, effects.glass) draws a live component through a WGSL shader. The component stays live: clicks, typing and state keep working.
- Following the pointer: glass, frost, dither.
- On each press: shockwave.
- Running on their own: glitch, VHS, glow, hue, ripple.
- Still: blur, pixelate, grayscale, dissolve.
defineEffecttakes your own WGSL, with the pointer, time and parameters as inputs.
The DOM fallback shows effects that have a CSS look as filters.
0.2.0: selection, and a live demo
Try it live: https://berkantay.github.io/gpucanvas/ (Chrome 157+, with chrome://flags/#canvas-draw-element enabled)
The film below: 30 agents build the first view, then the same 5,000 live React screens run side by side as plain DOM and in gpucanvas.
New
- Selection.
canvas.getNodesIn(rect)returns the nodes in a world rect,canvas.setSelection(ids)outlines them on the GPU at 2 CSS pixels at any zoom, and theselectionColoroption sets the color. Shift-drags on the background no longer pan, so an app can draw a selection box.
Demo
- 30 agent cursors build the opening view block by block, then the camera pulls out to all 5,000 screens. Each block is a real DOM change in a live React screen.
- The benchmark tour (press
b) is now 30 seconds with three stops: typing into a message, an animating chart, a push to 500% zoom, then shift-click picks and a selection sweep. At 5,000 screens it measures 113 to 115 fps for gpucanvas and 18 to 20 for DOM. - Without the HTML-in-Canvas flag, the demo runs the DOM fallback with 1,000 screens and shows how to turn the flag on.
- The demo is now on GitHub Pages and deploys on every push to main.
npm install gpucanvas@0.2.0