beckhoff-xts-viewer-3d 5.2.0 → 5.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.
Files changed (38) hide show
  1. package/README.md +35 -8
  2. package/dist/index.cjs +2 -2
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.cts +880 -753
  5. package/dist/index.d.ts +880 -753
  6. package/dist/index.js +2 -2
  7. package/dist/index.js.map +1 -1
  8. package/docs/screenshots/01-packaging-line.webp +0 -0
  9. package/docs/screenshots/02-standard-at.webp +0 -0
  10. package/docs/screenshots/03-eco-at2200.webp +0 -0
  11. package/docs/screenshots/04-nct-tools.webp +0 -0
  12. package/docs/screenshots/05-hygienic-ath.webp +0 -0
  13. package/docs/screenshots/06-hepco-gfx.webp +0 -0
  14. package/docs/screenshots/07-materials-closeup.webp +0 -0
  15. package/docs/screenshots/08-multi-track.webp +0 -0
  16. package/docs/screenshots/09-stations-areas.webp +0 -0
  17. package/docs/screenshots/10-dimensions.webp +0 -0
  18. package/docs/screenshots/11-stator-heatmap.webp +0 -0
  19. package/docs/screenshots/12-collision.webp +0 -0
  20. package/docs/screenshots/13-drive-status.webp +0 -0
  21. package/docs/screenshots/14-feed-segments.webp +0 -0
  22. package/docs/screenshots/15-measurements.webp +0 -0
  23. package/docs/screenshots/16-selection.webp +0 -0
  24. package/docs/screenshots/17-plan-view.webp +0 -0
  25. package/docs/screenshots/18-shadows.webp +0 -0
  26. package/docs/screenshots/19-perf-stress.webp +0 -0
  27. package/docs/screenshots/README.md +106 -46
  28. package/package.json +6 -3
  29. package/docs/screenshots/01-oval-loop.png +0 -0
  30. package/docs/screenshots/02-multi-track.png +0 -0
  31. package/docs/screenshots/03-stations-areas.png +0 -0
  32. package/docs/screenshots/04-stator-heatmap.png +0 -0
  33. package/docs/screenshots/05-collision.png +0 -0
  34. package/docs/screenshots/06-drive-status.png +0 -0
  35. package/docs/screenshots/07-perf-stress.png +0 -0
  36. package/docs/screenshots/08-shadows.png +0 -0
  37. package/docs/screenshots/09-screenshot-export.png +0 -0
  38. package/docs/screenshots/10-feed-segments.png +0 -0
Binary file
@@ -1,63 +1,123 @@
1
1
  # Screenshots
2
2
 
3
- README + docs gallery, captured straight out of the playground via the
4
- viewer's own `exportScreenshot` ref method. No external CAD render or
5
- hand-edit involved — every PNG below was generated by automating the
6
- playground over `window.__viewer`.
3
+ The README and docs-site image strip, captured straight out of the playground
4
+ through the viewer's own `exportScreenshot()` ref method. No external CAD
5
+ render and no hand-editing: every image below was produced by automating the
6
+ playground over `window.__viewer` / `window.__playground`.
7
7
 
8
8
  ## How to refresh
9
9
 
10
- The playground exposes two devtools handles for scripted capture:
11
- `window.__viewer` (Proxy onto the live `XtsViewer3DRef`) and
12
- `window.__setDemo` (switches the active sample by `DemoKey`). It also
13
- ships a Vite dev middleware at `POST /__save-screenshot?path=...` that
14
- writes the body bytes to a whitelisted file under `docs/screenshots/`
15
- (see `vite.config.ts → capturedScreenshotSaver`).
10
+ ```bash
11
+ npm i -g playwright && playwright install chromium # once
12
+ pnpm docs:capture-screenshots # the whole strip
13
+ pnpm docs:capture-screenshots --only 07,12 # by number or filename
14
+ pnpm docs:capture-screenshots --list
15
+ ```
16
16
 
17
- Two ways to refresh:
17
+ [`scripts/capture-screenshots.mjs`](../../scripts/capture-screenshots.mjs)
18
+ boots the playground's Vite dev server in-process, drives it in headless
19
+ Chromium and writes the files here. Playwright is deliberately not a
20
+ dependency of the repo — CI never runs this script and a browser download in
21
+ every install would not pay for itself.
18
22
 
