@cruxgarden/plasma-ui 0.2.4 → 0.5.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.
@@ -21,6 +21,49 @@ export interface RendererSettings {
21
21
  highlight: number;
22
22
  /** Thin edge line strength. */
23
23
  edgeLine: number;
24
+ /** Slow iridescent sheen across the body of each surface. 0 = none. */
25
+ shimmer: number;
26
+ /** Colored bloom the plasma casts onto the background around it. 0 = none. */
27
+ glow: number;
28
+ /** How much the material tints what is seen through it. 0 = clear as water. */
29
+ wash: number;
30
+ /** Film grain over the background. 0 = none. */
31
+ grain: number;
32
+ /** Blur applied to the background only, in CSS px (0-40). Costs 8 extra blur passes when above 0. */
33
+ backgroundBlur: number;
34
+ /**
35
+ * What the canvas shows where there is no surface. "field" paints the
36
+ * background everywhere. "clear" leaves it transparent, so the canvas can
37
+ * sit above other content: only the surfaces, their shadows and rims are
38
+ * drawn, and what a surface refracts is the `background` source - usually a
39
+ * live canvas of the field beneath, sampled without swirl so it lines up.
40
+ */
41
+ ground: "field" | "clear";
42
+ /**
43
+ * Keep each frame in the drawing buffer after it is shown, so another
44
+ * provider can pass this canvas as its `background` and sample it. Off,
45
+ * the browser may clear the buffer after compositing and the sample reads
46
+ * blank. Fixed at creation.
47
+ */
48
+ preserveDrawingBuffer: boolean;
49
+ /** What the surfaces are made of. */
50
+ material: MaterialName;
51
+ /** Direction the one light comes from. Every opaque material reads it, so they agree. */
52
+ lightDir: [number, number, number];
53
+ /** Surface finish: 0 mirror, 1 chalk. Used by metal; the others carry their own. */
54
+ roughness: number;
55
+ /** How far the highlight stretches along the grain. 0 is isotropic. */
56
+ anisotropy: number;
57
+ /** How far the outline is displaced from the rounded box, in CSS px. 0 leaves it clean. */
58
+ edge: number;
59
+ /** Size of the displacement, in cycles per px. Small is billows, large is chips. */
60
+ edgeScale: number;
61
+ /** 0 rolls the displaced edge, 1 breaks it into flats and points. */
62
+ edgeSharpness: number;
63
+ /** How thick a panel is as a solid, in CSS px. Only the marched materials use it. */
64
+ thickness: number;
65
+ /** Surface tension: how hard the material pulls its own shape toward a bead. */
66
+ tension: number;
24
67
  /** 0 = watery and bouncy, 1 = thick and slow. */
25
68
  viscosity: number;
26
69
  /** How far the surface trails behind moving panels. 0 = no trailing. */
@@ -40,8 +83,30 @@ export interface RendererSettings {
40
83
  /** Background: CSS color, image URL, or a live img/canvas/video source (null for the procedural mood field). */
41
84
  background: BackgroundSource | null;
42
85
  }
86
+ /**
87
+ * The materials a surface can be made of. `plasma` is the original and the
88
+ * default; the rest share its geometry, its springs and its fusing, and differ
89
+ * only in the composite pass — which is the whole reason they are cheap.
90
+ */
91
+ export declare const MATERIALS: readonly ["plasma", "crystal", "metal", "mercury", "wood", "stone", "cloud"];
92
+ export type MaterialName = (typeof MATERIALS)[number];
43
93
  /** Anything the background can be: a CSS color string, an image URL, or an element to sample (canvas and video update live). */
44
94
  export type BackgroundSource = string | HTMLImageElement | HTMLCanvasElement | HTMLVideoElement | ImageBitmap;
95
+ /**
96
+ * Set on a surface's element from `register` until its form-in has finished
97
+ * (about half a second; never under reduced motion). Style the element's
98
+ * children off it to have the contents arrive after the material:
99
+ * `[data-plasma-forming] > * { opacity: 0 }` with a transition on opacity.
100
+ */
101
+ export declare const FORMING_ATTR = "data-plasma-forming";
102
+ /**
103
+ * Events a surface's element dispatches (bubbling, so a page can listen at
104
+ * the document): `plasmaforming` when the form-in starts, `plasmaformed`
105
+ * when it has settled — at once under reduced motion. `detail.id` is the
106
+ * surface id. `<Plasma onForming onFormed>` wraps them.
107
+ */
108
+ export declare const FORMING_EVENT = "plasmaforming";
109
+ export declare const FORMED_EVENT = "plasmaformed";
45
110
  export interface ShapeOptions {
46
111
  radius: number;
47
112
  lean: number;
@@ -55,6 +120,8 @@ export interface ShapeOptions {
55
120
  elevation?: number | null;
56
121
  /** When false, this surface never blends, bridges, or joins with others. Default true. */
57
122
  fuse?: boolean;
123
+ /** Snap only against surfaces carrying the same group. null groups with the other ungrouped surfaces. */
124
+ group?: string | null;
58
125
  }
59
126
  /** Handle returned by `register`, used by <Plasma>. */
60
127
  export interface JoinedSides {
@@ -96,6 +163,13 @@ export declare class PlasmaRenderer {
96
163
  private floatOK;
97
164
  /** True between webglcontextlost and webglcontextrestored: draw nothing. */
98
165
  private lost;
166
+ private warnedOverflow;
167
+ /**
168
+ * Set by destroy(). The canvas and its context outlive this renderer, so an
169
+ * async callback that lands afterwards would happily allocate on a context
170
+ * nothing can free it from.
171
+ */
172
+ private destroyed;
99
173
  private resizeSettle;
100
174
  /** Everything initGL() created, so destroy() can free it by hand. */
101
175
  private owned;
@@ -145,13 +219,22 @@ export declare class PlasmaRenderer {
145
219
  private loadBackground;
146
220
  configure(s: RendererSettings, immediate?: boolean): void;
147
221
  register(el: HTMLElement, o: ShapeOptions, onJoin?: (j: boolean) => void, onSides?: (sides: JoinedSides) => void): ShapeHandle;
148
- /** Layout boxes of all shapes (lean removed; animating draggables report their destination). */
149
- layoutBoxes(excludeId?: number, fusingOnly?: boolean): Box[];
222
+ /**
223
+ * Layout boxes of all shapes (lean removed; animating draggables report
224
+ * their destination). Pass `group` to see only the surfaces in that group;
225
+ * omit it - as any caller written before groups existed does - to see them all.
226
+ */
227
+ layoutBoxes(excludeId?: number, fusingOnly?: boolean, group?: string | null): Box[];
150
228
  private layoutBoxOf;
151
229
  /** Send a pulse through the material from a viewport point. */
152
230
  pulse(x: number, y: number, strength?: number): void;
153
231
  /** Raise the material's energy (brightens contours and color); it decays on its own. */
154
232
  bump(e: number): void;
233
+ /** Rebuild the shaders and uniform arrays for a new surface budget. */
234
+ private setMax;
235
+ private allocUniformArrays;
236
+ /** Delete every GL object this renderer created, leaving the canvas usable. */
237
+ private releaseGL;
155
238
  /**
156
239
  * Every GL object this renderer owns. A lost context invalidates all of
157
240
  * them, so creation lives here rather than in the constructor: the restore
package/package.json CHANGED
@@ -1,16 +1,20 @@
1
1
  {
2
2
  "name": "@cruxgarden/plasma-ui",
3
- "version": "0.2.4",
3
+ "version": "0.5.0",
4
4
  "description": "Liquid panels for React, rendered in WebGL on canvas: every panel is one shared plasma - they fuse on contact, refract, and snap to a grid.",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
7
7
  "build": "esbuild src/index.ts --bundle --format=esm --jsx=automatic --target=es2020 --external:react --external:react-dom --outfile=dist/index.js && tsc",
8
8
  "build:site": "node site/build.mjs",
9
9
  "typecheck": "tsc --noEmit",
10
+ "typecheck:app": "tsc -p tsconfig.app.json",
11
+ "typecheck:react19": "npm i --no-save --no-audit --no-fund @types/react@19 @types/react-dom@19 && tsc -p tsconfig.app.json",
12
+ "format:check": "prettier --check site examples scripts",
10
13
  "test": "node --test tests/*.test.mjs",
11
- "prepublishOnly": "npm run typecheck && npm test && npm run build",
14
+ "prepublishOnly": "npm run verify",
12
15
  "format": "prettier --write .",
13
- "verify": "npm run typecheck && npm test && npm run build",
16
+ "check:docs": "node scripts/check-docs.mjs",
17
+ "verify": "npm run typecheck && npm run typecheck:app && npm run format:check && npm test && npm run build && npm run check:docs",
14
18
  "publish:patch": "npm version patch && npm publish && git push && git push --tags",
15
19
  "publish:minor": "npm version minor && npm publish && git push && git push --tags",
16
20
  "publish:major": "npm version major && npm publish && git push && git push --tags",