@layoutit/polycss 0.2.0 → 0.2.2

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@layoutit/polycss",
3
- "version": "0.2.0",
4
- "description": "Polycss vanilla / custom-elements + imperative API. Renders OBJ / glTF / GLB mesh polygons as DOM via CSS matrix3d.",
3
+ "version": "0.2.2",
4
+ "description": "PolyCSS vanilla / custom-elements + imperative API. Renders OBJ / STL / glTF / GLB mesh polygons as DOM via CSS matrix3d.",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
7
7
  "module": "dist/index.js",
@@ -47,7 +47,7 @@
47
47
  "access": "public"
48
48
  },
49
49
  "dependencies": {
50
- "@layoutit/polycss-core": "^0.2.0"
50
+ "@layoutit/polycss-core": "^0.2.2"
51
51
  },
52
52
  "devDependencies": {
53
53
  "tsup": "^8.0.1",
@@ -1,419 +0,0 @@
1
- import { Polygon, Vec3, ParseResult, PolyDirectionalLight, PolyAmbientLight, PolyTextureLightingMode, CameraHandle } from '@layoutit/polycss-core';
2
-
3
- type TextureQuality = number | "auto";
4
- type PolyRenderStrategy = "b" | "i" | "u";
5
- interface PolyRenderStrategiesOption {
6
- /** Strategies to skip; polygons that would normally use them fall through
7
- * the chain (b → i → s, u → i → s, i → s). `<s>` is the universal
8
- * fallback and cannot be disabled — textured polys have no other path. */
9
- disable?: readonly PolyRenderStrategy[];
10
- }
11
-
12
- /**
13
- * createPolyScene — imperative scene API. The vanilla counterpart to
14
- * `<PolyScene>` in React / Vue.
15
- *
16
- * Per §API freeze: takes a host element + scene options, returns a
17
- * `PolySceneHandle` whose `add(parseResult, transform?)` mounts a mesh under
18
- * the scene root and returns a removable `PolyMeshHandle`.
19
- *
20
- * Implementation:
21
- * - Inserts a `<div class="polycss-scene">` into the host.
22
- * - Each `add(...)` creates a `<div class="polycss-mesh">` with the
23
- * mesh transform; mounts every valid polygon as an atlas-backed
24
- * background sprite.
25
- * - `destroy()` removes the scene element and disposes every mesh
26
- * (which in turn disposes generated atlas blob URLs).
27
- *
28
- * The scene element is a 0×0 anchor at world (0,0,0) — pinned via
29
- * top:50%/left:50% so it sits at the visible center of the host. This
30
- * matches React/Vue's PolyScene anchor pattern. Polygons render around
31
- * the anchor via their own matrix3d translations.
32
- */
33
-
34
- interface PolySceneOptions {
35
- perspective?: number | false;
36
- rotX?: number;
37
- rotY?: number;
38
- zoom?: number;
39
- /**
40
- * Camera pull-back distance in CSS pixels. Increasing distance moves the
41
- * camera farther from the target (scene appears smaller), applied as an
42
- * outermost `translateZ(-distance)` in the scene transform. Matches the
43
- * `distance` field in core's `CameraState`. Default: 0 (no dolly offset).
44
- */
45
- distance?: number;
46
- /**
47
- * World-coordinate camera target — the world point that appears at the
48
- * viewport centre. Matches React's `CameraState.target`. Defaults to
49
- * `[0, 0, 0]` so existing scenes that don't set it keep working.
50
- *
51
- * Internally encoded as the innermost translate in the scene transform:
52
- * `scale(zoom) rotateX(rotX) rotate(rotY) translate3d(-ty*tile, -tx*tile, -tz*tile)`
53
- * (world→CSS axis swap: world-X→CSS-Y, world-Y→CSS-X, world-Z→CSS-Z).
54
- */
55
- target?: Vec3;
56
- directionalLight?: PolyDirectionalLight;
57
- ambientLight?: PolyAmbientLight;
58
- /** Textured polygon lighting mode. Defaults to "baked". */
59
- textureLighting?: PolyTextureLightingMode;
60
- /** Atlas bitmap budget and CSS sprite size. `"auto"` uses a
61
- * device-appropriate memory budget (~4 MB mobile / ~16 MB desktop) and
62
- * desktop/mobile sprite sizing. Numeric values 0.1..1 force an explicit
63
- * raster scale and the 64px sprite. */
64
- textureQuality?: TextureQuality;
65
- /**
66
- * Skip specific render-strategy tags. Polygons that would normally use a
67
- * disabled tag fall through the chain (b → i → s, u → i → s, i → s).
68
- * `<s>` is the universal fallback and cannot be disabled.
69
- */
70
- strategies?: PolyRenderStrategiesOption;
71
- /**
72
- * When `true`, rotation pivots around the union bbox of all added meshes
73
- * instead of world (0,0,0). The scene wraps polygons in an inner div
74
- * translated by `-bboxCenter`. Updates whenever a mesh is added/removed
75
- * or `setOptions` is called. Mirrors React's `<PolyScene autoCenter>`.
76
- */
77
- autoCenter?: boolean;
78
- /**
79
- * Shadow appearance for meshes with `castShadow: true`. Only applies in
80
- * dynamic lighting mode — baked mode does not emit shadow leaves.
81
- * Defaults: `{ color: "#000000", opacity: 0.25, lift: 0.05 }`.
82
- */
83
- shadow?: {
84
- /** Shadow color as a CSS hex string. Default: `"#000000"`. */
85
- color?: string;
86
- /** Shadow opacity 0..1. Default: `0.25`. */
87
- opacity?: number;
88
- /**
89
- * Raises the shadow plane slightly above the model bbox floor along
90
- * +Z (Z up) so it sits on top of a receiver mesh placed at the bbox
91
- * bottom, rather than below it where the receiver would occlude the
92
- * shadow. In world units. Default: `0.05`.
93
- */
94
- lift?: number;
95
- };
96
- }
97
- interface PolyMeshTransform {
98
- /** Stable identifier — exposed on the handle and reflected on the
99
- * wrapper as `data-poly-mesh-id`. Used by selection helpers to
100
- * resolve clicks back to the mesh and to dedupe selection state. */
101
- id?: string;
102
- position?: Vec3;
103
- scale?: number | Vec3;
104
- rotation?: Vec3;
105
- /**
106
- * Whether `scene.add()` should merge coplanar polygons before rendering.
107
- * Defaults to `true`. Set `false` for animated/deforming meshes whose
108
- * triangle topology must remain stable from frame to frame.
109
- */
110
- merge?: boolean;
111
- /**
112
- * Keep polygon leaf DOM nodes stable across setPolygons() calls when the
113
- * mesh topology is unchanged. Intended for animated/deforming meshes.
114
- */
115
- stableDom?: boolean;
116
- /**
117
- * When `true`, this mesh's polygons are NOT included in the scene's
118
- * auto-center bbox. Use for debug overlays / helpers that shouldn't
119
- * shift the camera target when toggled. Defaults to `false`.
120
- */
121
- excludeFromAutoCenter?: boolean;
122
- /**
123
- * When `true` and the scene is in dynamic lighting mode, the renderer emits
124
- * a flat shadow leaf sibling for each non-textured polygon. The shadow is
125
- * projected onto the ground plane (min world-Y of all casting meshes) along
126
- * the CSS-space light direction (driven by `--clx/--cly/--clz` vars). Zero
127
- * JS in the render loop — the projection matrix is a CSS var that recomputes
128
- * via `calc()` when the light vars change. Defaults to `false`.
129
- */
130
- castShadow?: boolean;
131
- }
132
- interface PolyMeshHandle {
133
- /** The polygons that were loaded after normalization and automatic merge. */
134
- polygons: Polygon[];
135
- /** The `.polycss-mesh` wrapper div for this mesh. Exposed so layered
136
- * helpers (selection, transform controls) can resolve a click target
137
- * back to its owning mesh, attach event listeners, or measure the
138
- * mesh's screen position via `getBoundingClientRect`. */
139
- readonly element: HTMLElement;
140
- /** Identifier passed via `PolyMeshTransform.id` (if any). Reflected on
141
- * the wrapper as `data-poly-mesh-id`. */
142
- readonly id?: string;
143
- /** Current transform snapshot (position / rotation / scale). Returned
144
- * by reference — treat as read-only and use `setTransform` to
145
- * mutate. */
146
- readonly transform: PolyMeshTransform;
147
- /** Remove the mesh from the scene. */
148
- remove(): void;
149
- /** Replace polygon geometry without tearing down the scene or controls. */
150
- setPolygons(polygons: Polygon[], options?: {
151
- merge?: boolean;
152
- stableDom?: boolean;
153
- recomputeAutoCenter?: boolean;
154
- }): void;
155
- /**
156
- * Update a single polygon in place. `target` is either a polygon
157
- * reference (as returned by `getPolygons()`) or its index. `partial`
158
- * fields are merged onto the polygon; the mesh is then re-rendered.
159
- * Skips the merge pass, so this is cheaper than `setPolygons` for
160
- * targeted edits like color picker updates from an inspector UI.
161
- * Silently no-ops if `target` isn't found.
162
- */
163
- updatePolygon(target: Polygon | number, partial: Partial<Polygon>): void;
164
- /** Update transform without re-parsing. */
165
- setTransform(t: Partial<PolyMeshTransform>): void;
166
- /** Revoke any blob URLs the parse created. Idempotent. */
167
- dispose(): void;
168
- /**
169
- * Re-rasterize the atlas using the directional light inverse-rotated into
170
- * the mesh's local frame. Call this after a mesh rotation has been
171
- * committed (e.g., on pointer release in rotate-mode transform controls) to
172
- * correct stale baked shading.
173
- *
174
- * **Background:** Baked atlas tiles encode `baseColor × Lambert(worldNormal,
175
- * worldLight)`. When the mesh wrapper rotates via CSS, the polygon's normal
176
- * in world space changes but the baked color doesn't — faces stay lit/unlit
177
- * incorrectly. `rebakeAtlas()` inverse-rotates the world light into the
178
- * mesh's local frame and re-runs the rasterizer; because
179
- * `dot(localNormal, localLight) === dot(worldNormal, worldLight)` the
180
- * output is correct for any rotation.
181
- *
182
- * **Performance note:** This does NOT run on every `setTransform` call —
183
- * only when explicitly invoked, so dragging remains smooth. Call it on
184
- * pointer release (or any point where you want to commit the new shading).
185
- */
186
- rebakeAtlas(): void;
187
- /** Current `position` from the transform (matches framework API). */
188
- getPosition(): Vec3 | undefined;
189
- /** Current `rotation` from the transform (matches framework API). */
190
- getRotation(): Vec3 | undefined;
191
- /** Current `scale` from the transform (matches framework API). */
192
- getScale(): number | Vec3 | undefined;
193
- /** Polygons currently being rendered (matches framework API). */
194
- getPolygons(): Polygon[];
195
- }
196
- interface PolySceneHandle {
197
- /** Add a mesh to the scene. Returns a handle for later removal. */
198
- add(mesh: ParseResult, opts?: PolyMeshTransform): PolyMeshHandle;
199
- /** Update scene-level config (rotation, lighting, etc.). */
200
- setOptions(partial: Partial<PolySceneOptions>): void;
201
- /** Tear down the scene; revokes all blob URLs of registered meshes. */
202
- destroy(): void;
203
- /**
204
- * The host element passed to `createPolyScene`. Exposed for layered
205
- * helpers like `createPolyOrbitControls` that need to attach event listeners
206
- * without tracking the host separately.
207
- */
208
- readonly host: HTMLElement;
209
- /**
210
- * Snapshot of the current options (camera, lighting, merge, autoCenter,
211
- * textureLighting, textureQuality, and perspective). Returned by reference,
212
- * so callers must treat it as read-only —
213
- * mutations won't propagate. Used by helpers that need to read the current
214
- * camera state without duplicating it.
215
- */
216
- getOptions(): Readonly<PolySceneOptions>;
217
- /** Snapshot of mesh handles currently in the scene (insertion order).
218
- * Used by selection helpers to enumerate hit-test candidates. */
219
- meshes(): readonly PolyMeshHandle[];
220
- /** Resolve a `.polycss-mesh` element back to its handle, or `null` if
221
- * the element doesn't belong to this scene. */
222
- findMeshByElement(element: Element | null): PolyMeshHandle | null;
223
- }
224
- declare function createPolyScene(host: HTMLElement, options?: PolySceneOptions): PolySceneHandle;
225
-
226
- interface PolyCameraOptions {
227
- zoom?: number;
228
- target?: Vec3;
229
- rotX?: number;
230
- rotY?: number;
231
- /** Camera pull-back in CSS pixels (dolly). Default 0. */
232
- distance?: number;
233
- }
234
- interface PolyPerspectiveCameraOptions extends PolyCameraOptions {
235
- /** CSS perspective distance in pixels. Default 8000. */
236
- perspective?: number;
237
- }
238
- interface PolyOrthographicCameraOptions extends PolyCameraOptions {
239
- }
240
- /** Extends CameraHandle with projection info for the container element. */
241
- interface PolyPerspectiveCameraHandle extends CameraHandle {
242
- readonly type: "perspective";
243
- /** CSS `perspective` value to set on the camera container element. */
244
- readonly perspectiveStyle: string;
245
- }
246
- interface PolyOrthographicCameraHandle extends CameraHandle {
247
- readonly type: "orthographic";
248
- /** CSS `perspective` value to set on the camera container element ("none"). */
249
- readonly perspectiveStyle: "none";
250
- }
251
- /**
252
- * Creates a perspective camera handle. The `perspectiveStyle` property
253
- * returns the CSS value to apply to the camera container's `perspective`
254
- * property (default `"8000px"`).
255
- */
256
- declare function createPolyPerspectiveCamera(options?: PolyPerspectiveCameraOptions): PolyPerspectiveCameraHandle;
257
- /**
258
- * Creates an orthographic camera handle. The `perspectiveStyle` property
259
- * returns `"none"` — pass it to the container element's CSS `perspective`
260
- * to disable perspective projection.
261
- */
262
- declare function createPolyOrthographicCamera(options?: PolyOrthographicCameraOptions): PolyOrthographicCameraHandle;
263
-
264
- declare const ELEMENT_BASE$8: typeof HTMLElement;
265
- declare class PolySceneElement extends ELEMENT_BASE$8 {
266
- static get observedAttributes(): string[];
267
- private _scene;
268
- /**
269
- * Returns the underlying PolySceneHandle. Children call this during their own
270
- * connectedCallback to register meshes.
271
- */
272
- getScene(): PolySceneHandle | null;
273
- private _readOptions;
274
- private _readDirectionalLight;
275
- private _readAmbientLight;
276
- connectedCallback(): void;
277
- disconnectedCallback(): void;
278
- attributeChangedCallback(_name: string, oldValue: string | null, newValue: string | null): void;
279
- }
280
-
281
- declare const ELEMENT_BASE$7: typeof HTMLElement;
282
- declare class PolyMeshElement extends ELEMENT_BASE$7 {
283
- static get observedAttributes(): string[];
284
- private _handle;
285
- private _parseResult;
286
- private _loadToken;
287
- /** Returns the current mesh handle, or null if not yet loaded. */
288
- getMeshHandle(): PolyMeshHandle | null;
289
- connectedCallback(): void;
290
- disconnectedCallback(): void;
291
- attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
292
- private _tearDown;
293
- private _maybeLoad;
294
- }
295
-
296
- declare const ELEMENT_BASE$6: typeof HTMLElement;
297
- declare class PolyPolygonElement extends ELEMENT_BASE$6 {
298
- static get observedAttributes(): string[];
299
- private _handle;
300
- connectedCallback(): void;
301
- disconnectedCallback(): void;
302
- attributeChangedCallback(_name: string, oldValue: string | null, newValue: string | null): void;
303
- private _tearDown;
304
- private _mount;
305
- }
306
-
307
- declare const ELEMENT_BASE$5: typeof HTMLElement;
308
- declare class PolyOrbitControlsElement extends ELEMENT_BASE$5 {
309
- static get observedAttributes(): string[];
310
- private _controls;
311
- private _readAnimate;
312
- private _readOptions;
313
- private _findScene;
314
- private _attach;
315
- connectedCallback(): void;
316
- disconnectedCallback(): void;
317
- attributeChangedCallback(_name: string, oldValue: string | null, newValue: string | null): void;
318
- }
319
-
320
- declare const ELEMENT_BASE$4: typeof HTMLElement;
321
- declare class PolyMapControlsElement extends ELEMENT_BASE$4 {
322
- static get observedAttributes(): string[];
323
- private _controls;
324
- private _readAnimate;
325
- private _readOptions;
326
- private _findScene;
327
- private _attach;
328
- connectedCallback(): void;
329
- disconnectedCallback(): void;
330
- attributeChangedCallback(_name: string, oldValue: string | null, newValue: string | null): void;
331
- }
332
-
333
- /**
334
- * <poly-perspective-camera> — standalone perspective camera element.
335
- *
336
- * Wraps `createPolyPerspectiveCamera`. Unlike <poly-scene> which owns the
337
- * scene DOM, this element provides a camera context that child controls can
338
- * read. It creates a `<div class="polycss-camera">` wrapper with the
339
- * CSS `perspective` property set.
340
- *
341
- * Attributes (all optional):
342
- * perspective — number, CSS perspective in pixels (default 8000)
343
- * zoom — number
344
- * rot-x — number, degrees (default 65)
345
- * rot-y — number, degrees (default 45)
346
- * target — "x,y,z" comma-separated world coordinates
347
- * distance — number, camera pull-back in CSS pixels
348
- */
349
-
350
- declare const ELEMENT_BASE$3: typeof HTMLElement;
351
- declare class PolyPerspectiveCameraElement extends ELEMENT_BASE$3 {
352
- static get observedAttributes(): string[];
353
- private _camera;
354
- private _wrapper;
355
- /** Returns the camera handle, or null if not yet connected. */
356
- getCamera(): PolyPerspectiveCameraHandle | null;
357
- private _readOptions;
358
- private _mount;
359
- private _teardown;
360
- connectedCallback(): void;
361
- disconnectedCallback(): void;
362
- attributeChangedCallback(_name: string, oldValue: string | null, newValue: string | null): void;
363
- }
364
-
365
- /**
366
- * <poly-orthographic-camera> — standalone orthographic camera element.
367
- *
368
- * Wraps `createPolyOrthographicCamera`. Sets CSS `perspective: none` on the
369
- * camera wrapper, disabling perspective projection.
370
- *
371
- * Attributes (all optional):
372
- * zoom — number
373
- * rot-x — number, degrees (default 65)
374
- * rot-y — number, degrees (default 45)
375
- * target — "x,y,z" comma-separated world coordinates
376
- * distance — number, camera pull-back in CSS pixels
377
- */
378
-
379
- declare const ELEMENT_BASE$2: typeof HTMLElement;
380
- declare class PolyOrthographicCameraElement extends ELEMENT_BASE$2 {
381
- static get observedAttributes(): string[];
382
- private _camera;
383
- private _wrapper;
384
- /** Returns the camera handle, or null if not yet connected. */
385
- getCamera(): PolyOrthographicCameraHandle | null;
386
- private _readOptions;
387
- private _mount;
388
- private _teardown;
389
- connectedCallback(): void;
390
- disconnectedCallback(): void;
391
- attributeChangedCallback(_name: string, oldValue: string | null, newValue: string | null): void;
392
- }
393
-
394
- declare const ELEMENT_BASE$1: typeof HTMLElement;
395
- declare class PolyTransformControlsElement extends ELEMENT_BASE$1 {
396
- static get observedAttributes(): string[];
397
- private _tc;
398
- private _findScene;
399
- private _findTargetMesh;
400
- private _readOptions;
401
- private _attach;
402
- connectedCallback(): void;
403
- disconnectedCallback(): void;
404
- attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
405
- }
406
-
407
- declare const ELEMENT_BASE: typeof HTMLElement;
408
- declare class PolySelectElement extends ELEMENT_BASE {
409
- static get observedAttributes(): string[];
410
- private _selection;
411
- private _findScene;
412
- private _readOptions;
413
- private _attach;
414
- connectedCallback(): void;
415
- disconnectedCallback(): void;
416
- attributeChangedCallback(_name: string, oldValue: string | null, newValue: string | null): void;
417
- }
418
-
419
- export { type PolySceneHandle as P, type TextureQuality as T, type PolyMeshHandle as a, type PolyCameraOptions as b, PolyMapControlsElement as c, PolyMeshElement as d, type PolyMeshTransform as e, PolyOrbitControlsElement as f, PolyOrthographicCameraElement as g, type PolyOrthographicCameraHandle as h, type PolyOrthographicCameraOptions as i, PolyPerspectiveCameraElement as j, type PolyPerspectiveCameraHandle as k, type PolyPerspectiveCameraOptions as l, PolyPolygonElement as m, type PolyRenderStrategiesOption as n, type PolyRenderStrategy as o, PolySceneElement as p, type PolySceneOptions as q, PolySelectElement as r, PolyTransformControlsElement as s, createPolyOrthographicCamera as t, createPolyPerspectiveCamera as u, createPolyScene as v };