19
- **Manual** (one shot, hand-framed):
23
+ What the script takes care of, and why each part is load-bearing:
20
24
 
21
- 1. `npm run dev` — open the playground.
22
- 2. Pick the demo from the sidebar (names match the filenames below).
23
- 3. Frame the camera (ViewCube for clean isometric / top-down, or the
24
- sidebar's **Reset camera** button for `zoomToFit`).
25
- 4. Open devtools and:
25
+ - **Framing** is computed, not hand-held. A first pass fits the scene AABB to
26
+ the frustum analytically; a second pass renders a 640 × 360 alpha probe,
27
+ measures the bounding box of the non-transparent pixels and dollies + pans
28
+ until the geometry fills 94 % of the frame. An XTS layout is a thin ribbon
29
+ inside a large box, so the box fit alone leaves half the frame empty.
30
+ - **Readiness** is checked in pixels. `getBoundingBox()` goes non-empty as
31
+ soon as the config changes, while the GLBs are still streaming and the scene
32
+ subtree is a Suspense fallback — capturing then yields a blank frame with no
33
+ error. The script waits until an AABB-fit probe actually covers part of its
34
+ frame, and refuses to write a shot whose final frame is under 0.5 % covered.
35
+ - **Fonts are proxied through Node.** Station, area, dimension and annotation
36
+ labels fetch a WOFF from jsDelivr, and the drive-status icons resolve a glyph
37
+ font through `unicode-font-resolver`. A failed label font suspends the whole
38
+ scene; a failed glyph resolve renders a warning icon's "!" as exploded
39
+ geometry. Both are silent, so every font request is served from the Node
40
+ process, which can reach the network through a proxy.
41
+ - **Motion is stopped** before every capture: the mover drivers are switched
42
+ off and each shot sets its mover positions explicitly, so a re-run produces
43
+ the same image.
44
+
45
+ ## Format
46
+
47
+ 1920 × 1080 WebP at quality 0.92 on a solid `#eef0f3` ground, 4× MSAA. Full HD
48
+ is what the README and the docs site actually display, and the whole strip
49
+ weighs ~1.4 MB — it ships inside the npm tarball (`package.json#files`).
50
+
51
+ The ground is deliberately opaque rather than the transparent alpha the old
52
+ PNGs used: the AT2 housings are anodised anthracite (`#34383c`, see
53
+ [`scripts/materialLibrary.mjs`](../../scripts/materialLibrary.mjs)) and
54
+ disappear into a dark-mode README on a transparent canvas. `--background
55
+ transparent`, `--format png`, `--width`, `--height`, `--samples`, `--quality`
56
+ and `--fill` override the defaults for a one-off.
57
+
58
+ ## File map
59
+
60
+ Every shot is taken from one of the machine layouts in
61
+ [`playground/src/configs.ts`](../../playground/src/configs.ts) — closed,
62
+ buildable tracks with the infeed modules, station stops and zones where a real
63
+ line would have them, rather than the calibration chains that visit every
64
+ module type in one run. A unit test pins that each layout closes.
65
+
66
+ | File | Demo key | Camera | Shows |
67
+ | --------------------------- | ----------------- | -------------- | ------------------------------------------------- |
68
+ | `01-packaging-line.webp` | `line-standard` | 3⁄4 isometric | hero — 5 m racetrack, 10 movers |
69
+ | `02-standard-at.webp` | `line-standard` | steep 3⁄4 | Standard AT: AT2001 / AT2000 / AT2050 |
70
+ | `03-eco-at2200.webp` | `line-eco` | 3⁄4 isometric | Eco AT2200 / AT2202 |
71
+ | `04-nct-tools.webp` | `line-nct` | 3⁄4 isometric | NCT modules + AT8200 tool carriers |
72
+ | `05-hygienic-ath.webp` | `line-hygienic` | 3⁄4 isometric | Hygienic ATH |
73
+ | `06-hepco-gfx.webp` | `line-standard` ¹ | 3⁄4 isometric | Hepco GFX2 rail and carriage |
74
+ | `07-materials-closeup.webp` | `line-standard` | close, low | PBR materials, stator packs, type plate |
75
+ | `08-multi-track.webp` | `line-dual` | steep 3⁄4 | two lines placed with `trackTransform` |
76
+ | `09-stations-areas.webp` | `line-standard` | steep 3⁄4 | stations, stops, ghost movers, zones |
77
+ | `10-dimensions.webp` | `line-standard` | steep 3⁄4 | dimensions along the track |
78
+ | `11-stator-heatmap.webp` | `line-standard` | steep 3⁄4 | green → red gradient along the centerline |
79
+ | `12-collision.webp` | `line-standard` | close 3⁄4 | two movers parked at a 1 mm overlap |
80
+ | `13-drive-status.webp` | `drive-status` | steep 3⁄4 | warning / error icons + tinted modules and movers |
81
+ | `14-feed-segments.webp` | `line-standard` | steep 3⁄4 | one strand per infeed, wrapping the loop seam |
82
+ | `15-measurements.webp` | `line-standard` | steep 3⁄4 | distance with ΔX/ΔY guides + two annotations |
83
+ | `16-selection.webp` | `line-standard` | steep 3⁄4 | two modules and one mover selected |
84
+ | `17-plan-view.webp` | `line-standard` | top-down ortho | `exportScreenshot({ mode: 'top-down' })` |
85
+ | `18-shadows.webp` | `line-standard` | low 3⁄4 | PCF-soft shadows + IBL |
86
+ | `19-perf-stress.webp` | `perf-stress` | steep 3⁄4 | 3 ovals × 250 movers = 750 |
87
+
88
+ ¹ with `railSystem: 'HepcoGfx'` and a GFX2 1TC carriage.
89
+
90
+ The shot list itself lives at the top of the capture script; adding an image
91
+ means adding one entry there, not writing browser code.
92
+
93
+ ## Doing it by hand
94
+
95
+ The playground still exposes the devtools handles the script drives, so a
96
+ one-off shot needs no tooling:
97
+
98
+ 1. `pnpm dev`, pick the demo from the sidebar, frame the camera.
99
+ 2. In the console:
26
100
 
27
101
  ```js
28
102
  const r = await window.__viewer.exportScreenshot({
29
- mode: 'current', // or 'top-down'
30
- pixelRatio: 2,
31
- format: 'png',
32
- backgroundColor: null, // transparent
103
+ mode: 'current',
104
+ width: 1920,
105
+ height: 1080,
106
+ samples: 4,
107
+ format: 'webp',
108
+ quality: 0.92,
109
+ backgroundColor: '#eef0f3',
33
110
  });
34
- await fetch('/__save-screenshot?path=docs/screenshots/02-multi-track.png', {
111
+ await fetch('/__save-screenshot?path=docs/screenshots/08-multi-track.webp', {
35
112
  method: 'POST',
36
113
  body: r.blob,
37
- headers: { 'content-type': 'image/png' },
114
+ headers: { 'content-type': 'image/webp' },
38
115
  });
39
116
  ```
40
117
 
41
- **Automated** (re-shoot the whole gallery): drive the same loop over the
42
- demo keys below from any browser-automation tool (Claude Preview / in
43
- Chrome MCP, Playwright, …). Switch with `window.__setDemo('<key>')`,
44
- wait ~2 s for GLBs + initial frame, then call the eval above.
45
-
46
- ## File map
47
-
48
- | File | Demo key | Camera | Notes |
49
- | -------------------------- | --------------------------------- | -------------- | ---------------------------------------------------------------------------- |
50
- | `01-oval-loop.png` | `oval-loop` | 3⁄4 isometric | hero shot, env reflections on |
51
- | `02-multi-track.png` | `multi-track` | 3⁄4 isometric | shows `trackTransform` placement |
52
- | `03-stations-areas.png` | `areas` | 3⁄4 isometric | cleanroom / safety-loop tubes |
53
- | `04-stator-heatmap.png` | `heatmap` | 3⁄4 isometric | green → red gradient, `displacementMm: 35` lifts the tube above the rail |
54
- | `05-collision.png` | `collision` | 3⁄4 isometric | two movers touching mid-track |
55
- | `06-drive-status.png` | `drive-status` | 3⁄4 isometric | pulsing emissives + ▲ / ⊙ status icons |
56
- | `07-perf-stress.png` | `perf-stress` | wide isometric | 3 ovals × 250 movers = 750 |
57
- | `08-shadows.png` | `standard` + shadows on | low-angle | PCF-soft shadows + IBL |
58
- | `09-screenshot-export.png` | `oval-loop` | top-down ortho | demonstrates `exportScreenshot('top-down')` itself |
59
- | `10-feed-segments.png` | `eco` + both feed segments ticked | 3⁄4 isometric | `feedSegmentHighlights` — strand 0 blue, strand 1 pink (wraps the loop seam) |
60
-
61
- All PNGs are RGBA with a transparent alpha channel, captured at
62
- `pixelRatio: 2` (~3000 × 2400 px) so they stay crisp at 1× and shrink
63
- cleanly to the README's two-column gallery rendering.
118
+ `window.__setDemo('<DemoKey>')` switches the sample, `window.__playground`
119
+ holds the sidebar toggles the script uses (shadows, stations, dimensions,
120
+ selection, feed-segment colours, …) and the dev-only `POST
121
+ /__save-screenshot?path=…` middleware in
122
+ [`vite.config.ts`](../../vite.config.ts) writes the body bytes to a
123
+ whitelisted path under `docs/screenshots/`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "beckhoff-xts-viewer-3d",
3
- "version": "5.2.0",
3
+ "version": "5.2.2",
4
4
  "description": "Reusable React component for rendering Beckhoff XTS linear-motor systems in 3D using Three.js",
5
5
  "keywords": [
6
6
  "xts",
@@ -38,7 +38,7 @@
38
38
  },
39
39
  "files": [
40
40
  "dist",
41
- "docs/screenshots/*.png",
41
+ "docs/screenshots/*.webp",
42
42
  "README.md",
43
43
  "LICENSE"
44
44
  ],
@@ -57,6 +57,7 @@
57
57
  "sync-assets-cdn-version": "node scripts/sync-assets-cdn-version.mjs",
58
58
  "dev": "vite",
59
59
  "playground:build": "vite build",
60
+ "docs:capture-screenshots": "node scripts/capture-screenshots.mjs",
60
61
  "docs:copy-screenshots": "node scripts/docs-copy-screenshots.mjs",
61
62
  "docs:dev": "pnpm run docs:copy-screenshots && vitepress dev docs",
62
63
  "docs:build": "pnpm run docs:copy-screenshots && vitepress build docs",
@@ -175,6 +176,7 @@
175
176
  "esbuild"
176
177
  ],
