mudra-skills 1.0.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.
Files changed (149) hide show
  1. package/.claude-plugin/plugin.json +19 -0
  2. package/CLAUDE.md +35 -0
  3. package/bin/install.js +25 -0
  4. package/package.json +28 -0
  5. package/skills/mudra-master/SKILL.md +202 -0
  6. package/skills/mudra-master/mudra-preview/SKILL.md +151 -0
  7. package/skills/mudra-master/mudra-preview/assets/ar-menu.html +382 -0
  8. package/skills/mudra-master/mudra-preview/assets/document-scroller.html +468 -0
  9. package/skills/mudra-master/mudra-preview/assets/drum-machine.html +788 -0
  10. package/skills/mudra-master/mudra-preview/assets/emg-visualizer.html +390 -0
  11. package/skills/mudra-master/mudra-preview/assets/generative-art.html +408 -0
  12. package/skills/mudra-master/mudra-preview/assets/gesture-assistant.html +342 -0
  13. package/skills/mudra-master/mudra-preview/assets/gesture-speech.html +444 -0
  14. package/skills/mudra-master/mudra-preview/assets/hands-free-desktop.html +376 -0
  15. package/skills/mudra-master/mudra-preview/assets/model-rotator.html +365 -0
  16. package/skills/mudra-master/mudra-preview/assets/mudra-duel.html +3200 -0
  17. package/skills/mudra-master/mudra-preview/assets/mudra-monitor.html +1451 -0
  18. package/skills/mudra-master/mudra-preview/assets/mudra-ultimate-template.html +891 -0
  19. package/skills/mudra-master/mudra-preview/assets/music-sequencer.html +455 -0
  20. package/skills/mudra-master/mudra-preview/assets/neural-pong.html +380 -0
  21. package/skills/mudra-master/mudra-preview/assets/neural-snake.html +364 -0
  22. package/skills/mudra-master/mudra-preview/assets/presentation-controller.html +345 -0
  23. package/skills/mudra-master/mudra-preview/assets/pressure-painter.html +285 -0
  24. package/skills/mudra-master/mudra-preview/assets/runner.html +1812 -0
  25. package/skills/mudra-master/mudra-preview/assets/smart-home.html +461 -0
  26. package/skills/mudra-master/mudra-preview/assets/space-invaders.html +1154 -0
  27. package/skills/mudra-master/mudra-preview/assets/waterful-ring-toss.html +1624 -0
  28. package/skills/mudra-master/mudra-preview/references/agent_protocol.json +646 -0
  29. package/skills/mudra-master/mudra-preview/references/promt.md +16829 -0
  30. package/skills/mudra-master/mudra-xr/SKILL.md +245 -0
  31. package/skills/mudra-master/mudra-xr/assets/demos/3dgs-walkthrough.html +242 -0
  32. package/skills/mudra-master/mudra-xr/assets/demos/aisimulator.html +792 -0
  33. package/skills/mudra-master/mudra-xr/assets/demos/balloonpop.html +422 -0
  34. package/skills/mudra-master/mudra-xr/assets/demos/ballpit.html +284 -0
  35. package/skills/mudra-master/mudra-xr/assets/demos/drone.html +41 -0
  36. package/skills/mudra-master/mudra-xr/assets/demos/gemini-icebreakers.html +338 -0
  37. package/skills/mudra-master/mudra-xr/assets/demos/gemini-xrobject.html +302 -0
  38. package/skills/mudra-master/mudra-xr/assets/demos/math3d.html +188 -0
  39. package/skills/mudra-master/mudra-xr/assets/demos/measure.html +247 -0
  40. package/skills/mudra-master/mudra-xr/assets/demos/occlusion.html +251 -0
  41. package/skills/mudra-master/mudra-xr/assets/demos/rain.html +498 -0
  42. package/skills/mudra-master/mudra-xr/assets/demos/screenwiper.html +432 -0
  43. package/skills/mudra-master/mudra-xr/assets/demos/splash.html +519 -0
  44. package/skills/mudra-master/mudra-xr/assets/demos/webcam_gestures.html +253 -0
  45. package/skills/mudra-master/mudra-xr/assets/demos/xremoji.html +833 -0
  46. package/skills/mudra-master/mudra-xr/assets/demos/xrpoet.html +151 -0
  47. package/skills/mudra-master/mudra-xr/assets/samples/depthmap.html +266 -0
  48. package/skills/mudra-master/mudra-xr/assets/samples/depthmesh.html +100 -0
  49. package/skills/mudra-master/mudra-xr/assets/samples/game_rps.html +1099 -0
  50. package/skills/mudra-master/mudra-xr/assets/samples/gestures_custom.html +467 -0
  51. package/skills/mudra-master/mudra-xr/assets/samples/gestures_heuristic.html +256 -0
  52. package/skills/mudra-master/mudra-xr/assets/samples/lighting.html +163 -0
  53. package/skills/mudra-master/mudra-xr/assets/samples/mesh_detection.html +46 -0
  54. package/skills/mudra-master/mudra-xr/assets/samples/modelviewer.html +183 -0
  55. package/skills/mudra-master/mudra-xr/assets/samples/paint.html +133 -0
  56. package/skills/mudra-master/mudra-xr/assets/samples/planar-vst.html +45 -0
  57. package/skills/mudra-master/mudra-xr/assets/samples/reticle.html +95 -0
  58. package/skills/mudra-master/mudra-xr/assets/samples/skybox_agent.html +384 -0
  59. package/skills/mudra-master/mudra-xr/assets/samples/sound.html +390 -0
  60. package/skills/mudra-master/mudra-xr/assets/samples/ui.html +496 -0
  61. package/skills/mudra-master/mudra-xr/assets/samples/virtual-screens.html +808 -0
  62. package/skills/mudra-master/mudra-xr/assets/templates/0_basic.html +64 -0
  63. package/skills/mudra-master/mudra-xr/assets/templates/1_ui.html +107 -0
  64. package/skills/mudra-master/mudra-xr/assets/templates/2_hands.html +183 -0
  65. package/skills/mudra-master/mudra-xr/assets/templates/3_depth.html +89 -0
  66. package/skills/mudra-master/mudra-xr/assets/templates/4_stereo.html +84 -0
  67. package/skills/mudra-master/mudra-xr/assets/templates/5_camera.html +117 -0
  68. package/skills/mudra-master/mudra-xr/assets/templates/6_ai.html +154 -0
  69. package/skills/mudra-master/mudra-xr/assets/templates/7_ai_live.html +253 -0
  70. package/skills/mudra-master/mudra-xr/assets/templates/8_objects.html +95 -0
  71. package/skills/mudra-master/mudra-xr/assets/templates/9_xr-toggle.html +90 -0
  72. package/skills/mudra-master/mudra-xr/assets/templates/heuristic_hand_gestures.html +102 -0
  73. package/skills/mudra-master/mudra-xr/assets/templates/meshes.html +47 -0
  74. package/skills/mudra-master/mudra-xr/assets/templates/planes.html +47 -0
  75. package/skills/mudra-master/mudra-xr/assets/templates/uikit.html +187 -0
  76. package/skills/mudra-master/mudra-xr/references/agent_protocol.json +878 -0
  77. package/skills/mudra-master/mudra-xr/references/promt.md +1516 -0
  78. package/skills/mudra-preview/SKILL.md +151 -0
  79. package/skills/mudra-preview/assets/ar-menu.html +382 -0
  80. package/skills/mudra-preview/assets/document-scroller.html +468 -0
  81. package/skills/mudra-preview/assets/drum-machine.html +788 -0
  82. package/skills/mudra-preview/assets/emg-visualizer.html +390 -0
  83. package/skills/mudra-preview/assets/generative-art.html +408 -0
  84. package/skills/mudra-preview/assets/gesture-assistant.html +342 -0
  85. package/skills/mudra-preview/assets/gesture-speech.html +444 -0
  86. package/skills/mudra-preview/assets/hands-free-desktop.html +376 -0
  87. package/skills/mudra-preview/assets/model-rotator.html +365 -0
  88. package/skills/mudra-preview/assets/mudra-duel.html +3200 -0
  89. package/skills/mudra-preview/assets/mudra-monitor.html +1451 -0
  90. package/skills/mudra-preview/assets/mudra-ultimate-template.html +891 -0
  91. package/skills/mudra-preview/assets/music-sequencer.html +455 -0
  92. package/skills/mudra-preview/assets/neural-pong.html +380 -0
  93. package/skills/mudra-preview/assets/neural-snake.html +364 -0
  94. package/skills/mudra-preview/assets/presentation-controller.html +345 -0
  95. package/skills/mudra-preview/assets/pressure-painter.html +285 -0
  96. package/skills/mudra-preview/assets/runner.html +1812 -0
  97. package/skills/mudra-preview/assets/smart-home.html +461 -0
  98. package/skills/mudra-preview/assets/space-invaders.html +1154 -0
  99. package/skills/mudra-preview/assets/waterful-ring-toss.html +1624 -0
  100. package/skills/mudra-preview/references/agent_protocol.json +646 -0
  101. package/skills/mudra-preview/references/promt.md +16829 -0
  102. package/skills/mudra-xr/SKILL.md +245 -0
  103. package/skills/mudra-xr/assets/demos/3dgs-walkthrough.html +242 -0
  104. package/skills/mudra-xr/assets/demos/aisimulator.html +792 -0
  105. package/skills/mudra-xr/assets/demos/balloonpop.html +422 -0
  106. package/skills/mudra-xr/assets/demos/ballpit.html +284 -0
  107. package/skills/mudra-xr/assets/demos/drone.html +41 -0
  108. package/skills/mudra-xr/assets/demos/gemini-icebreakers.html +338 -0
  109. package/skills/mudra-xr/assets/demos/gemini-xrobject.html +302 -0
  110. package/skills/mudra-xr/assets/demos/math3d.html +188 -0
  111. package/skills/mudra-xr/assets/demos/measure.html +247 -0
  112. package/skills/mudra-xr/assets/demos/occlusion.html +251 -0
  113. package/skills/mudra-xr/assets/demos/rain.html +498 -0
  114. package/skills/mudra-xr/assets/demos/screenwiper.html +432 -0
  115. package/skills/mudra-xr/assets/demos/splash.html +519 -0
  116. package/skills/mudra-xr/assets/demos/webcam_gestures.html +253 -0
  117. package/skills/mudra-xr/assets/demos/xremoji.html +833 -0
  118. package/skills/mudra-xr/assets/demos/xrpoet.html +151 -0
  119. package/skills/mudra-xr/assets/samples/depthmap.html +266 -0
  120. package/skills/mudra-xr/assets/samples/depthmesh.html +100 -0
  121. package/skills/mudra-xr/assets/samples/game_rps.html +1099 -0
  122. package/skills/mudra-xr/assets/samples/gestures_custom.html +467 -0
  123. package/skills/mudra-xr/assets/samples/gestures_heuristic.html +256 -0
  124. package/skills/mudra-xr/assets/samples/lighting.html +163 -0
  125. package/skills/mudra-xr/assets/samples/mesh_detection.html +46 -0
  126. package/skills/mudra-xr/assets/samples/modelviewer.html +183 -0
  127. package/skills/mudra-xr/assets/samples/paint.html +133 -0
  128. package/skills/mudra-xr/assets/samples/planar-vst.html +45 -0
  129. package/skills/mudra-xr/assets/samples/reticle.html +95 -0
  130. package/skills/mudra-xr/assets/samples/skybox_agent.html +384 -0
  131. package/skills/mudra-xr/assets/samples/sound.html +390 -0
  132. package/skills/mudra-xr/assets/samples/ui.html +496 -0
  133. package/skills/mudra-xr/assets/samples/virtual-screens.html +808 -0
  134. package/skills/mudra-xr/assets/templates/0_basic.html +64 -0
  135. package/skills/mudra-xr/assets/templates/1_ui.html +107 -0
  136. package/skills/mudra-xr/assets/templates/2_hands.html +183 -0
  137. package/skills/mudra-xr/assets/templates/3_depth.html +89 -0
  138. package/skills/mudra-xr/assets/templates/4_stereo.html +84 -0
  139. package/skills/mudra-xr/assets/templates/5_camera.html +117 -0
  140. package/skills/mudra-xr/assets/templates/6_ai.html +154 -0
  141. package/skills/mudra-xr/assets/templates/7_ai_live.html +253 -0
  142. package/skills/mudra-xr/assets/templates/8_objects.html +95 -0
  143. package/skills/mudra-xr/assets/templates/9_xr-toggle.html +90 -0
  144. package/skills/mudra-xr/assets/templates/heuristic_hand_gestures.html +102 -0
  145. package/skills/mudra-xr/assets/templates/meshes.html +47 -0
  146. package/skills/mudra-xr/assets/templates/planes.html +47 -0
  147. package/skills/mudra-xr/assets/templates/uikit.html +187 -0
  148. package/skills/mudra-xr/references/agent_protocol.json +878 -0
  149. package/skills/mudra-xr/references/promt.md +1516 -0
