@womp/kakapo-web
v0.1.1
Published
Kakapo scenes in the browser: the viewer loads a scene, models each object on the GPU and renders it on a canvas. OpenSCAD knobs can be changed live.
Keywords
Readme
@womp/kakapo-web
Kakapo scenes in the browser: the viewer loads a scene, models each object on the GPU and renders it on a canvas. OpenSCAD knobs can be changed live.
Needs WebGPU (core features, default limits). ES modules, with TypeScript types.
Viewer
import { createViewer } from "@womp/kakapo-web"
const viewer = await createViewer(canvas, { sceneUrl: "https://example.com/scene.json" })createViewer(canvas, options) resolves once the scene is loaded and its knobs are known. Modelling then
continues in the background.
| Option | Type | Default | |
|---|---|---|---|
| sceneUrl | string | required | the scene JSON |
| quality | number, 0..1 | 0.3 on phones, 0.5 elsewhere | modelling resolution |
| shadows | boolean | true | |
| msaa | boolean | true | 4× multisampling |
| insets | () => Insets | none | the CSS pixels of the canvas your UI covers, kept clear when framing |
| onProgress | ({ built, total }) => void | | modelling progress; built === total when idle |
| onError | (e: ViewerError) => void | | errors after startup |
| Method | |
|---|---|
| getScripts(): Script[] | the visible OpenSCAD scripts and their knobs |
| setParams(values: Params, nodeId?: number) | sets knobs on one script, or on every script that declares them; re-models only the objects that change |
| resetParams(nodeId?: number) | back to the scene file's values |
| setScene(url: string): Promise<boolean> | swaps in another revision of the same scene, re-modelling only what changed; false if a later call or destroy superseded it |
| frame(nodeId?: number) | points the camera at the object holding nodeId, or at the whole scene, which then stays framed on resize |
| destroy() | releases the GPU device and the listeners |
type ParamValue = number | boolean | string | ParamValue[]
type Params = Record<string, ParamValue>
interface Script {
nodeId: number
name: string
params: ParamSpec[]
warnings: string[]
error: string
}
interface ParamSpec {
name: string
value: ParamValue
defaultValue: ParamValue
min?: number
max?: number
step?: number
options?: { value: number | string; label: string }[]
section?: string
}
interface Insets {
left: number
right: number
top: number
bottom: number
}Errors
Failures are ViewerErrors, with a code:
| code | From | |
|---|---|---|
| no-scene | createViewer | sceneUrl is empty |
| no-webgpu | createViewer | no WebGPU, adapter or device |
| scene-load | createViewer, setScene | the scene cannot be fetched or parsed |
| scene-mismatch | setScene | the revision's objects differ; create a new viewer for it |
| device-lost | onError | the GPU device was lost and the viewer stops |
| build | onError | one object could not be modelled; the others carry on |
Behaviour
- The viewer fetches only scenes:
sceneUrland the URLs given tosetScene. Its fonts and environment map are built in, at about 2 MB of the JavaScript (1.26 MB gzipped). - It draws only on
canvas. - Text is set in Roboto Medium, with Noto Emoji for the characters Roboto lacks. The scene's font family, weight and italic are ignored.
- Every scene is lit by the built-in environment map, whatever
hdr_nameit names.
Knob UI
import { createUi } from "@womp/kakapo-web/ui"
const ui = createUi(container, { shownParams: ["wall"], onChange, onPrint })
const viewer = await createViewer(canvas, { sceneUrl, insets: () => ui.insets(canvas) })
ui.setViewer(viewer)A panel over the canvas with every visible script's knobs, Focus and Reset per script, a status line, and
a Print button when onPrint is given. container must be positioned and hold the canvas; the panel
lives in a shadow root inside it.
| UiOptions | |
|---|---|
| shownParams?: string[] | shows only these knobs |
| onChange?: () => void | the user turned a knob or reset a script |
| onPrint?: () => void | adds the Print button |
| Ui | |
|---|---|
| setViewer(viewer: Viewer) | the viewer whose knobs the panel shows |
| refresh() | redraws the knobs after they change elsewhere |
| setStatus(text: string \| null) | the status line; null hides it |
| insets(canvas: HTMLElement): Insets | the part of the canvas the panel covers |
| destroy() | removes the panel |
Not part of the contract
@womp/kakapo-web/dev exposes internals for benchmarks and debugging, and changes with the
implementation.
Licences
The built-in fonts are Roboto (Apache License 2.0) and Noto Emoji (SIL Open Font License 1.1); their
licence texts are in src/viewer/assets/. The environment map is Womp's own.