177
178
  "//-overrides": "Transitive dev-only dependencies pinned forward to their patched releases so `pnpm audit` stays clean. None of these reach the published bundle — dist/ contains only src/ with the peer deps externalised. Keyed by major where several majors coexist in the tree. Drop an entry once every direct dependency has caught up on its own.",
179
+ "//-overrides-vite": "vite@5 is the one entry that crosses a major: vitepress 1.6.4 depends on vite ^5.4.14, and the fs.deny / path-traversal / launch-editor advisories are only fixed from 6.4.2 onward — the 5.x line ends at 5.4.21 with no patch. Verified against this combination: docs:dev serves, docs:build and docs:build:all both complete. Drop it for a plain vitepress bump as soon as vitepress 2 leaves alpha, since 2.x is on vite 6+ on its own.",
178
180
  "overrides": {
179
181
  "brace-expansion@2": "^2.1.4",
180
182
  "esbuild@0.21": "^0.25.12",
@@ -185,7 +187,8 @@
185
187
  "sharp": "^0.35.0",
186
188
  "tmp": "^0.2.7",
187
189
  "undici@6": "^6.27.0",
188
- "undici@7": "^7.29.0"
190
+ "undici@7": "^7.29.0",
191
+ "vite@5": "^6.4.3"
189
192
  }
190
193
  }
191
194
  }
Binary file
Binary file
Binary file
Binary file
Binary file