@relu-interactives/spatial-ecs 0.8.0 → 0.9.0
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/dist/{XRHandPose-G0Dl-F0w.d.ts → XRHandPose-CWSrsnYN.d.ts} +144 -1
- package/dist/{XRHandPose-VQMT1WXj.d.cts → XRHandPose-Dn2yiALk.d.cts} +144 -1
- package/dist/{chunk-G4XJ53LS.js → chunk-JEPUCLZX.js} +3 -3
- package/dist/{chunk-G4XJ53LS.js.map → chunk-JEPUCLZX.js.map} +1 -1
- package/dist/{chunk-NNDUOQ7O.js → chunk-JNYPJB55.js} +250 -3
- package/dist/chunk-JNYPJB55.js.map +1 -0
- package/dist/{chunk-SGF73YTF.js → chunk-NXASMBDS.js} +4 -4
- package/dist/{chunk-SGF73YTF.js.map → chunk-NXASMBDS.js.map} +1 -1
- package/dist/{chunk-JIJQFW6P.js → chunk-VYIWOXAY.js} +1377 -480
- package/dist/chunk-VYIWOXAY.js.map +1 -0
- package/dist/{chunk-U727NTWQ.js → chunk-WWP46AEF.js} +26 -4
- package/dist/chunk-WWP46AEF.js.map +1 -0
- package/dist/components/index.cjs +151 -0
- package/dist/components/index.cjs.map +1 -1
- package/dist/components/index.d.cts +2 -2
- package/dist/components/index.d.ts +2 -2
- package/dist/components/index.js +1 -1
- package/dist/docs/guide/spatial-ui.md +83 -7
- package/dist/factories/index.cjs +151 -0
- package/dist/factories/index.cjs.map +1 -1
- package/dist/factories/index.d.cts +1 -1
- package/dist/factories/index.d.ts +1 -1
- package/dist/factories/index.js +3 -3
- package/dist/{index-D9DjrUn3.d.cts → index-CAZHrh0q.d.cts} +5 -2
- package/dist/{index-DppafVu4.d.ts → index-CLtSMf2M.d.ts} +5 -2
- package/dist/{index-C61n65PE.d.ts → index-D5MmJNyj.d.ts} +26 -1
- package/dist/{index-C70N4BYG.d.cts → index-DiIjV2lm.d.cts} +26 -1
- package/dist/index.cjs +1787 -621
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.js +10 -10
- package/dist/network/index.cjs +177 -4
- package/dist/network/index.cjs.map +1 -1
- package/dist/network/index.js +3 -3
- package/dist/systems/index.cjs +1689 -523
- package/dist/systems/index.cjs.map +1 -1
- package/dist/systems/index.d.cts +1 -1
- package/dist/systems/index.d.ts +1 -1
- package/dist/systems/index.js +4 -4
- package/package.json +1 -1
- package/dist/chunk-JIJQFW6P.js.map +0 -1
- package/dist/chunk-NNDUOQ7O.js.map +0 -1
- package/dist/chunk-U727NTWQ.js.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { A as AnimationComponent, a as AnimationComponentOptions, b as AudioComponent, B as BoneAttachmentComponent, c as BoneAttachmentOptions, C as CameraComponent, d as CameraComponentOptions, e as CameraProjection, f as CameraRuntimeType, g as ColliderShape, h as ColliderState, i as CubeMeshParameters, D as DEFAULT_COLLIDER_STATE, j as DEFAULT_INSTANCED_MESH_PARAMETERS, k as DEFAULT_INSTANCE_TRANSFORM, l as DEFAULT_MESH_GEOMETRY_PARAMETERS, m as DEFAULT_PHYSICS_STATE, n as DEFAULT_POSE_CURLS, o as DEFAULT_POSE_DIRECTIONS, p as DEFAULT_RIGIDBODY_STATE, E as EditableMeshObjectKind, q as EntityType, I as ImageComponent, r as ImageTarget, s as ImageTargetAnchor, t as ImageTargetAnchorOptions, u as ImageTargetReference, v as InstanceSlotComponent, w as InstanceTransform, x as InstancedMeshComponent, y as InstancedMeshKind, L as LightComponent, z as LightShadowState, F as LightValueState, M as MODEL_NO_PATH_MESSAGE, G as MaterialComponent, H as MaterialTypeValue, J as MaterialValueState, K as MeshComponent, N as MeshGeometryComponent, O as MeshGeometryParameters, P as MeshGeometryParametersByKind, Q as ModelComponent, R as ModelLoadState, S as Name, T as Object3DRef, U as PhysicsComponent, V as PhysicsState, W as PlaneMeshParameters, X as RadiusHeightMeshParameters, Y as RadiusMeshParameters, Z as RigidbodyState, _ as RigidbodyType, $ as ScriptComponent, a0 as ScriptEntry, a1 as ScriptObjectComponent, a2 as ScriptObjectComponentInput, a3 as ScriptObjectRuntimeState, a4 as Selectable, a5 as SelectionTransformState, a6 as SpriteComponent, a7 as TextureFilteringValue, a8 as TransformModeValue, a9 as TransformSpaceValue, aa as UIButtonComponent, ab as UIButtonOptions, ac as UIPanelComponent, ad as UIPanelOptions, ae as UISliderComponent, af as UISliderOptions, ag as UITextComponent, ah as UITextOptions, ai as UIToggleComponent, aj as UIToggleOptions, ak as UiFollowMode, al as
|
|
1
|
+
export { A as AnimationComponent, a as AnimationComponentOptions, b as AudioComponent, B as BoneAttachmentComponent, c as BoneAttachmentOptions, C as CameraComponent, d as CameraComponentOptions, e as CameraProjection, f as CameraRuntimeType, g as ColliderShape, h as ColliderState, i as CubeMeshParameters, D as DEFAULT_COLLIDER_STATE, j as DEFAULT_INSTANCED_MESH_PARAMETERS, k as DEFAULT_INSTANCE_TRANSFORM, l as DEFAULT_MESH_GEOMETRY_PARAMETERS, m as DEFAULT_PHYSICS_STATE, n as DEFAULT_POSE_CURLS, o as DEFAULT_POSE_DIRECTIONS, p as DEFAULT_RIGIDBODY_STATE, E as EditableMeshObjectKind, q as EntityType, I as ImageComponent, r as ImageTarget, s as ImageTargetAnchor, t as ImageTargetAnchorOptions, u as ImageTargetReference, v as InstanceSlotComponent, w as InstanceTransform, x as InstancedMeshComponent, y as InstancedMeshKind, L as LightComponent, z as LightShadowState, F as LightValueState, M as MODEL_NO_PATH_MESSAGE, G as MaterialComponent, H as MaterialTypeValue, J as MaterialValueState, K as MeshComponent, N as MeshGeometryComponent, O as MeshGeometryParameters, P as MeshGeometryParametersByKind, Q as ModelComponent, R as ModelLoadState, S as Name, T as Object3DRef, U as PhysicsComponent, V as PhysicsState, W as PlaneMeshParameters, X as RadiusHeightMeshParameters, Y as RadiusMeshParameters, Z as RigidbodyState, _ as RigidbodyType, $ as ScriptComponent, a0 as ScriptEntry, a1 as ScriptObjectComponent, a2 as ScriptObjectComponentInput, a3 as ScriptObjectRuntimeState, a4 as Selectable, a5 as SelectionTransformState, a6 as SpriteComponent, a7 as TextureFilteringValue, a8 as TransformModeValue, a9 as TransformSpaceValue, aa as UIButtonComponent, ab as UIButtonOptions, ac as UIPanelComponent, ad as UIPanelOptions, ae as UISliderComponent, af as UISliderOptions, ag as UITextComponent, ah as UITextOptions, ai as UIToggleComponent, aj as UIToggleOptions, ak as UiFollowMode, al as UiIconPosition, am as UiSliderVariant, an as UiTextAlign, ao as UiTextVAlign, ap as UiToggleVariant, aq as VRTeleportAreaComponent, ar as VRTeleportAreaOptions, as as VideoComponent, at as VrTeleportShape, au as XRAnchorComponent, av as XRAnchorOptions, aw as XRHandPoseComponent, ax as XRHandPoseOptions, ay as XRInteractableComponent, az as XRInteractableOptions, aA as XRInteractorComponent, aB as XRInteractorOptions, aC as XRInteractorSideComponent, aD as XRRigComponent, aE as XRRigOptions, aF as XrAttachPoint, aG as XrDistanceGrabBehavior, aH as XrEnvironmentPhysics, aI as XrGrabGesture, aJ as XrGrabHands, aK as XrGrabReach, aL as XrHandPoseEntry, aM as XrHandPreset, aN as XrInteractorSide, aO as XrInteractorType, aP as XrLocomotionMode, aQ as XrTrackingOrigin, aR as XrTwoHandRotation, aS as createAttachPoint, aT as createHandPoseEntry, aU as defaultMaterialValue, aV as handPoseDefinitionFor, aW as normalizePhysicsState, aX as setModelLoadState, aY as setPhysicsLiveRef } from '../XRHandPose-Dn2yiALk.cjs';
|
|
2
2
|
export { D as DEFAULT_ENVIRONMENT_LIGHTING, a as DEFAULT_ENVIRONMENT_STATE, b as DEFAULT_POSTPROCESSING_STATE, E as Environment, c as EnvironmentFogState, d as EnvironmentFogType, e as EnvironmentGradientEffect, f as EnvironmentLightingState, g as EnvironmentSkyboxImageProjection, h as EnvironmentSkyboxState, i as EnvironmentSkyboxType, j as EnvironmentState, k as EnvironmentToneMapping, I as IKChain, l as IKComponent, m as IKLimb, n as IKOptions, N as NetValue, o as NetworkIdentityComponent, p as NetworkSpawnerComponent, q as NetworkTransformComponent, r as NetworkTransformOptions, s as NetworkedPropsComponent, P as ParentId, t as Postprocessing, u as PostprocessingState, T as TransformComponent, v as TransformData, V as Vec3, w as normalizeEnvironmentLighting, x as normalizeIKChain } from '../System-8D-XBDKZ.cjs';
|
|
3
|
-
export { P as PrefabInstance, a as PrefabNode, X as XREnvironmentComponent, b as XrEnvironmentKind, c as XrEnvironmentOrientation } from '../index-
|
|
3
|
+
export { P as PrefabInstance, a as PrefabNode, X as XREnvironmentComponent, b as XrEnvironmentKind, c as XrEnvironmentOrientation } from '../index-CAZHrh0q.cjs';
|
|
4
4
|
import 'three';
|
|
5
5
|
import '@dimforge/rapier3d-compat';
|
|
6
6
|
import '../handPose-DlcTtqgx.cjs';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { A as AnimationComponent, a as AnimationComponentOptions, b as AudioComponent, B as BoneAttachmentComponent, c as BoneAttachmentOptions, C as CameraComponent, d as CameraComponentOptions, e as CameraProjection, f as CameraRuntimeType, g as ColliderShape, h as ColliderState, i as CubeMeshParameters, D as DEFAULT_COLLIDER_STATE, j as DEFAULT_INSTANCED_MESH_PARAMETERS, k as DEFAULT_INSTANCE_TRANSFORM, l as DEFAULT_MESH_GEOMETRY_PARAMETERS, m as DEFAULT_PHYSICS_STATE, n as DEFAULT_POSE_CURLS, o as DEFAULT_POSE_DIRECTIONS, p as DEFAULT_RIGIDBODY_STATE, E as EditableMeshObjectKind, q as EntityType, I as ImageComponent, r as ImageTarget, s as ImageTargetAnchor, t as ImageTargetAnchorOptions, u as ImageTargetReference, v as InstanceSlotComponent, w as InstanceTransform, x as InstancedMeshComponent, y as InstancedMeshKind, L as LightComponent, z as LightShadowState, F as LightValueState, M as MODEL_NO_PATH_MESSAGE, G as MaterialComponent, H as MaterialTypeValue, J as MaterialValueState, K as MeshComponent, N as MeshGeometryComponent, O as MeshGeometryParameters, P as MeshGeometryParametersByKind, Q as ModelComponent, R as ModelLoadState, S as Name, T as Object3DRef, U as PhysicsComponent, V as PhysicsState, W as PlaneMeshParameters, X as RadiusHeightMeshParameters, Y as RadiusMeshParameters, Z as RigidbodyState, _ as RigidbodyType, $ as ScriptComponent, a0 as ScriptEntry, a1 as ScriptObjectComponent, a2 as ScriptObjectComponentInput, a3 as ScriptObjectRuntimeState, a4 as Selectable, a5 as SelectionTransformState, a6 as SpriteComponent, a7 as TextureFilteringValue, a8 as TransformModeValue, a9 as TransformSpaceValue, aa as UIButtonComponent, ab as UIButtonOptions, ac as UIPanelComponent, ad as UIPanelOptions, ae as UISliderComponent, af as UISliderOptions, ag as UITextComponent, ah as UITextOptions, ai as UIToggleComponent, aj as UIToggleOptions, ak as UiFollowMode, al as
|
|
1
|
+
export { A as AnimationComponent, a as AnimationComponentOptions, b as AudioComponent, B as BoneAttachmentComponent, c as BoneAttachmentOptions, C as CameraComponent, d as CameraComponentOptions, e as CameraProjection, f as CameraRuntimeType, g as ColliderShape, h as ColliderState, i as CubeMeshParameters, D as DEFAULT_COLLIDER_STATE, j as DEFAULT_INSTANCED_MESH_PARAMETERS, k as DEFAULT_INSTANCE_TRANSFORM, l as DEFAULT_MESH_GEOMETRY_PARAMETERS, m as DEFAULT_PHYSICS_STATE, n as DEFAULT_POSE_CURLS, o as DEFAULT_POSE_DIRECTIONS, p as DEFAULT_RIGIDBODY_STATE, E as EditableMeshObjectKind, q as EntityType, I as ImageComponent, r as ImageTarget, s as ImageTargetAnchor, t as ImageTargetAnchorOptions, u as ImageTargetReference, v as InstanceSlotComponent, w as InstanceTransform, x as InstancedMeshComponent, y as InstancedMeshKind, L as LightComponent, z as LightShadowState, F as LightValueState, M as MODEL_NO_PATH_MESSAGE, G as MaterialComponent, H as MaterialTypeValue, J as MaterialValueState, K as MeshComponent, N as MeshGeometryComponent, O as MeshGeometryParameters, P as MeshGeometryParametersByKind, Q as ModelComponent, R as ModelLoadState, S as Name, T as Object3DRef, U as PhysicsComponent, V as PhysicsState, W as PlaneMeshParameters, X as RadiusHeightMeshParameters, Y as RadiusMeshParameters, Z as RigidbodyState, _ as RigidbodyType, $ as ScriptComponent, a0 as ScriptEntry, a1 as ScriptObjectComponent, a2 as ScriptObjectComponentInput, a3 as ScriptObjectRuntimeState, a4 as Selectable, a5 as SelectionTransformState, a6 as SpriteComponent, a7 as TextureFilteringValue, a8 as TransformModeValue, a9 as TransformSpaceValue, aa as UIButtonComponent, ab as UIButtonOptions, ac as UIPanelComponent, ad as UIPanelOptions, ae as UISliderComponent, af as UISliderOptions, ag as UITextComponent, ah as UITextOptions, ai as UIToggleComponent, aj as UIToggleOptions, ak as UiFollowMode, al as UiIconPosition, am as UiSliderVariant, an as UiTextAlign, ao as UiTextVAlign, ap as UiToggleVariant, aq as VRTeleportAreaComponent, ar as VRTeleportAreaOptions, as as VideoComponent, at as VrTeleportShape, au as XRAnchorComponent, av as XRAnchorOptions, aw as XRHandPoseComponent, ax as XRHandPoseOptions, ay as XRInteractableComponent, az as XRInteractableOptions, aA as XRInteractorComponent, aB as XRInteractorOptions, aC as XRInteractorSideComponent, aD as XRRigComponent, aE as XRRigOptions, aF as XrAttachPoint, aG as XrDistanceGrabBehavior, aH as XrEnvironmentPhysics, aI as XrGrabGesture, aJ as XrGrabHands, aK as XrGrabReach, aL as XrHandPoseEntry, aM as XrHandPreset, aN as XrInteractorSide, aO as XrInteractorType, aP as XrLocomotionMode, aQ as XrTrackingOrigin, aR as XrTwoHandRotation, aS as createAttachPoint, aT as createHandPoseEntry, aU as defaultMaterialValue, aV as handPoseDefinitionFor, aW as normalizePhysicsState, aX as setModelLoadState, aY as setPhysicsLiveRef } from '../XRHandPose-CWSrsnYN.js';
|
|
2
2
|
export { D as DEFAULT_ENVIRONMENT_LIGHTING, e as DEFAULT_ENVIRONMENT_STATE, f as DEFAULT_POSTPROCESSING_STATE, g as Environment, h as EnvironmentFogState, i as EnvironmentFogType, j as EnvironmentGradientEffect, k as EnvironmentLightingState, l as EnvironmentSkyboxImageProjection, m as EnvironmentSkyboxState, n as EnvironmentSkyboxType, o as EnvironmentState, p as EnvironmentToneMapping, I as IKChain, q as IKComponent, r as IKLimb, s as IKOptions, N as NetValue, t as NetworkIdentityComponent, u as NetworkSpawnerComponent, v as NetworkTransformComponent, w as NetworkTransformOptions, x as NetworkedPropsComponent, y as ParentId, z as Postprocessing, b as PostprocessingState, T as TransformComponent, A as TransformData, V as Vec3, B as normalizeEnvironmentLighting, F as normalizeIKChain } from '../System-DPMAW30g.js';
|
|
3
|
-
export { P as PrefabInstance, a as PrefabNode, X as XREnvironmentComponent, b as XrEnvironmentKind, c as XrEnvironmentOrientation } from '../index-
|
|
3
|
+
export { P as PrefabInstance, a as PrefabNode, X as XREnvironmentComponent, b as XrEnvironmentKind, c as XrEnvironmentOrientation } from '../index-CLtSMf2M.js';
|
|
4
4
|
import 'three';
|
|
5
5
|
import '@dimforge/rapier3d-compat';
|
|
6
6
|
import '../handPose-DlcTtqgx.js';
|
package/dist/components/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { AnimationComponent, AudioComponent, BoneAttachmentComponent, CameraComponent, DEFAULT_COLLIDER_STATE, DEFAULT_ENVIRONMENT_LIGHTING, DEFAULT_ENVIRONMENT_STATE, DEFAULT_INSTANCED_MESH_PARAMETERS, DEFAULT_INSTANCE_TRANSFORM, DEFAULT_MESH_GEOMETRY_PARAMETERS, DEFAULT_PHYSICS_STATE, DEFAULT_POSE_CURLS, DEFAULT_POSE_DIRECTIONS, DEFAULT_POSTPROCESSING_STATE, DEFAULT_RIGIDBODY_STATE, EntityType, Environment, IKComponent, ImageComponent, ImageTarget, ImageTargetAnchor, InstanceSlotComponent, InstancedMeshComponent, LightComponent, MODEL_NO_PATH_MESSAGE, MaterialComponent, MeshComponent, MeshGeometryComponent, ModelComponent, Name, NetworkIdentityComponent, NetworkSpawnerComponent, NetworkTransformComponent, NetworkedPropsComponent, Object3DRef, ParentId, PhysicsComponent, Postprocessing, PrefabInstance, PrefabNode, ScriptComponent, ScriptObjectComponent, Selectable, SelectionTransformState, SpriteComponent, TransformComponent, UIButtonComponent, UIPanelComponent, UISliderComponent, UITextComponent, UIToggleComponent, VRTeleportAreaComponent, VideoComponent, XRAnchorComponent, XREnvironmentComponent, XRHandPoseComponent, XRInteractableComponent, XRInteractorComponent, XRInteractorSideComponent, XRRigComponent, createAttachPoint, createHandPoseEntry, defaultMaterialValue, handPoseDefinitionFor, normalizeEnvironmentLighting, normalizeIKChain, normalizePhysicsState, setModelLoadState, setPhysicsLiveRef } from '../chunk-
|
|
1
|
+
export { AnimationComponent, AudioComponent, BoneAttachmentComponent, CameraComponent, DEFAULT_COLLIDER_STATE, DEFAULT_ENVIRONMENT_LIGHTING, DEFAULT_ENVIRONMENT_STATE, DEFAULT_INSTANCED_MESH_PARAMETERS, DEFAULT_INSTANCE_TRANSFORM, DEFAULT_MESH_GEOMETRY_PARAMETERS, DEFAULT_PHYSICS_STATE, DEFAULT_POSE_CURLS, DEFAULT_POSE_DIRECTIONS, DEFAULT_POSTPROCESSING_STATE, DEFAULT_RIGIDBODY_STATE, EntityType, Environment, IKComponent, ImageComponent, ImageTarget, ImageTargetAnchor, InstanceSlotComponent, InstancedMeshComponent, LightComponent, MODEL_NO_PATH_MESSAGE, MaterialComponent, MeshComponent, MeshGeometryComponent, ModelComponent, Name, NetworkIdentityComponent, NetworkSpawnerComponent, NetworkTransformComponent, NetworkedPropsComponent, Object3DRef, ParentId, PhysicsComponent, Postprocessing, PrefabInstance, PrefabNode, ScriptComponent, ScriptObjectComponent, Selectable, SelectionTransformState, SpriteComponent, TransformComponent, UIButtonComponent, UIPanelComponent, UISliderComponent, UITextComponent, UIToggleComponent, VRTeleportAreaComponent, VideoComponent, XRAnchorComponent, XREnvironmentComponent, XRHandPoseComponent, XRInteractableComponent, XRInteractorComponent, XRInteractorSideComponent, XRRigComponent, createAttachPoint, createHandPoseEntry, defaultMaterialValue, handPoseDefinitionFor, normalizeEnvironmentLighting, normalizeIKChain, normalizePhysicsState, setModelLoadState, setPhysicsLiveRef } from '../chunk-JNYPJB55.js';
|
|
2
2
|
import '../chunk-CKTHDXPS.js';
|
|
3
3
|
import '../chunk-XE4OXN2W.js';
|
|
4
4
|
//# sourceMappingURL=index.js.map
|
|
@@ -21,8 +21,9 @@ raise its `width`/`height` fields and it re-renders crisply.
|
|
|
21
21
|
1. Create a **UI Panel** — the backdrop. A comfortable read is 1–2 m from the
|
|
22
22
|
player, centred around eye height (y ≈ 1.2–1.6).
|
|
23
23
|
2. Create **Text**, **Button**, **Toggle**, **Slider** entities and parent
|
|
24
|
-
them under the panel. Place them with local transforms
|
|
25
|
-
|
|
24
|
+
them under the panel. Place them with local transforms. Children always
|
|
25
|
+
draw over their parent, from any angle, so local z is only for depth you
|
|
26
|
+
want to see.
|
|
26
27
|
3. Give each interactive widget an `actionId` (empty means "use the entity's
|
|
27
28
|
name").
|
|
28
29
|
4. Attach **one Behaviour to the panel**. UI events fire on the widget's own
|
|
@@ -71,7 +72,9 @@ independent: each panel script hears only its own children.
|
|
|
71
72
|
| Toggle | `UIToggleComponent` | On/off switch. Fires `onUiToggle`; `value` persists with the scene. |
|
|
72
73
|
| Slider | `UISliderComponent` | Draggable value in `[min, max]`. Fires `onUiChange`. |
|
|
73
74
|
|
|
74
|
-
Images need no widget: parent an ordinary `image` entity under the panel.
|
|
75
|
+
Images need no widget: parent an ordinary `image` entity under the panel. A
|
|
76
|
+
transparent mesh under a widget draws with it, in front of that widget and
|
|
77
|
+
behind the widget's own children.
|
|
75
78
|
|
|
76
79
|
### Press semantics
|
|
77
80
|
|
|
@@ -90,6 +93,65 @@ and always fires once more with the final value on release.
|
|
|
90
93
|
panel's texture density. Lines wrap automatically to the component's `width`;
|
|
91
94
|
overflow past `height` is clamped with an ellipsis.
|
|
92
95
|
|
|
96
|
+
## Styling
|
|
97
|
+
|
|
98
|
+
Every widget takes a `style`, which wins over its plain colour fields. Leave it
|
|
99
|
+
out and the widget draws as it always has.
|
|
100
|
+
|
|
101
|
+
```ts
|
|
102
|
+
import { UIPanelComponent } from "@relu-interactives/spatial-ecs/components";
|
|
103
|
+
|
|
104
|
+
const panel = new UIPanelComponent({
|
|
105
|
+
width: 0.9,
|
|
106
|
+
height: 0.6,
|
|
107
|
+
tokens: { plate: "#1b2432", plateDeep: "#121824" },
|
|
108
|
+
style: {
|
|
109
|
+
fill: {
|
|
110
|
+
kind: "linear",
|
|
111
|
+
angle: 160,
|
|
112
|
+
stops: [
|
|
113
|
+
{ at: 0, color: "$plate" },
|
|
114
|
+
{ at: 1, color: "$plateDeep" },
|
|
115
|
+
],
|
|
116
|
+
},
|
|
117
|
+
radius: 0.036,
|
|
118
|
+
shadows: [{ x: 0, y: -0.02, blur: 0.06, color: "#00000099" }],
|
|
119
|
+
edge: { width: 0.0035, color: "#ffffff30" },
|
|
120
|
+
},
|
|
121
|
+
});
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
| Field | What it does |
|
|
125
|
+
| --- | --- |
|
|
126
|
+
| `fill` | `solid`, `linear` (angle in degrees, reads like CSS), `radial`, or `image` (`cover`, `contain`, `fill`, with an optional `tint`) |
|
|
127
|
+
| `border` | Width in metres and a paint |
|
|
128
|
+
| `radius` | One radius, or four: top-left, top-right, bottom-right, bottom-left |
|
|
129
|
+
| `shadows` | Drop shadows, in metres, outside the shape only. They don't change what a pointer can hit |
|
|
130
|
+
| `edge` | A thin highlight along the top inner edge |
|
|
131
|
+
| `opacity` | 0–1. Multiplies down the widget tree, so fading a panel fades its menu, and a fade never redraws anything |
|
|
132
|
+
| `text` | `font`, `weight`, `tracking`, `transform`, `paint`, `maxLines`, `shadow` |
|
|
133
|
+
|
|
134
|
+
### Tokens
|
|
135
|
+
|
|
136
|
+
`tokens` on a panel name values for every widget under it, as `$name` in any
|
|
137
|
+
colour or file field, the nearest panel winning. A theme therefore travels with
|
|
138
|
+
a prefab, and one edit restyles a whole menu, redrawing only the widgets that
|
|
139
|
+
use that token.
|
|
140
|
+
|
|
141
|
+
### Fonts and images
|
|
142
|
+
|
|
143
|
+
`style.text.font` takes a font file in the project, and `fill` with
|
|
144
|
+
`kind: "image"` or a button's `icon` takes an image or SVG. Files load on
|
|
145
|
+
demand and the widget redraws when they arrive. Until then text uses a system
|
|
146
|
+
face.
|
|
147
|
+
|
|
148
|
+
### Variants
|
|
149
|
+
|
|
150
|
+
- Toggle `variant`: `switch` (default), `checkbox`, `radio`.
|
|
151
|
+
- Slider `variant`: `slider` (default), `progress`, `ring`. The last two only
|
|
152
|
+
show a value. `readOnly` does the same for a plain slider, and `step` snaps
|
|
153
|
+
a dragged value.
|
|
154
|
+
|
|
93
155
|
## Follow modes
|
|
94
156
|
|
|
95
157
|
- `follow: "world"` (default) — the panel stays where you put it.
|
|
@@ -148,7 +210,8 @@ export class Inspect extends Behaviour {
|
|
|
148
210
|
}
|
|
149
211
|
|
|
150
212
|
onUiHoverStart(event: UiInteractionEvent) {
|
|
151
|
-
//
|
|
213
|
+
// A ray or the mouse moved onto the widget. Two hands on one widget count
|
|
214
|
+
// as one hover. Vision Pro has no hover before a pinch.
|
|
152
215
|
console.log("hovering", event.targetEntityId);
|
|
153
216
|
}
|
|
154
217
|
}
|
|
@@ -160,6 +223,19 @@ export class Inspect extends Behaviour {
|
|
|
160
223
|
idle menu costs nothing per frame.
|
|
161
224
|
- Slider drags and toggle flips move **geometry** (the knob and fill quads),
|
|
162
225
|
not pixels, so dragging never re-renders the texture.
|
|
163
|
-
- `pixelDensity` (
|
|
164
|
-
1024 px/m is crisp at arm's length; raise it only for
|
|
165
|
-
inspects up close.
|
|
226
|
+
- `pixelDensity` (every widget) trades texture memory for sharpness: the
|
|
227
|
+
default 1024 px/m is crisp at arm's length; raise it only for widgets the
|
|
228
|
+
player inspects up close.
|
|
229
|
+
|
|
230
|
+
## Draw order and blending
|
|
231
|
+
|
|
232
|
+
Widgets draw in a fixed order: within one UI tree, parents before children;
|
|
233
|
+
between trees, back to front by plane distance. Widgets on one plane that are
|
|
234
|
+
not parented to each other draw large before small, so parent them when the
|
|
235
|
+
order matters.
|
|
236
|
+
|
|
237
|
+
Text and controls show from the front only. A panel keeps its back.
|
|
238
|
+
|
|
239
|
+
On a WebGPU project a translucent widget over a bright background looks a
|
|
240
|
+
little duller than on WebGL, because WebGPU blends in linear light. Over dark
|
|
241
|
+
backgrounds the two match. Opaque widgets are identical on both.
|
package/dist/factories/index.cjs
CHANGED
|
@@ -2680,6 +2680,127 @@ function createXRInteractorSideComponent(world, entityId, ...args) {
|
|
|
2680
2680
|
}
|
|
2681
2681
|
__name(createXRInteractorSideComponent, "createXRInteractorSideComponent");
|
|
2682
2682
|
|
|
2683
|
+
// core/ui/uiStyle.ts
|
|
2684
|
+
var isRecord = /* @__PURE__ */ __name((value) => typeof value === "object" && value !== null && !Array.isArray(value), "isRecord");
|
|
2685
|
+
var finite = /* @__PURE__ */ __name((value) => typeof value === "number" && Number.isFinite(value), "finite");
|
|
2686
|
+
var nonEmpty = /* @__PURE__ */ __name((value) => typeof value === "string" && value.length > 0, "nonEmpty");
|
|
2687
|
+
function normalizeStops(value) {
|
|
2688
|
+
if (!Array.isArray(value)) return null;
|
|
2689
|
+
const stops = [];
|
|
2690
|
+
for (const stop of value) {
|
|
2691
|
+
if (isRecord(stop) && finite(stop.at) && nonEmpty(stop.color)) {
|
|
2692
|
+
stops.push({ at: Math.min(1, Math.max(0, stop.at)), color: stop.color });
|
|
2693
|
+
}
|
|
2694
|
+
}
|
|
2695
|
+
return stops.length >= 2 ? stops : null;
|
|
2696
|
+
}
|
|
2697
|
+
__name(normalizeStops, "normalizeStops");
|
|
2698
|
+
function normalizePaint(value) {
|
|
2699
|
+
if (!isRecord(value)) return void 0;
|
|
2700
|
+
if (value.kind === "solid" && nonEmpty(value.color)) {
|
|
2701
|
+
return { kind: "solid", color: value.color };
|
|
2702
|
+
}
|
|
2703
|
+
if (value.kind === "linear") {
|
|
2704
|
+
const stops = normalizeStops(value.stops);
|
|
2705
|
+
if (stops) {
|
|
2706
|
+
return {
|
|
2707
|
+
kind: "linear",
|
|
2708
|
+
angle: finite(value.angle) ? value.angle : 180,
|
|
2709
|
+
stops
|
|
2710
|
+
};
|
|
2711
|
+
}
|
|
2712
|
+
}
|
|
2713
|
+
if (value.kind === "radial") {
|
|
2714
|
+
const stops = normalizeStops(value.stops);
|
|
2715
|
+
if (stops) return { kind: "radial", stops };
|
|
2716
|
+
}
|
|
2717
|
+
if (value.kind === "image" && nonEmpty(value.src)) {
|
|
2718
|
+
const fit = value.fit === "contain" || value.fit === "fill" ? value.fit : "cover";
|
|
2719
|
+
return {
|
|
2720
|
+
kind: "image",
|
|
2721
|
+
src: value.src,
|
|
2722
|
+
fit,
|
|
2723
|
+
...nonEmpty(value.tint) ? { tint: value.tint } : {}
|
|
2724
|
+
};
|
|
2725
|
+
}
|
|
2726
|
+
return void 0;
|
|
2727
|
+
}
|
|
2728
|
+
__name(normalizePaint, "normalizePaint");
|
|
2729
|
+
function normalizeShadow(value) {
|
|
2730
|
+
if (!isRecord(value) || !nonEmpty(value.color)) return void 0;
|
|
2731
|
+
return {
|
|
2732
|
+
x: finite(value.x) ? value.x : 0,
|
|
2733
|
+
y: finite(value.y) ? value.y : 0,
|
|
2734
|
+
blur: finite(value.blur) ? Math.max(0, value.blur) : 0,
|
|
2735
|
+
color: value.color
|
|
2736
|
+
};
|
|
2737
|
+
}
|
|
2738
|
+
__name(normalizeShadow, "normalizeShadow");
|
|
2739
|
+
function normalizeText(value) {
|
|
2740
|
+
if (!isRecord(value)) return void 0;
|
|
2741
|
+
const text = {};
|
|
2742
|
+
if (nonEmpty(value.font)) text.font = value.font;
|
|
2743
|
+
if (finite(value.weight)) text.weight = value.weight;
|
|
2744
|
+
if (finite(value.tracking)) text.tracking = value.tracking;
|
|
2745
|
+
if (value.transform === "upper" || value.transform === "lower") {
|
|
2746
|
+
text.transform = value.transform;
|
|
2747
|
+
}
|
|
2748
|
+
const paint = normalizePaint(value.paint);
|
|
2749
|
+
if (paint) text.paint = paint;
|
|
2750
|
+
if (finite(value.maxLines) && value.maxLines >= 1) {
|
|
2751
|
+
text.maxLines = Math.floor(value.maxLines);
|
|
2752
|
+
}
|
|
2753
|
+
const shadow = normalizeShadow(value.shadow);
|
|
2754
|
+
if (shadow) text.shadow = shadow;
|
|
2755
|
+
return Object.keys(text).length > 0 ? text : void 0;
|
|
2756
|
+
}
|
|
2757
|
+
__name(normalizeText, "normalizeText");
|
|
2758
|
+
function normalizeUiStyle(value) {
|
|
2759
|
+
if (!isRecord(value)) return void 0;
|
|
2760
|
+
const style = {};
|
|
2761
|
+
const fill = normalizePaint(value.fill);
|
|
2762
|
+
if (fill) style.fill = fill;
|
|
2763
|
+
if (isRecord(value.border) && finite(value.border.width)) {
|
|
2764
|
+
const paint = normalizePaint(value.border.paint);
|
|
2765
|
+
if (paint) {
|
|
2766
|
+
style.border = { width: Math.max(0, value.border.width), paint };
|
|
2767
|
+
}
|
|
2768
|
+
}
|
|
2769
|
+
if (finite(value.radius)) {
|
|
2770
|
+
style.radius = Math.max(0, value.radius);
|
|
2771
|
+
} else if (Array.isArray(value.radius) && value.radius.length === 4 && value.radius.every(finite)) {
|
|
2772
|
+
style.radius = value.radius.map((r) => Math.max(0, r));
|
|
2773
|
+
}
|
|
2774
|
+
if (Array.isArray(value.shadows)) {
|
|
2775
|
+
const shadows = value.shadows.map(normalizeShadow).filter((s) => !!s);
|
|
2776
|
+
if (shadows.length > 0) style.shadows = shadows;
|
|
2777
|
+
}
|
|
2778
|
+
if (isRecord(value.edge) && finite(value.edge.width) && nonEmpty(value.edge.color)) {
|
|
2779
|
+
style.edge = {
|
|
2780
|
+
width: Math.max(0, value.edge.width),
|
|
2781
|
+
color: value.edge.color
|
|
2782
|
+
};
|
|
2783
|
+
}
|
|
2784
|
+
if (finite(value.opacity)) {
|
|
2785
|
+
style.opacity = Math.min(1, Math.max(0, value.opacity));
|
|
2786
|
+
}
|
|
2787
|
+
const text = normalizeText(value.text);
|
|
2788
|
+
if (text) style.text = text;
|
|
2789
|
+
return Object.keys(style).length > 0 ? style : void 0;
|
|
2790
|
+
}
|
|
2791
|
+
__name(normalizeUiStyle, "normalizeUiStyle");
|
|
2792
|
+
function normalizeUiTokens(value) {
|
|
2793
|
+
if (!isRecord(value)) return void 0;
|
|
2794
|
+
const tokens = {};
|
|
2795
|
+
for (const [key, token] of Object.entries(value)) {
|
|
2796
|
+
if (nonEmpty(token) && key.length > 0 && !key.includes("/")) {
|
|
2797
|
+
tokens[key] = token;
|
|
2798
|
+
}
|
|
2799
|
+
}
|
|
2800
|
+
return Object.keys(tokens).length > 0 ? tokens : void 0;
|
|
2801
|
+
}
|
|
2802
|
+
__name(normalizeUiTokens, "normalizeUiTokens");
|
|
2803
|
+
|
|
2683
2804
|
// core/components/UIButton.ts
|
|
2684
2805
|
var _UIButtonComponent = class _UIButtonComponent extends Component {
|
|
2685
2806
|
constructor(options) {
|
|
@@ -2696,6 +2817,13 @@ var _UIButtonComponent = class _UIButtonComponent extends Component {
|
|
|
2696
2817
|
this.cornerRadius = options?.cornerRadius ?? 0.02;
|
|
2697
2818
|
this.borderWidth = options?.borderWidth ?? 2e-3;
|
|
2698
2819
|
this.borderColor = options?.borderColor ?? "#3a3a3a";
|
|
2820
|
+
if (options?.pixelDensity !== void 0) {
|
|
2821
|
+
this.pixelDensity = options.pixelDensity;
|
|
2822
|
+
}
|
|
2823
|
+
const style = normalizeUiStyle(options?.style);
|
|
2824
|
+
if (style) this.style = style;
|
|
2825
|
+
if (options?.icon) this.icon = options.icon;
|
|
2826
|
+
if (options?.iconPosition) this.iconPosition = options.iconPosition;
|
|
2699
2827
|
}
|
|
2700
2828
|
};
|
|
2701
2829
|
__name(_UIButtonComponent, "UIButtonComponent");
|
|
@@ -2722,6 +2850,10 @@ var _UIPanelComponent = class _UIPanelComponent extends Component {
|
|
|
2722
2850
|
this.borderColor = options?.borderColor ?? "#333333";
|
|
2723
2851
|
this.pixelDensity = options?.pixelDensity ?? 1024;
|
|
2724
2852
|
this.follow = options?.follow ?? "world";
|
|
2853
|
+
const style = normalizeUiStyle(options?.style);
|
|
2854
|
+
if (style) this.style = style;
|
|
2855
|
+
const tokens = normalizeUiTokens(options?.tokens);
|
|
2856
|
+
if (tokens) this.tokens = tokens;
|
|
2725
2857
|
}
|
|
2726
2858
|
};
|
|
2727
2859
|
__name(_UIPanelComponent, "UIPanelComponent");
|
|
@@ -2750,6 +2882,14 @@ var _UISliderComponent = class _UISliderComponent extends Component {
|
|
|
2750
2882
|
this.trackColor = options?.trackColor ?? "#2a2a2a";
|
|
2751
2883
|
this.accentColor = options?.accentColor ?? "#ff6b35";
|
|
2752
2884
|
this.knobColor = options?.knobColor ?? "#ffffff";
|
|
2885
|
+
if (options?.pixelDensity !== void 0) {
|
|
2886
|
+
this.pixelDensity = options.pixelDensity;
|
|
2887
|
+
}
|
|
2888
|
+
const style = normalizeUiStyle(options?.style);
|
|
2889
|
+
if (style) this.style = style;
|
|
2890
|
+
if (options?.variant) this.variant = options.variant;
|
|
2891
|
+
if (options?.step !== void 0) this.step = options.step;
|
|
2892
|
+
if (options?.readOnly !== void 0) this.readOnly = options.readOnly;
|
|
2753
2893
|
}
|
|
2754
2894
|
};
|
|
2755
2895
|
__name(_UISliderComponent, "UISliderComponent");
|
|
@@ -2777,6 +2917,11 @@ var _UITextComponent = class _UITextComponent extends Component {
|
|
|
2777
2917
|
this.valign = options?.valign ?? "middle";
|
|
2778
2918
|
this.lineHeight = options?.lineHeight ?? 1.25;
|
|
2779
2919
|
this.padding = options?.padding ?? 0.01;
|
|
2920
|
+
if (options?.pixelDensity !== void 0) {
|
|
2921
|
+
this.pixelDensity = options.pixelDensity;
|
|
2922
|
+
}
|
|
2923
|
+
const style = normalizeUiStyle(options?.style);
|
|
2924
|
+
if (style) this.style = style;
|
|
2780
2925
|
}
|
|
2781
2926
|
};
|
|
2782
2927
|
__name(_UITextComponent, "UITextComponent");
|
|
@@ -2801,6 +2946,12 @@ var _UIToggleComponent = class _UIToggleComponent extends Component {
|
|
|
2801
2946
|
this.trackColor = options?.trackColor ?? "#2a2a2a";
|
|
2802
2947
|
this.accentColor = options?.accentColor ?? "#ff6b35";
|
|
2803
2948
|
this.knobColor = options?.knobColor ?? "#ffffff";
|
|
2949
|
+
if (options?.pixelDensity !== void 0) {
|
|
2950
|
+
this.pixelDensity = options.pixelDensity;
|
|
2951
|
+
}
|
|
2952
|
+
const style = normalizeUiStyle(options?.style);
|
|
2953
|
+
if (style) this.style = style;
|
|
2954
|
+
if (options?.variant) this.variant = options.variant;
|
|
2804
2955
|
}
|
|
2805
2956
|
};
|
|
2806
2957
|
__name(_UIToggleComponent, "UIToggleComponent");
|