@@ -0,0 +1,496 @@
1
+ <!doctype html>
2
+ <!-- reference: samples/ui -->
3
+ <html lang="en">
4
+ <head>
5
+ <title>UI Panels Showcase | XR Blocks</title>
6
+
7
+ <meta
8
+ name="viewport"
9
+ content="width=device-width, initial-scale=1.0, user-scalable=no"
10
+ />
11
+ <link type="text/css" rel="stylesheet" href="https://xrblocks.github.io/css/xr.css" />
12
+ <script type="importmap">
13
+ {
14
+ "imports": {
15
+ "three": "https://cdn.jsdelivr.net/npm/three@0.182.0/build/three.module.js",
16
+ "three/addons/": "https://cdn.jsdelivr.net/npm/three@0.182.0/examples/jsm/",
17
+ "troika-three-text": "https://cdn.jsdelivr.net/gh/protectwise/troika@028b81cf308f0f22e5aa8e78196be56ec1997af5/packages/troika-three-text/src/index.js",
18
+ "troika-three-utils": "https://cdn.jsdelivr.net/gh/protectwise/troika@v0.52.4/packages/troika-three-utils/src/index.js",
19
+ "troika-worker-utils": "https://cdn.jsdelivr.net/gh/protectwise/troika@v0.52.4/packages/troika-worker-utils/src/index.js",
20
+ "bidi-js": "https://esm.sh/bidi-js@%5E1.0.2?target=es2022",
21
+ "webgl-sdf-generator": "https://esm.sh/webgl-sdf-generator@1.1.1/es2022/webgl-sdf-generator.mjs",
22
+ "xrblocks": "https://cdn.jsdelivr.net/npm/xrblocks@0.11.0/build/xrblocks.js"
23
+ }
24
+ }
25
+ </script>
26
+ </head>
27
+
28
+ <body>
29
+ <canvas
30
+ id="barChartCanvas"
31
+ width="512"
32
+ height="340"
33
+ style="display: none"
34
+ ></canvas>
35
+ <script type="module">
36
+ import * as THREE from 'three';
37
+ import * as xb from 'xrblocks';
38
+
39
+ class MainScript extends xb.Script {
40
+ createProfilePanel() {
41
+ const profilePanel = new xb.SpatialPanel({
42
+ width: 0.8,
43
+ height: 1.0,
44
+ backgroundColor: '#282c3488',
45
+ });
46
+ profilePanel.rotation.set(0, 45, 0);
47
+ profilePanel.position.set(-1.5, 1.5, -2.0);
48
+ this.add(profilePanel);
49
+
50
+ const profileGrid = profilePanel.addGrid();
51
+ profileGrid.addRow({weight: 0.1}).addText({
52
+ text: 'UI Samples',
53
+ fontSize: 0.07,
54
+ fontColor: '#61dafb',
55
+ });
56
+
57
+ const avatarRow = profileGrid.addRow({weight: 0.4});
58
+ avatarRow.addCol({weight: 0.15});
59
+ const avatarCol = avatarRow.addCol({weight: 0.7});
60
+ avatarCol.addImage({
61
+ src: 'https://placehold.co/256x128/61dafb/282c34.png?text=XRBlocks',
62
+ });
63
+
64
+ profileGrid
65
+ .addRow({weight: 0.15})
66
+ .addText({text: 'Spatial Panel', fontSize: 0.08});
67
+ profileGrid.addRow({weight: 0.25}).addText({
68
+ text: 'You may drag borders of this spatial panel to move it around.',
69
+ fontSize: 0.07,
70
+ fontColor: '#abb2bf',
71
+ });
72
+ }
73
+
74
+ createProfilePanelFromJSON() {
75
+ const profilePanelJson = {
76
+ type: 'Panel',
77
+ options: {
78
+ name: 'JSON Panel',
79
+ width: 1.0,
80
+ height: 1.2,
81
+ backgroundColor: '#282c3488',
82
+ },
83
+ position: {x: 1.5, y: 1.5, z: -2.0},
84
+ rotation: {x: 0, y: -45, z: 0},
85
+ children: [
86
+ {
87
+ name: 'JSON Grid',
88
+ type: 'Grid',
89
+ children: [
90
+ {
91
+ // Padding Row
92
+ type: 'Row',
93
+ options: {weight: 0.1},
94
+ },
95
+ {
96
+ // Title Row
97
+ type: 'Row',
98
+ options: {weight: 0.1},
99
+ children: [
100
+ {
101
+ type: 'Text',
102
+ options: {
103
+ text: 'Panel',
104
+ fontSize: 0.07,
105
+ fontColor: '#61dafb',
106
+ },
107
+ },
108
+ ],
109
+ },
110
+ {
111
+ // Avatar Row
112
+ type: 'Row',
113
+ options: {weight: 0.4, name: 'AvatarRow'},
114
+ children: [
115
+ {
116
+ type: 'Col',
117
+ options: {weight: 0.15},
118
+ }, // Left spacer
119
+ {
120
+ type: 'Col',
121
+ options: {weight: 0.7},
122
+ children: [
123
+ {
124
+ type: 'Image',
125
+ options: {
126
+ name: 'PlaceHolderImage',
127
+ src: 'https://placehold.co/256x128/61dafb/282c34.png?text=XRBlocks',
128
+ },
129
+ },
130
+ ],
131
+ },
132
+ {
133
+ type: 'Col',
134
+ options: {weight: 0.15},
135
+ }, // Right spacer
136
+ ],
137
+ },
138
+ {
139
+ // Name Row
140
+ type: 'Row',
141
+ options: {weight: 0.15},
142
+ children: [
143
+ {
144
+ type: 'Text',
145
+ options: {text: 'Panel from JSON', fontSize: 0.08},
146
+ },
147
+ ],
148
+ },
149
+ {
150
+ // Subtitle Row
151
+ type: 'Row',
152
+ options: {weight: 0.25},
153
+ children: [
154
+ {
155
+ type: 'Text',
156
+ options: {
157
+ text: 'This panel cannot be dragged around.',
158
+ fontSize: 0.07,
159
+ fontColor: '#abb2bf',
160
+ },
161
+ },
162
+ ],
163
+ },
164
+ ],
165
+ },
166
+ ],
167
+ };
168
+
169
+ const profileUI = xb.core.ui.compose(profilePanelJson);
170
+ this.add(profileUI);
171
+ }
172
+
173
+ createPlayerPanel() {
174
+ // Panel 2: Interactive Media Player (Top-Center)
175
+ const panel = new xb.SpatialPanel({
176
+ width: 1.3,
177
+ height: 1.25,
178
+ backgroundColor: '#00000000',
179
+ });
180
+ panel.position.set(
181
+ 0,
182
+ xb.user.height * 2.0,
183
+ -xb.user.panelDistance - 1.0
184
+ );
185
+ panel.isRoot = true;
186
+ this.add(panel);
187
+ const grid = panel.addGrid();
188
+ // Space for orbiter
189
+ grid.addRow({weight: 0.0});
190
+ // player row
191
+ const playerRow = grid.addRow({weight: 1.0});
192
+ const playerPanel = playerRow.addPanel({
193
+ width: 1.2,
194
+ height: 1.2,
195
+ backgroundColor: '#21252baa',
196
+ });
197
+ const playerGrid = playerPanel.addGrid();
198
+ {
199
+ // video row
200
+ playerGrid.addRow({weight: 0.1});
201
+ const videoRow = playerGrid.addRow({weight: 0.5});
202
+ videoRow.addVideo({
203
+ src: 'https://storage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4',
204
+ });
205
+ // progress row
206
+ const progressRow = playerGrid.addRow({weight: 0.05});
207
+ // controls row
208
+ const controlsRow = playerGrid.addRow({weight: 0.35});
209
+ controlsRow.addCol({weight: 0.2});
210
+ controlsRow
211
+ .addCol({weight: 0.2})
212
+ .addIconButton({text: 'skip_previous', fontSize: 0.4});
213
+ controlsRow
214
+ .addCol({weight: 0.2})
215
+ .addIconButton({text: 'play_arrow', fontSize: 0.6});
216
+ controlsRow
217
+ .addCol({weight: 0.2})
218
+ .addIconButton({text: 'skip_next', fontSize: 0.4});
219
+ controlsRow.addCol({weight: 0.2});
220
+ }
221
+ const orbiter = playerGrid.addOrbiter({
222
+ orbiterScale: 0.1,
223
+ });
224
+ orbiter.addExitButton();
225
+ panel.updateLayouts();
226
+ }
227
+
228
+ createSettingsPanel() {
229
+ // Panel 3: Settings Menu (Top-Right)
230
+ const settingsPanel = new xb.SpatialPanel({
231
+ width: 1.0,
232
+ height: 1.2,
233
+ backgroundColor: '#282c3488',
234
+ });
235
+ settingsPanel.position.set(
236
+ 1.5,
237
+ xb.user.height,
238
+ -xb.user.panelDistance + 2.0
239
+ );
240
+ settingsPanel.rotation.set(0, -Math.PI / 2.0, 0);
241
+
242
+ this.add(settingsPanel);
243
+ const settingsGrid = settingsPanel.addGrid();
244
+ settingsGrid.addRow({weight: 0.15}).addText({
245
+ text: 'Fake Settings',
246
+ fontSize: 0.1,
247
+ fontColor: '#61dafb',
248
+ });
249
+
250
+ const addSettingRow = (grid, label, type) => {
251
+ const row = grid.addRow({weight: 0.2});
252
+ row.addCol({weight: 0.6}).addText({
253
+ text: label,
254
+ anchorX: 'left',
255
+ textAlign: 'left',
256
+ fontSize: 0.07,
257
+ });
258
+ const controlCol = row.addCol({weight: 0.4});
259
+ if (type === 'toggle') {
260
+ const toggleBg = controlCol.addPanel({
261
+ backgroundColor: '#61dafb',
262
+ width: 0.3,
263
+ height: 0.06,
264
+ });
265
+ toggleBg.addGrid().addPanel({
266
+ backgroundColor: '#ffffff',
267
+ width: 0.05,
268
+ height: 0.05,
269
+ x: 0.04,
270
+ });
271
+ } else if (type === 'slider') {
272
+ const sliderBg = controlCol.addPanel({
273
+ backgroundColor: '#3a3f4b',
274
+ width: 0.35,
275
+ height: 0.02,
276
+ });
277
+ sliderBg.addGrid().addPanel({
278
+ backgroundColor: '#61dafb',
279
+ width: 0.04,
280
+ height: 0.04,
281
+ x: 0.05,
282
+ });
283
+ }
284
+ };
285
+
286
+ addSettingRow(settingsGrid, 'Enable Hand Tracking', 'toggle');
287
+ addSettingRow(settingsGrid, 'Show Notifications', 'toggle');
288
+ addSettingRow(settingsGrid, 'Master Volume', 'slider');
289
+ addSettingRow(settingsGrid, 'UI Scale', 'slider');
290
+ }
291
+
292
+ createGalleryPanel() {
293
+ // Panel 4: Photo Gallery (Bottom-Right)
294
+ const galleryPanel = new xb.SpatialPanel({
295
+ width: 1.5,
296
+ height: 1.0,
297
+ backgroundColor: '#21252b88',
298
+ });
299
+ galleryPanel.position.set(
300
+ 0.0,
301
+ xb.user.height,
302
+ -xb.user.panelDistance - 1.0
303
+ );
304
+ this.add(galleryPanel);
305
+ const galleryGrid = galleryPanel.addGrid();
306
+ galleryGrid.addRow({weight: 0.25}).addText({
307
+ text: 'Photo Gallery',
308
+ fontSize: 0.07,
309
+ fontColor: '#61dafb',
310
+ });
311
+ const photoRow1 = galleryGrid.addRow({weight: 0.375});
312
+ photoRow1.addCol({weight: 1 / 3}).addImage({
313
+ src: 'https://placehold.co/150x150/92c5fd/333?text=Img1',
314
+ paddingX: 0.02,
315
+ paddingY: 0.02,
316
+ });
317
+ photoRow1.addCol({weight: 1 / 3}).addImage({
318
+ src: 'https://placehold.co/150x150/6ee7b7/333?text=Img2',
319
+ paddingX: 0.02,
320
+ paddingY: 0.02,
321
+ });
322
+ photoRow1.addCol({weight: 1 / 3}).addImage({
323
+ src: 'https://placehold.co/150x150/fca5a5/333?text=Img3',
324
+ paddingX: 0.02,
325
+ paddingY: 0.02,
326
+ });
327
+ galleryGrid.addRow({weight: 0.05});
328
+ const photoRow2 = galleryGrid.addRow({weight: 0.375});
329
+ photoRow2.addCol({weight: 1 / 3}).addImage({
330
+ src: 'https://placehold.co/150x150/fde047/333?text=Img4',
331
+ paddingX: 0.02,
332
+ paddingY: 0.02,
333
+ });
334
+ photoRow2.addCol({weight: 1 / 3}).addImage({
335
+ src: 'https://placehold.co/150x150/c4b5fd/333?text=Img5',
336
+ paddingX: 0.02,
337
+ paddingY: 0.02,
338
+ });
339
+ photoRow2.addCol({weight: 1 / 3}).addImage({
340
+ src: 'https://placehold.co/150x150/f9a8d4/333?text=Img6',
341
+ paddingX: 0.02,
342
+ paddingY: 0.02,
343
+ });
344
+ }
345
+
346
+ createFormPanel() {
347
+ // Panel 5: Complex Form (Bottom-Left)
348
+ const formPanel = new xb.SpatialPanel({
349
+ width: 1.2,
350
+ height: 1.4,
351
+ backgroundColor: '#282c34',
352
+ });
353
+ formPanel.position.set(-1.8, 0.7, -2.5);
354
+ this.add(formPanel);
355
+ const formGrid = formPanel.addGrid();
356
+ formGrid.addRow({weight: 0.1}).addText({
357
+ text: 'Feedback Form',
358
+ fontSize: 0.07,
359
+ fontColor: '#61dafb',
360
+ });
361
+ const addFormField = (grid, label) => {
362
+ const row = grid.addRow({weight: 0.12});
363
+ row
364
+ .addCol({weight: 0.3})
365
+ .addText({text: label, anchorX: 'left', fontSize: 0.05});
366
+ row
367
+ .addCol({weight: 0.7})
368
+ .addPanel({backgroundColor: '#3a3f4b', height: 0.06});
369
+ };
370
+ addFormField(formGrid, 'Name');
371
+ addFormField(formGrid, 'Email');
372
+ const categoryRow = formGrid.addRow({weight: 0.12});
373
+ categoryRow
374
+ .addCol({weight: 0.3})
375
+ .addText({text: 'Category', anchorX: 'left', fontSize: 0.05});
376
+ const dropdown = categoryRow
377
+ .addCol({weight: 0.7})
378
+ .addPanel({backgroundColor: '#3a3f4b', height: 0.06});
379
+ dropdown
380
+ .addGrid()
381
+ .addText({text: 'General Feedback ▼', fontSize: 0.045});
382
+
383
+ const messageRow = formGrid.addRow({weight: 0.3});
384
+ messageRow.addCol({weight: 0.3}).addText({
385
+ text: 'Message',
386
+ anchorX: 'left',
387
+ anchorY: 'top',
388
+ fontSize: 0.05,
389
+ });
390
+ messageRow
391
+ .addCol({weight: 0.7})
392
+ .addPanel({backgroundColor: '#3a3f4b', height: 0.2});
393
+
394
+ formGrid.addRow({weight: 0.18}).addTextButton({
395
+ text: 'Submit',
396
+ backgroundColor: '#61dafb',
397
+ fontColor: '#282c34',
398
+ height: 0.08,
399
+ width: 0.3,
400
+ });
401
+ }
402
+
403
+ createChartPanel() {
404
+ // Panel 6: Dynamic Chart with Canvas (Bottom-Center)
405
+ const chartPanel = new xb.SpatialPanel({
406
+ width: 0.8,
407
+ height: 0.6,
408
+ backgroundColor: '#21252b88',
409
+ });
410
+ chartPanel.position.set(
411
+ -1.5,
412
+ xb.user.height,
413
+ -xb.user.panelDistance + 2.0
414
+ );
415
+ chartPanel.rotation.set(0, Math.PI / 2.0, 0);
416
+
417
+ this.add(chartPanel);
418
+ const chartGrid = chartPanel.addGrid();
419
+ chartGrid.addRow({weight: 0.15}).addText({
420
+ text: 'Performance Metrics',
421
+ fontSize: 0.07,
422
+ fontColor: '#61dafb',
423
+ });
424
+
425
+ // --- Canvas Chart ---
426
+ const canvas = document.getElementById('barChartCanvas');
427
+ const ctx = canvas.getContext('2d');
428
+ const barData = [0.4, 0.7, 0.5, 0.8, 0.6];
429
+ const colors = [
430
+ '#92c5fd',
431
+ '#6ee7b7',
432
+ '#fca5a5',
433
+ '#fde047',
434
+ '#c4b5fd',
435
+ ];
436
+ const padding = 40;
437
+ const barWidth =
438
+ (canvas.width - padding * (barData.length + 1)) / barData.length;
439
+ const maxBarHeight = canvas.height - padding * 2;
440
+
441
+ ctx.fillStyle = '#282c34'; // background
442
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
443
+
444
+ barData.forEach((value, index) => {
445
+ const barHeight = value * maxBarHeight;
446
+ const x = padding + index * (barWidth + padding);
447
+ const y = canvas.height - padding - barHeight;
448
+ ctx.fillStyle = colors[index];
449
+ ctx.fillRect(x, y, barWidth, barHeight);
450
+ });
451
+
452
+ const canvasTexture = new THREE.CanvasTexture(canvas);
453
+ canvasTexture.needsUpdate = true;
454
+ const chartCol = chartGrid.addCol();
455
+ chartCol.addRow({weight: 0.15});
456
+ const chartArea = chartCol.addRow({weight: 0.85});
457
+ const chartMesh = new THREE.Mesh(
458
+ new THREE.PlaneGeometry(1, 1),
459
+ new THREE.MeshBasicMaterial({map: canvasTexture})
460
+ );
461
+ chartArea.add(chartMesh);
462
+
463
+ const tmpRow = chartGrid.addCol();
464
+ tmpRow.addRow({weight: 0.3});
465
+ const okButton = tmpRow.addRow().addTextButton({
466
+ text: 'OK',
467
+ backgroundColor: '#22aa33',
468
+ opacity: 0.5,
469
+ fontColor: '#66ccff',
470
+ fontSizeDp: 50,
471
+ });
472
+ }
473
+
474
+ init() {
475
+ this.add(new THREE.HemisphereLight(0xffffff, 0x666666, 3));
476
+
477
+ this.createProfilePanel();
478
+ this.createProfilePanelFromJSON();
479
+ this.createPlayerPanel();
480
+ this.createGalleryPanel();
481
+ this.createChartPanel();
482
+ this.createSettingsPanel();
483
+ }
484
+ }
485
+
486
+ document.addEventListener('DOMContentLoaded', function () {
487
+ const options = new xb.Options();
488
+ options.simulator.instructions.enabled = false;
489
+ options.enableUI();
490
+ options.setAppTitle('Spatial UI');
491
+ xb.add(new MainScript());
492
+ xb.init(options);
493
+ });
494
+ </script>
495
+ </body>
496
+ </html>