@layoutit/polycss 0.2.0 → 0.2.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.
- package/README.md +147 -148
- package/dist/{PolySelectElement-Tvsmhx2m.d.cts → PolyShapeElements-prI_DBZX.d.cts} +234 -104
- package/dist/{PolySelectElement-Tvsmhx2m.d.ts → PolyShapeElements-prI_DBZX.d.ts} +234 -104
- package/dist/elements.cjs +73 -17
- package/dist/elements.d.cts +1 -1
- package/dist/elements.d.ts +1 -1
- package/dist/elements.js +73 -17
- package/dist/index.cjs +73 -17
- package/dist/index.d.cts +126 -5
- package/dist/index.d.ts +126 -5
- package/dist/index.js +73 -17
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,200 +1,199 @@
|
|
|
1
|
-
|
|
1
|
+
# PolyCSS
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A CSS polygon mesh library. A 3D engine for the DOM. Renders OBJ/MTL, GLB and VOX as real HTML elements transformed with CSS `matrix3d(...)`. Supports colors, textures, lighting, shadows, shapes and animations. Works with React, Vue or plain JavaScript.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Visit [polycss.com](https://polycss.com) for docs and model examples.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
<img width="1600" height="300" alt="PolyCSS primitives banner" src="https://github.com/user-attachments/assets/b05e2204-9323-4f83-8d1b-01ea0dd000db" />
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
- **`polycss/elements`**: side-effect import that registers the scene, mesh, polygon, controls, camera, helper, select, and transform-control custom elements.
|
|
11
|
-
|
|
12
|
-
## Install
|
|
9
|
+
## Installation
|
|
13
10
|
|
|
14
11
|
```bash
|
|
12
|
+
|
|
13
|
+
# Vanilla
|
|
15
14
|
npm install @layoutit/polycss
|
|
16
|
-
```
|
|
17
15
|
|
|
18
|
-
|
|
16
|
+
# React
|
|
17
|
+
npm install @layoutit/polycss-react
|
|
18
|
+
|
|
19
|
+
# Vue
|
|
20
|
+
npm install @layoutit/polycss-vue
|
|
19
21
|
|
|
20
|
-
```html
|
|
21
|
-
<script type="module" src="https://esm.sh/@layoutit/polycss/elements"></script>
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
-
## Custom elements (declarative, primary path)
|
|
25
24
|
|
|
26
|
-
|
|
25
|
+
You can also load PolyCSS directly from a CDN. Here is a minimal custom-element scene:
|
|
27
26
|
|
|
28
27
|
```html
|
|
29
28
|
<script type="module" src="https://esm.sh/@layoutit/polycss/elements"></script>
|
|
30
29
|
|
|
31
|
-
<poly-
|
|
32
|
-
<poly-
|
|
33
|
-
|
|
30
|
+
<poly-camera rot-x="65" rot-y="45">
|
|
31
|
+
<poly-scene>
|
|
32
|
+
<poly-orbit-controls drag wheel></poly-orbit-controls>
|
|
33
|
+
<poly-box size="100" color="#ffd166"></poly-box>
|
|
34
|
+
</poly-scene>
|
|
35
|
+
</poly-camera>
|
|
34
36
|
```
|
|
35
37
|
|
|
36
|
-
|
|
38
|
+
<img width="2500" height="1145" alt="PolyCSS intro" src="https://github.com/user-attachments/assets/0e5df0d8-04a8-4e50-8e3a-1097a96ce42f" />
|
|
37
39
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
40
|
+
## Framework Components
|
|
41
|
+
|
|
42
|
+
React and Vue expose the same component model. `<PolyCamera>` owns the viewpoint, `<PolyScene>` owns lighting and atlas options, and `<PolyMesh>` loads or receives polygon data.
|
|
43
|
+
|
|
44
|
+
```tsx
|
|
45
|
+
import { PolyCamera, PolyScene, PolyOrbitControls, PolyMesh } from "@layoutit/polycss-react";
|
|
46
|
+
|
|
47
|
+
export default function App() {
|
|
48
|
+
return (
|
|
49
|
+
<PolyCamera rotX={65} rotY={45}>
|
|
50
|
+
<PolyScene textureLighting="dynamic">
|
|
51
|
+
<PolyOrbitControls drag wheel />
|
|
52
|
+
<PolyMesh src="/gallery/obj/cottage.obj" mtl="/gallery/obj/cottage.mtl" />
|
|
53
|
+
</PolyScene>
|
|
54
|
+
</PolyCamera>
|
|
55
|
+
);
|
|
56
|
+
}
|
|
49
57
|
```
|
|
50
58
|
|
|
51
|
-
|
|
59
|
+
## API Reference
|
|
52
60
|
|
|
53
|
-
|
|
54
|
-
<poly-scene id="scene" perspective="1000" rot-x="65" rot-y="45"></poly-scene>
|
|
61
|
+
### PolyCamera
|
|
55
62
|
|
|
56
|
-
|
|
57
|
-
|
|
63
|
+
- `rotX`, `rotY` control the orbit angle in degrees.
|
|
64
|
+
- `zoom` scales the projected scene.
|
|
65
|
+
- `target` pans the camera target in world coordinates.
|
|
66
|
+
- `distance` adds dolly pull-back.
|
|
67
|
+
- `PolyCamera` is the orthographic default. Use `PolyPerspectiveCamera` when you want perspective depth.
|
|
58
68
|
|
|
59
|
-
|
|
69
|
+
### PolyScene
|
|
60
70
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
71
|
+
- `polygons` renders a static `Polygon[]` directly.
|
|
72
|
+
- `directionalLight` and `ambientLight` control scene lighting.
|
|
73
|
+
- `textureLighting` chooses `"baked"` or `"dynamic"`.
|
|
74
|
+
- `textureQuality` controls atlas raster budget.
|
|
75
|
+
- Solid seam bleed is automatic on detected shared solid edges.
|
|
76
|
+
- `strategies` can disable selected render strategies for diagnostics.
|
|
77
|
+
- `autoCenter` rotates around the rendered mesh bounds instead of world origin.
|
|
65
78
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
79
|
+
### PolyMesh
|
|
80
|
+
|
|
81
|
+
- `src` loads `.obj`, `.gltf`, `.glb`, or `.vox` files.
|
|
82
|
+
- `mtl` loads companion OBJ materials.
|
|
83
|
+
- `polygons` accepts pre-parsed geometry.
|
|
84
|
+
- `position`, `scale`, and `rotation` transform the mesh wrapper.
|
|
85
|
+
- `autoCenter` shifts the mesh bbox center to local origin.
|
|
86
|
+
- `meshResolution` chooses `"lossy"` (default) or `"lossless"` optimization.
|
|
87
|
+
- `castShadow` emits CSS-projected shadows in dynamic lighting mode.
|
|
88
|
+
|
|
89
|
+
### Controls
|
|
90
|
+
|
|
91
|
+
- `<PolyOrbitControls>` adds drag orbit, shift-drag pan, wheel zoom, and optional auto-rotate.
|
|
92
|
+
- `<PolyMapControls>` uses pan-first map-style input.
|
|
93
|
+
- `<PolyFirstPersonControls>` provides keyboard and pointer-look navigation.
|
|
94
|
+
- `<PolyTransformControls>` adds translate/rotate gizmos for selected mesh handles.
|
|
95
|
+
|
|
96
|
+
### Polygon Data Model
|
|
76
97
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
98
|
+
Each polygon describes one renderable face:
|
|
99
|
+
|
|
100
|
+
```ts
|
|
101
|
+
const polygons = [
|
|
102
|
+
{
|
|
103
|
+
vertices: [[0, 0, 0], [60, 0, 0], [0, 60, 0]],
|
|
104
|
+
color: "#f97316",
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
vertices: [[0, 0, 0], [60, 0, 0], [60, 60, 0], [0, 60, 0]],
|
|
108
|
+
texture: "/texture.png",
|
|
109
|
+
uvs: [[0, 0], [1, 0], [1, 1], [0, 1]],
|
|
110
|
+
},
|
|
111
|
+
];
|
|
80
112
|
```
|
|
81
113
|
|
|
82
|
-
|
|
114
|
+
Render polygons directly when you need per-face DOM events or custom styling:
|
|
115
|
+
|
|
116
|
+
```tsx
|
|
117
|
+
<PolyCamera>
|
|
118
|
+
<PolyScene>
|
|
119
|
+
{polygons.map((polygon, index) => (
|
|
120
|
+
<Poly
|
|
121
|
+
key={index}
|
|
122
|
+
{...polygon}
|
|
123
|
+
onClick={() => console.log("clicked polygon", index)}
|
|
124
|
+
className="my-polygon"
|
|
125
|
+
/>
|
|
126
|
+
))}
|
|
127
|
+
</PolyScene>
|
|
128
|
+
</PolyCamera>
|
|
129
|
+
```
|
|
83
130
|
|
|
84
|
-
|
|
131
|
+
## Loading Mesh Files
|
|
85
132
|
|
|
86
|
-
|
|
87
|
-
|---|---|
|
|
88
|
-
| `perspective` | CSS perspective distance in pixels |
|
|
89
|
-
| `rot-x` | Camera X-axis rotation in degrees |
|
|
90
|
-
| `rot-y` | Camera Y-axis rotation in degrees |
|
|
91
|
-
| `zoom` | Scale factor |
|
|
92
|
-
| `directional-direction` | Comma-separated `x, y, z` e.g. `"0.5, -0.7, 0.6"` |
|
|
93
|
-
| `directional-color` | Directional light color hex |
|
|
94
|
-
| `directional-intensity` | Directional light intensity |
|
|
95
|
-
| `ambient-intensity` | Ambient light intensity |
|
|
96
|
-
| `ambient-color` | Ambient light color hex |
|
|
97
|
-
| `texture-lighting` | `"baked"` or `"dynamic"` |
|
|
98
|
-
| `atlas-scale` | Atlas bitmap budget and compositor sprite size; lower numeric values reduce memory/detail |
|
|
99
|
-
|
|
100
|
-
For pointer drag, wheel zoom, and autorotate, drop a `<poly-orbit-controls>` child inside the scene (or wire `createPolyOrbitControls(scene, ...)` against the imperative API). For pan-first map-style input use `<poly-map-controls>` / `createPolyMapControls` instead. Mirrors Three.js's split between camera state (`<poly-scene>`) and camera input.
|
|
101
|
-
|
|
102
|
-
**`<poly-mesh>`**
|
|
103
|
-
|
|
104
|
-
| Attribute | Description |
|
|
105
|
-
|---|---|
|
|
106
|
-
| `src` | URL to `.obj`, `.glb`, `.gltf`, or `.vox` |
|
|
107
|
-
| `position` | Comma-separated `x, y, z` |
|
|
108
|
-
| `scale` | Uniform scale factor |
|
|
109
|
-
| `rotation` | Comma-separated euler degrees `x, y, z` |
|
|
110
|
-
| `auto-center` | Boolean: shift mesh bbox center to origin |
|
|
133
|
+
Use `loadMesh()` to parse supported model formats:
|
|
111
134
|
|
|
112
|
-
|
|
135
|
+
```ts
|
|
136
|
+
import { createPolyCamera, createPolyScene, loadMesh } from "@layoutit/polycss";
|
|
113
137
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
| `color` | CSS color |
|
|
118
|
-
| `texture` | Image URL |
|
|
119
|
-
| `uvs` | JSON array of `[u,v]` pairs |
|
|
120
|
-
| `position` | Comma-separated `x, y, z` |
|
|
121
|
-
| `scale` | Uniform scale factor |
|
|
122
|
-
| `rotation` | Comma-separated euler degrees `x, y, z` |
|
|
123
|
-
|
|
124
|
-
## Imperative API (escape hatch)
|
|
125
|
-
|
|
126
|
-
For programmatic control without custom elements:
|
|
127
|
-
|
|
128
|
-
```js
|
|
129
|
-
import { createPolyScene, loadMesh } from "@layoutit/polycss";
|
|
130
|
-
|
|
131
|
-
const scene = createPolyScene(document.querySelector("#scene"), {
|
|
132
|
-
perspective: 1000,
|
|
133
|
-
rotX: 65,
|
|
134
|
-
rotY: 45,
|
|
135
|
-
directionalLight: { direction: [0.5, -0.7, 0.6] },
|
|
136
|
-
});
|
|
138
|
+
const host = document.getElementById("polycss")!;
|
|
139
|
+
const camera = createPolyCamera({ rotX: 65, rotY: 45 });
|
|
140
|
+
const scene = createPolyScene(host, { camera });
|
|
137
141
|
|
|
138
|
-
const mesh = await loadMesh("/cottage.
|
|
139
|
-
|
|
142
|
+
const mesh = await loadMesh("https://polycss.com/gallery/obj/cottage.obj", {
|
|
143
|
+
mtlUrl: "https://polycss.com/gallery/obj/cottage.mtl",
|
|
140
144
|
});
|
|
141
|
-
const handle = scene.add(mesh, { position: [0, 0, 0] });
|
|
142
145
|
|
|
143
|
-
|
|
144
|
-
handle.setTransform({ position: [5, 0, 0] });
|
|
145
|
-
handle.remove();
|
|
146
|
-
mesh.dispose();
|
|
146
|
+
scene.add(mesh);
|
|
147
147
|
```
|
|
148
148
|
|
|
149
|
-
|
|
149
|
+
Supported formats:
|
|
150
150
|
|
|
151
|
-
|
|
151
|
+
- OBJ + MTL, including `map_Kd` textures and UV coordinates.
|
|
152
|
+
- glTF / GLB, including embedded images and `TEXCOORD_0`.
|
|
153
|
+
- MagicaVoxel `.vox`, with direct voxel fast paths when eligible.
|
|
154
|
+
- Generated primitives: box, plane, ring, sphere, torus, cylinder, cone, and Platonic solids.
|
|
152
155
|
|
|
153
|
-
|
|
154
|
-
|---|---|---|
|
|
155
|
-
| `perspective` | `number` | CSS perspective distance |
|
|
156
|
-
| `rotX` | `number` | Camera X rotation in degrees |
|
|
157
|
-
| `rotY` | `number` | Camera Y rotation in degrees |
|
|
158
|
-
| `zoom` | `number` | Camera zoom scale |
|
|
159
|
-
| `distance` | `number` | Camera dolly pull-back in CSS pixels |
|
|
160
|
-
| `target` | `Vec3` | World-coordinate camera target |
|
|
161
|
-
| `directionalLight` | `PolyDirectionalLight` | Directional light config |
|
|
162
|
-
| `ambientLight` | `PolyAmbientLight` | Ambient light config |
|
|
163
|
-
| `textureLighting` | `"baked" \| "dynamic"` | Texture lighting mode |
|
|
164
|
-
| `textureQuality` | `number \| "auto"` | Atlas bitmap budget and compositor sprite size |
|
|
165
|
-
| `autoCenter` | `boolean` | Rotate around the union bbox center of added meshes |
|
|
156
|
+
## Performance
|
|
166
157
|
|
|
167
|
-
|
|
158
|
+
PolyCSS renders in the DOM, so performance is mostly determined by how many polygons are mounted and how much texture atlas area they consume. The renderer uses several CSS strategies so simple surfaces stay cheap and textured or irregular surfaces fall back to atlas slices.
|
|
168
159
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
160
|
+
- One visible polygon becomes one leaf DOM element.
|
|
161
|
+
- Flat rectangles and stable quads use solid CSS leaves.
|
|
162
|
+
- Textured polygons are packed into generated texture atlases.
|
|
163
|
+
- Dynamic lighting runs through CSS custom properties instead of per-frame JavaScript.
|
|
164
|
+
- Voxel-shaped meshes mount only camera-facing leaves when the mesh is eligible.
|
|
165
|
+
- `meshResolution: "lossy"` merges compatible polygons, then may spend a small split budget to repair high-risk seams.
|
|
166
|
+
|
|
167
|
+
Renderer internals:
|
|
176
168
|
|
|
177
|
-
|
|
169
|
+
Each visible polygon is emitted as one leaf element; the renderer chooses the least expensive CSS primitive that can represent the polygon, then uses `matrix3d(...)` to place that primitive in 3D space.
|
|
178
170
|
|
|
179
|
-
|
|
180
|
-
|
|
171
|
+
- `<b>` uses `background: currentColor` on a fixed box for solid rectangles and stable quads.
|
|
172
|
+
- `<u>` uses `corner-shape` for stable triangles and beveled-corner solids, with a `border-width` triangle fallback when needed.
|
|
173
|
+
- `<i>` clips solid polygons with `border-shape: polygon(...)` when the browser supports it.
|
|
174
|
+
- `<s>` maps a packed texture-atlas slice with `background-image`, and is the fallback for textured or unsupported shapes.
|
|
181
175
|
|
|
182
|
-
##
|
|
176
|
+
## Packages
|
|
183
177
|
|
|
184
|
-
|
|
|
178
|
+
| Package | Description |
|
|
185
179
|
|---|---|
|
|
186
|
-
|
|
|
187
|
-
|
|
|
180
|
+
| `@layoutit/polycss-core` | Pure math, parsers, lighting, camera helpers, mesh optimization. Zero browser globals. |
|
|
181
|
+
| `@layoutit/polycss` | Vanilla custom elements and imperative `createPolyScene` API. |
|
|
182
|
+
| `@layoutit/polycss-react` | React components, hooks, controls, and core re-exports. |
|
|
183
|
+
| `@layoutit/polycss-vue` | Vue 3 components, composables, controls, and core re-exports. |
|
|
188
184
|
|
|
189
|
-
##
|
|
185
|
+
## Made with PolyCSS
|
|
190
186
|
|
|
191
|
-
|
|
187
|
+
[Layoutit Voxels](https://voxels.layoutit.com)
|
|
188
|
+
-> A CSS Voxel editor
|
|
192
189
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
190
|
+
<img width="1000" height="600" alt="layoutit-voxels" src="https://polycss.com/layoutit-voxels.png" />
|
|
191
|
+
|
|
192
|
+
[Layoutit Terra](https://terra.layoutit.com)
|
|
193
|
+
-> A CSS Terrain Generator
|
|
194
|
+
|
|
195
|
+
<img width="1000" height="601" alt="layoutit-terra" src="https://polycss.com/layoutit-terra.png" />
|
|
197
196
|
|
|
198
|
-
##
|
|
197
|
+
## License
|
|
199
198
|
|
|
200
|
-
|
|
199
|
+
MIT.
|