gpucanvas 0.3.1 → 0.4.1

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.
@@ -85,6 +85,8 @@ declare const EFFECTS: {
85
85
  readonly blur: Effect;
86
86
  readonly pixelate: Effect;
87
87
  readonly dissolve: Effect;
88
+ readonly fade: Effect;
89
+ readonly wipe: Effect;
88
90
  readonly grayscale: Effect;
89
91
  };
90
92
 
@@ -186,6 +188,13 @@ interface GpuCanvas {
186
188
  * class on `<html>` or a web font finishing loading.
187
189
  */
188
190
  invalidate(): void;
191
+ /**
192
+ * The node's pixels as it looks now, drawn fresh at `scale` texels per CSS pixel (default the
193
+ * device pixel ratio), with straight alpha. GPU backend only: the DOM backend rejects.
194
+ */
195
+ snapshot(node: HTMLElement, options?: {
196
+ scale?: number;
197
+ }): Promise<ImageData>;
189
198
  /** Changes the canvas background, any CSS color. */
190
199
  setBackground(color: string): void;
191
200
  /** Fits all nodes in view. */
@@ -224,8 +233,9 @@ interface EditorOptions {
224
233
  * shift-cmd-click (shift-ctrl-click) adds or removes, shift-drag draws a selection box.
225
234
  * `'click'`: an edit mode. Every click selects, shift-click adds or removes, drags move, and
226
235
  * shift-drag on the background draws a selection box.
227
- * Either way, a double-click goes one layer deeper, and a drag on the open area of the layer
228
- * you are inside draws a box over its children.
236
+ * In the edit mode, a double-click on a text field starts typing in it, and Escape or a click
237
+ * elsewhere ends it. Either way, a double-click goes one layer deeper, and a drag on the open
238
+ * area of the layer you are inside draws a box over its children.
229
239
  */
230
240
  trigger?: 'shift-click' | 'click';
231
241
  /** Outlines what a click would select. With `'shift-click'`, only while shift is held. Default true. */
@@ -264,4 +274,4 @@ interface Editor {
264
274
  */
265
275
  declare function bindEditor(canvas: GpuCanvas, options?: EditorOptions): Editor;
266
276
 
267
- export { type Camera as C, type Editor as E, type GpuCanvasOptions as G, type Layer as L, type Point as P, type Rect as R, type TransformEvent as T, type GpuCanvas as a, type EditorOptions as b, type EditorPick as c, type Effect as d, type EffectDefinition as e, type GpuCanvasMode as f, type GpuCanvasStats as g, bindEditor as h, defineEffect as i, EFFECTS as j, fitCamera as k, screenToWorld as s, worldToScreen as w, zoomAt as z };
277
+ export { type Camera as C, type Effect as E, type GpuCanvas as G, type Layer as L, type Point as P, type Rect as R, type TransformEvent as T, type GpuCanvasOptions as a, type Editor as b, type EditorOptions as c, type EditorPick as d, type EffectDefinition as e, type GpuCanvasMode as f, type GpuCanvasStats as g, bindEditor as h, defineEffect as i, EFFECTS as j, fitCamera as k, screenToWorld as s, worldToScreen as w, zoomAt as z };
package/dist/index.d.ts CHANGED
@@ -1,12 +1,174 @@
1
- import { G as GpuCanvasOptions, a as GpuCanvas } from './editor-BSRqjhN8.js';
2
- export { C as Camera, E as Editor, b as EditorOptions, c as EditorPick, d as Effect, e as EffectDefinition, f as GpuCanvasMode, g as GpuCanvasStats, L as Layer, P as Point, R as Rect, T as TransformEvent, h as bindEditor, i as defineEffect, j as effects, k as fitCamera, s as screenToWorld, w as worldToScreen, z as zoomAt } from './editor-BSRqjhN8.js';
1
+ import { R as Rect, G as GpuCanvas, P as Point, E as Effect, a as GpuCanvasOptions } from './editor-CuH4tLHg.js';
2
+ export { C as Camera, b as Editor, c as EditorOptions, d as EditorPick, e as EffectDefinition, f as GpuCanvasMode, g as GpuCanvasStats, L as Layer, T as TransformEvent, h as bindEditor, i as defineEffect, j as effects, k as fitCamera, s as screenToWorld, w as worldToScreen, z as zoomAt } from './editor-CuH4tLHg.js';
3
3
 
4
4
  declare function supportsGpuCanvas(): boolean;
5
5
 
6
+ /** One element as an agent reads it: what it is, what it says, and where it sits on the canvas. */
7
+ interface AgentElement {
8
+ /** Stable for the life of the agent view; pass it back to `element`, `capture` or a mark. */
9
+ id: string;
10
+ tag: string;
11
+ role?: string;
12
+ /** Its accessible name: aria-label, alt, title or a label's text. */
13
+ name?: string;
14
+ /** Its own text, trimmed. */
15
+ text?: string;
16
+ /** For inputs: the current value. */
17
+ value?: string;
18
+ /** For checkboxes and radios. */
19
+ checked?: boolean;
20
+ rect: Rect;
21
+ children?: AgentElement[];
22
+ }
23
+ interface DescribeOptions {
24
+ /** The world rect to read. Default: what is in view. */
25
+ rect?: Rect;
26
+ /** Levels below each node, counting only elements with a role, name, text or value. Default 6. */
27
+ depth?: number;
28
+ /** A name for an element when it has none of its own, such as its React component's. */
29
+ name?: (element: Element) => string | null | undefined;
30
+ }
31
+ /**
32
+ * The canvas as an agent sees it: a JSON tree of what is in a region, with ids it can point back
33
+ * at, and images of any region. Wrappers that add nothing (no text, no role, the same box as
34
+ * their only child) are left out, so the tree stays short.
35
+ */
36
+ declare function createAgentView(canvas: GpuCanvas): {
37
+ /** What is in `rect` (default: the view), node by node, as plain JSON. */
38
+ describe(options?: DescribeOptions): AgentElement[];
39
+ /** The element behind an id from `describe`, or null once it is gone. */
40
+ element(id: string): Element | null;
41
+ /** Where an element (or the element behind an id) sits, in world units. */
42
+ rect(target: string | Element): Rect | null;
43
+ /**
44
+ * An image of a world rect (an element's box when given one) as the nodes look now, at
45
+ * `scale` texels per world unit. GPU backend only.
46
+ */
47
+ capture(target: Rect | string | Element, { scale, background }?: {
48
+ scale?: number;
49
+ background?: string;
50
+ }): Promise<ImageData>;
51
+ };
52
+ type AgentView = ReturnType<typeof createAgentView>;
53
+
54
+ /** Something drawn above the nodes. `remove` takes it off the canvas. */
55
+ interface Mark {
56
+ remove(): void;
57
+ }
58
+ interface CursorMark extends Mark {
59
+ /** Glides the cursor to a world point; null hides it. */
60
+ move(point: Point | null): void;
61
+ }
62
+ type Target = Element | Point;
63
+ /**
64
+ * Marks above the nodes: connectors between elements, comment pins, notes that point at an
65
+ * element (what an agent is talking about), and live cursors. They follow the camera and the
66
+ * elements they are attached to, and stay the same size on screen at any zoom.
67
+ */
68
+ declare function createMarks(canvas: GpuCanvas, { color }?: {
69
+ color?: string | undefined;
70
+ }): {
71
+ /** An arrow from one element (or world point) to another, with an optional label. */
72
+ connect(from: Target, to: Target, options?: {
73
+ label?: string;
74
+ color?: string;
75
+ dashed?: boolean;
76
+ }): Mark;
77
+ /**
78
+ * A comment pin at an element's top right corner, or at a world point. Its text shows on
79
+ * hover; `onClick` makes it a button.
80
+ */
81
+ pin(target: Target, options?: {
82
+ text?: string;
83
+ label?: string;
84
+ color?: string;
85
+ onClick?: () => void;
86
+ }): Mark;
87
+ /** A dashed frame around an element with a note above it: what someone is pointing at. */
88
+ note(target: Element, text: string, options?: {
89
+ color?: string;
90
+ }): Mark;
91
+ /** Someone's cursor, with their name. It glides to each point given to `move`. */
92
+ cursor(name: string, options?: {
93
+ color?: string;
94
+ }): CursorMark;
95
+ /** Removes every mark. */
96
+ clear(): void;
97
+ destroy(): void;
98
+ };
99
+ type Marks = ReturnType<typeof createMarks>;
100
+
101
+ /** A snapshot as an image file, PNG by default. */
102
+ declare function toBlob(image: ImageData, type?: string, quality?: number): Promise<Blob>;
103
+ interface ImageDiff {
104
+ /** Pixels that differ by more than the threshold, out of `total`. */
105
+ changed: number;
106
+ total: number;
107
+ /** The smallest rect around every changed pixel, in pixels of the images, or null. */
108
+ bounds: Rect | null;
109
+ /** `after` faded, with the changed pixels in `color` on top. */
110
+ image: ImageData;
111
+ }
112
+ /**
113
+ * Where two snapshots of the same node differ. Pixels count as changed when a channel moves by
114
+ * more than `threshold` (0 to 255). Images of different sizes compare over the larger one, and
115
+ * what only one of them covers counts as changed.
116
+ */
117
+ declare function diffImages(before: ImageData, after: ImageData, { threshold, color }?: {
118
+ threshold?: number | undefined;
119
+ color?: [number, number, number] | undefined;
120
+ }): ImageDiff;
121
+ interface FilmstripFrame {
122
+ /** When the frame was taken, from performance.now(). */
123
+ at: number;
124
+ image: ImageData;
125
+ }
126
+ interface Filmstrip {
127
+ readonly frames: readonly FilmstripFrame[];
128
+ stop(): void;
129
+ }
130
+ /**
131
+ * Keeps a snapshot of `node` after each change to its content, once the change has settled.
132
+ * Starts with one of how it looks now. Keeps the latest `max` frames.
133
+ */
134
+ declare function recordFilmstrip(canvas: Pick<GpuCanvas, 'snapshot'>, node: HTMLElement, { scale, max, settleMs, onFrame, }?: {
135
+ scale?: number;
136
+ max?: number;
137
+ settleMs?: number;
138
+ onFrame?: (frame: FilmstripFrame, frames: readonly FilmstripFrame[]) => void;
139
+ }): Filmstrip;
140
+
141
+ type Easing = (t: number) => number;
142
+ declare const easeInOut: Easing;
143
+ interface AnimateEffectOptions {
144
+ /** Progress at the start and the end, 0 (whole) to 1 (gone). Default 0 to 1. */
145
+ from?: number;
146
+ to?: number;
147
+ /** Milliseconds. Default 500. */
148
+ duration?: number;
149
+ easing?: Easing;
150
+ /** The effect's other parameters, after progress. */
151
+ params?: readonly number[];
152
+ }
153
+ /**
154
+ * Runs a transition effect (one whose first parameter is progress, such as dissolve, fade or
155
+ * wipe) on a node. Resolves true when it finishes, false when another animation on the same node
156
+ * replaced it. A node that ends whole (progress 0) loses the effect; one that ends gone keeps it,
157
+ * so it stays hidden until it is removed or animated back.
158
+ */
159
+ declare function animateEffect(canvas: Pick<GpuCanvas, 'setEffect'>, node: HTMLElement, effect: Effect, { from, to, duration, easing, params }?: AnimateEffectOptions): Promise<boolean>;
160
+ /**
161
+ * Takes `outgoing` away and brings `incoming` in at the same time, each through `effect`.
162
+ * `incoming` ends whole; `outgoing` ends hidden, ready to be removed.
163
+ */
164
+ declare function swapNodes(canvas: Pick<GpuCanvas, 'setEffect'>, outgoing: HTMLElement, incoming: HTMLElement, { effect, ...options }?: Omit<AnimateEffectOptions, 'from' | 'to'> & {
165
+ effect?: Effect;
166
+ }): Promise<boolean>;
167
+
6
168
  /**
7
169
  * Creates an infinite canvas inside `host`. Uses WebGPU + HTML-in-Canvas when the browser has
8
170
  * both (Chrome 157+), and plain DOM transforms everywhere else; the API is the same.
9
171
  */
10
172
  declare function createGpuCanvas(host: HTMLElement, options?: GpuCanvasOptions): Promise<GpuCanvas>;
11
173
 
12
- export { GpuCanvas, GpuCanvasOptions, createGpuCanvas, supportsGpuCanvas };
174
+ export { type AgentElement, type AgentView, type AnimateEffectOptions, type CursorMark, type DescribeOptions, type Easing, Effect, type Filmstrip, type FilmstripFrame, GpuCanvas, GpuCanvasOptions, type ImageDiff, type Mark, type Marks, Point, Rect, animateEffect, createAgentView, createGpuCanvas, createMarks, diffImages, easeInOut, recordFilmstrip, supportsGpuCanvas, swapNodes, toBlob };
package/dist/index.js CHANGED
@@ -1,22 +1,38 @@
1
1
  import {
2
2
  EFFECTS,
3
+ animateEffect,
3
4
  bindEditor,
5
+ createAgentView,
4
6
  createGpuCanvas,
7
+ createMarks,
5
8
  defineEffect,
9
+ diffImages,
10
+ easeInOut,
6
11
  fitCamera,
12
+ recordFilmstrip,
7
13
  screenToWorld,
8
14
  supportsGpuCanvas,
15
+ swapNodes,
16
+ toBlob,
9
17
  worldToScreen,
10
18
  zoomAt
11
- } from "./chunk-RBXGH44N.js";
19
+ } from "./chunk-DPCICAYZ.js";
12
20
  export {
21
+ animateEffect,
13
22
  bindEditor,
23
+ createAgentView,
14
24
  createGpuCanvas,
25
+ createMarks,
15
26
  defineEffect,
27
+ diffImages,
28
+ easeInOut,
16
29
  EFFECTS as effects,
17
30
  fitCamera,
31
+ recordFilmstrip,
18
32
  screenToWorld,
19
33
  supportsGpuCanvas,
34
+ swapNodes,
35
+ toBlob,
20
36
  worldToScreen,
21
37
  zoomAt
22
38
  };
package/dist/react.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode, CSSProperties } from 'react';
3
- import { d as Effect, G as GpuCanvasOptions, a as GpuCanvas$1, L as Layer, b as EditorOptions } from './editor-BSRqjhN8.js';
3
+ import { E as Effect, a as GpuCanvasOptions, G as GpuCanvas$1, L as Layer, c as EditorOptions } from './editor-CuH4tLHg.js';
4
4
 
5
5
  interface GpuCanvasProps extends GpuCanvasOptions {
6
6
  children?: ReactNode;
package/dist/react.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  bindEditor,
4
4
  createGpuCanvas
5
- } from "./chunk-RBXGH44N.js";
5
+ } from "./chunk-DPCICAYZ.js";
6
6
 
7
7
  // src/react.tsx
8
8
  import {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "gpucanvas",
3
- "version": "0.3.1",
4
- "description": "Put thousands of live DOM nodes on an infinite canvas: the GPU draws them, an editor selects, moves and resizes them, and shaders run on them.",
3
+ "version": "0.4.1",
4
+ "description": "Put thousands of live DOM nodes on an infinite canvas: the GPU draws them, an editor selects, moves and resizes them, shaders and transitions run on them, and an AI agent can read them and point at them.",
5
5
  "keywords": [
6
6
  "canvas",
7
7
  "infinite-canvas",
@@ -12,7 +12,9 @@
12
12
  "design-tools",
13
13
  "editor",
14
14
  "shaders",
15
- "wgsl"
15
+ "wgsl",
16
+ "ai-agents",
17
+ "transitions"
16
18
  ],
17
19
  "author": "Berkant Ay",
18
20
  "license": "MIT",