Task-focused snippets. All use the shared <GcodePreview> surface unless noted.
Clip to a layer range and scrub within it — no geometry rebuilds, just draw-range updates:
<GcodePreview source={file} layerRange={[0, 73]} scrub={0.5} />
<GcodePreview source={file} quality="tubes" colorMode="feature" cameraMode="orthographic" />
colorMode is capability-gated — the stack colors by a feature only when the dialect actually
disclosed it (see ToolpathIR & the capability model).
The imperative controls handle (the composable return / React ref / Svelte bind:this / element
instance) exposes preset orientations and a serializable camera snapshot:
const { controls } = preview; // or handleRef.current, etc.
controls.setView('iso'); // 'top' | 'bottom' | 'front' | 'back' | 'left' | 'right' | 'iso'
controls.frame(); // re-fit to the model bounds
controls.setCameraMode('orthographic'); // perspective ↔ ortho
// Persist "where the user was looking" and restore it later (e.g. a dashboard).
const view = controls.getCameraState(); // { position, target, zoom, cameraMode } | null
localStorage.setItem('view', JSON.stringify(view));
controls.setCameraState(view); // restores verbatim — no re-fit to the current model
setView snaps instantly (no animation) and preserves the active projection. getCameraState
returns null on the low-resource 2D renderer, which has no 3D pose — setView/setCameraState
there disclose via the renderer-unsupported event rather than fabricating one.
The same three are also declarative props on every adapter — a view prop (preset) and a
cameraState prop (restore) — paired with a camerachange/camera-change event that fires with
the new CameraState after a user orbits/pans/zooms. Together they form a two-way binding you can
persist:
<GcodePreview {source} {view} bind:cameraState on:camerachange={(e) => save(e.detail)} />
readyThe ready event (React onReady, Vue @ready, Svelte on:ready, element ready) carries
capabilities (the per-field known | inferred | approximated | unavailable map) and warnings
alongside { segments, layers, complete } — so a consumer can gate its own UI (e.g. only offer a
color-by-power control when capabilities.toolPower !== 'unavailable') without reaching for the raw
handle.
.gcode.3mf multi-plate.gcode.3mf containers can hold several sliced plates. Select one with parseOptions.plate:
<GcodePreview source={file} parseOptions={{ plate: 1 }} />
By default the adapters create a batteries worker (every dialect adapter + .gcode.3mf) via the
bundler-native new Worker(new URL(...)) pattern. Pass createWorker to supply your own — a slim
build, custom dialects, or a CSP-friendly setup:
<GcodePreview source={file} createWorker={() => new Worker(new URL('./my-worker.js', import.meta.url), { type: 'module' })} />
Feed a normalized ProgressObservation and the preview maps it onto the toolpath with honest,
tiered confidence — a precise marker when the source position is known, an uncertainty band when it
is approximate, and user scrub always winning. See
Live progress & motion model and the
progress signal contract.
<GcodePreview source={file} progress={observation} />
renderStill from @chestnutlabs/gcode-renderer-three produces a single non-interactive image from
a Worker OffscreenCanvas, an Electron hidden window, or headless Chromium — no interactive viewer
required. See the
still-render reference.
Mount multiple <GcodePreview> instances — each owns its own worker and renderer. See the
multi-gcode note
for the current guidance and its trade-offs.