UIKitDocument
UIKitDocument wraps the interpreted UIKit component tree in a THREE.Group and exposes DOM‑like query helpers and sizing utilities.
What It Provides
DOM‑like queries:
getElementById(id)getElementsByClassName(name)querySelector(selector)/querySelectorAll(selector)- Simple selectors supported:
#id,.class, and descendant combinators like#parent .child.
Physical sizing in meters:
setTargetDimensions(widthMeters, heightMeters)computes a uniform scale from the component’s intrinsic cm size.- Keeps aspect ratio stable; ideal for XR where 1 unit = 1 meter.
Lifecycle:
- A
dispose()method cleans up signals and components.
- A
Using with IWSDK Systems
PanelUISystemloads JSON, interprets it, createsUIKitDocument, and attaches it to your entity’sobject3D.ScreenSpaceUISystemre‑parents the document under the camera with CSS‑like positioning when XR is not presenting.- Pointer events are forwarded (configurable) so UI elements receive hover/active/focus state.
Examples
Querying by ID and class:
ts
// Access the document from the entity’s PanelDocument component
const doc = entity.getValue(PanelDocument, 'document'); // UIKitDocument
const button = doc.getElementById('start');
const rows = doc.getElementsByClassName('row');
// Descendant query
const label = doc.querySelector('#menu .title');Setting a physical target size (meters):
ts
doc.setTargetDimensions(1.0, 0.6); // ~1m wide panel, height constrained to aspectSee also: UIKit, Screen‑space vs World‑space Flow
How Sizing Works
- UIKit components report an intrinsic size in centimeters (via their
sizesignal). UIKitDocumentconverts target meters to a uniform scale:uiWidthMeters = intrinsicWidthCm / 100scale = min(targetWidth / uiWidthMeters, targetHeight / uiHeightMeters)
- The scale is applied to the
Group(document), not individual components, preserving internal layout.
Selectors and Limitations
- Supported:
#id,.class, descendant combinators (e.g.,#menu .row .button). - Not supported: attribute selectors, pseudo‑classes beyond UIKit state (
hover,active,focus). - Performance: cache query results you reuse in systems; avoid repeated deep queries inside per‑frame loops.
Integrating Interactions
- Pointer events forwarded by IWSDK will toggle
hover/active/focusstate on elements, which in turn applies conditional styles. - For custom behavior, subscribe to your ECS input/pointer systems and call methods or set properties on matched components.
ts
const start = doc.getElementById('start');
// Example: toggle a class on app state change
if (isLocked) start?.classList.add('disabled');
else start?.classList.remove('disabled');Lifecycle and Cleanup
- When removing a panel, call
dispose()(done byPanelUISystem.cleanupPanel) to detach listeners and release resources. - After disposal, references to components are invalid; re‑query after re‑creating the document.
Debugging Tips
- Log
doc.toString()to see element/class counts and computed sizes. - Use IDs and class names consistently in
.uikitmlso selectors remain stable during iteration.