janusweb 1.5.42 → 1.5.43

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/CHANGELOG CHANGED
@@ -1,3 +1,26 @@
1
+ JanusWeb 1.5.42
2
+ ===============
3
+ - New Features
4
+ - TiltBrush / OpenBrush support via three-icosa
5
+ - VOIP "start call" button
6
+ - Synced avatar morphtargets over network
7
+ - New <outliner> built-in element
8
+ - Support for .hdr envmaps
9
+ - Updates
10
+ - glTF optimizations: KTX2 textures, Meshopt compression
11
+ - VR controller improvements
12
+ - Scriptable player walk/run speeds
13
+ - Editor improvements
14
+ - Upgrade Three.js to r140
15
+ - Bugfixes
16
+ - Handle localStorage permission rejection
17
+ - Fixed particle rates < 1 particle per frame
18
+ - Fixed toon shader for <room toon="true">
19
+ - Material fixes for emissive, clearcoat, transmission tint, etc
20
+ - Fixed FBX texture load path
21
+ - Update player gravity when flying is toggled
22
+
23
+
1
24
  JanusWeb 1.5
2
25
  ============
3
26
  - Threejs upgrade to r133
package/css/janusweb.css CHANGED
@@ -263,7 +263,8 @@ janus-viewer section {
263
263
  janus-viewer ui-scrollindicator {
264
264
  text-align: center;
265
265
  position: absolute;
266
- bottom: 5vh;
266
+ bottom: 2vh;
267
+ overflow: hidden;
267
268
  }
268
269
  janus-viewer ui-scrollindicator:after {
269
270
  border-left: 4px solid white;
@@ -271,6 +272,7 @@ janus-viewer ui-scrollindicator:after {
271
272
  width: 50px;
272
273
  height: 50px;
273
274
  transform: rotate(-45deg);
275
+ transform-origin: 0 5px;
274
276
  display: block;
275
277
  animation: scrollindicator-bounce 1s infinite;
276
278
  content: ' ';
@@ -301,6 +303,9 @@ janus-overlay[hidden] {
301
303
  pointer-events: none;
302
304
  display: block !important;
303
305
  }
304
- fireboxroom {
306
+ janus-viewer room,
307
+ janus-viewer assets,
308
+ fireboxroom room,
309
+ fireboxroom assets {
305
310
  display: none;
306
311
  }
@@ -202,16 +202,25 @@ elation.elements.define('janus-button-audio', class extends elation.elements.ui.
202
202
  init() {
203
203
  super.init();
204
204
  this.defineAttribute('muted', { type: 'boolean' });
205
+ janus.engine.systems.sound.getOutputChannel().then(c => this.output_main = c);
205
206
  }
206
207
  create() {
208
+ /*
207
209
  this.popupcontent = `
208
- <ui-slider name="volume_env" label="Environment" min="0" max="1.2" value="1"></ui-slider>
209
- <ui-slider name="volume_voip" label="Voice Chat" min="0" max="1.2" value="1"></ui-slider>
210
+ <ui-slider name="volume_env" label="Main Volume" min="0" max="150" value="100" snap="1"></ui-slider>
211
+ <ui-slider name="volume_voip" label="Voice Chat" min="0" max="150" value="100" snap="1"></ui-slider>
212
+ `;
213
+ */
214
+ this.popupcontent = `
215
+ <ui-slider name="volume_env" label="Main Volume" min="0" max="150" value="100" snap="1"></ui-slider>
210
216
  `;
211
217
  super.create();
212
218
  this.createPopup();
213
219
  this.hidePopup();
214
- elation.events.add(this.popup.content.elements['volume_env'], 'change', (ev) => this.adjustEnvironmentVolume(ev.data));
220
+
221
+ console.log(this.popup.content);
222
+ elation.events.add(this.popup.content.querySelector('[name="volume_env"]'), 'change', (ev) => this.adjustEnvironmentVolume(ev.data));
223
+ //elation.events.add(this.popup.content.querySelector('[name="volume_voip"]'), 'change', (ev) => this.adjustVoipVolume(ev.data));
215
224
  //this.addEventListener('click', (ev) => this.handleClick(ev));
216
225
 
217
226
  let soundsystem = janus.engine.systems.sound;
@@ -226,10 +235,15 @@ elation.elements.define('janus-button-audio', class extends elation.elements.ui.
226
235
  elation.events.add(soundsystem, 'sound_enabled', (ev) => this.updateMuteState());
227
236
  }
228
237
  adjustEnvironmentVolume(volume) {
238
+ //console.log('adjust environment output', room.audionodes.gain.gain.value);
239
+ /*
229
240
  if (room.audionodes) {
230
241
  room.audionodes.gain.gain.value = volume;
231
242
  this.updateMuteState();
232
243
  }
244
+ */
245
+ console.log(volume);
246
+ janus.engine.systems.sound.reallistener.gain.gain.value = volume / 100;
233
247
  }
234
248
  adjustVOIPVolume(volume) {
235
249
  // TODO
@@ -52,7 +52,7 @@ elation.elements.define('janus-comms-status', class extends elation.elements.bas
52
52
  this.state = 'disconnected';
53
53
  }
54
54
  }
55
- this.elements = elation.elements.fromTemplate('janus.comms.status', this);
55
+ this.refresh();
56
56
 
57
57
  //elation.events.add(player._target, 'username_change', (ev) => this.handleUsernameChange(ev));
58
58
  }
@@ -1,10 +1,13 @@
1
1
  janus-voip-client {
2
- display: flex;
3
2
  border: 1px solid black;
4
3
  position: relative;
5
4
  max-width: 75vh;
6
5
  flex-wrap: wrap;
7
6
  }
7
+ janus-voip-client-janus {
8
+ display: flex;
9
+ flex-direction: horizontal;
10
+ }
8
11
  janus-voip-localuser {
9
12
  display: block;
10
13
  bottom: 0px;
@@ -20,7 +23,7 @@ janus-voip-localuser video {
20
23
  margin: 1px 0 0 1px;
21
24
  }
22
25
  janus-voip-remoteuser {
23
- display: inline-block;
26
+ xdisplay: inline-block;
24
27
  border: 2px solid black;
25
28
  position: relative;
26
29
  font-family: monospace;
@@ -34,7 +37,7 @@ janus-voip-remoteuser video {
34
37
  height: 128px;
35
38
  }
36
39
  janus-voip-remoteuser video.active {
37
- display: block;
40
+ display: inline-block;
38
41
  }
39
42
  janus-voip-remoteuser[active] {
40
43
  transform: scale(1, 1);
@@ -68,6 +71,7 @@ janus-voip-localuser ui-button {
68
71
  font-size: 0;
69
72
  width: auto;
70
73
  transition: opacity 100ms linear;
74
+ z-index: 100;
71
75
  }
72
76
  janus-voip-remoteuser ui-button {
73
77
  font-size: 0;
@@ -99,6 +103,11 @@ janus-voip-localuser ui-button.muted:before {
99
103
  }
100
104
  janus-voip-localuser:hover ui-button,
101
105
  janus-voip-remoteuser:hover ui-button {
106
+ display: block;
107
+ opacity: .6;
108
+ }
109
+ janus-voip-localuser ui-button:hover,
110
+ janus-voip-remoteuser ui-button:hover {
102
111
  display: block;
103
112
  opacity: 1;
104
113
  }
@@ -555,6 +555,7 @@ elation.elements.define('janus-voip-remoteuser', class extends elation.elements.
555
555
  }
556
556
  setUserData(data) {
557
557
  this.id = data.id;
558
+ console.log('got a remote voip user', data);
558
559
 
559
560
  if (!this.label) {
560
561
  let label = document.createElement('h2');
@@ -621,11 +622,12 @@ elation.elements.define('janus-voip-remoteuser', class extends elation.elements.
621
622
  if (!this.controlpanel) {
622
623
  this.controlpanel = elation.elements.create('ui-panel', { bottom: 1, append: this });
623
624
  this.mutebutton = elation.elements.create('ui-button', { label: 'Mute', name: "mutebutton", append: this.controlpanel });
624
- /*
625
- this.volume = elation.elements.create('ui-slider', { name: "volume", min: 0, max: 2, value: this.video.volume, append: this.controlpanel });
625
+ this.volume = elation.elements.create('ui-slider', { name: "volume", min: 0, max: 200, value: this.video.volume * 100, append: this.controlpanel, snap: 1 });
626
626
 
627
627
  elation.events.add(this.volume, 'change', (ev) => {
628
- remoteuser.setVolume(ev.data);
628
+ if (remoteuser) {
629
+ remoteuser.setVolume(ev.data / 100);
630
+ }
629
631
  this.muted = (ev.data == 0);
630
632
  if (this.muted && !this.mutebutton.hasclass('muted')) {
631
633
  this.mutebutton.addclass('muted');
@@ -633,7 +635,6 @@ elation.elements.define('janus-voip-remoteuser', class extends elation.elements.
633
635
  this.mutebutton.removeclass('muted');
634
636
  }
635
637
  });
636
- */
637
638
  elation.events.add(this.mutebutton, 'click', (ev) => {
638
639
  /*
639
640
  remoteuser.setVolume(0);
@@ -730,6 +731,7 @@ elation.elements.define('janus-voip-remoteuser', class extends elation.elements.
730
731
  }
731
732
  toggleMute() {
732
733
  this.muted = !this.muted;
734
+ console.log('mute?', this.muted, this);
733
735
  let remoteuser = janus.network.remoteplayers[this.id];
734
736
  if (this.muted) {
735
737
  this.mutebutton.addclass('muted');
@@ -977,12 +979,12 @@ elation.elements.define('janus-voip-picker-audio', class extends elation.element
977
979
 
978
980
  if (this.elements.inputDevice.value && this.elements.inputDevice.value != 'default') {
979
981
  console.log('input!', this.elements.inputDevice.value);
980
- constraints.audio.deviceId = { exact: this.elements.inputDevice.value };
982
+ constraints.audio.deviceId = { ideal: this.elements.inputDevice.value };
981
983
  }
982
984
  if (this.elements.videoDevice && this.elements.videoDevice.value && this.elements.videoDevice.value != 'none') {
983
985
  console.log('video!', this.elements.videoDevice.value);
984
986
  constraints.video = {
985
- deviceId: { exact: this.elements.videoDevice.value },
987
+ deviceId: { ideal: this.elements.videoDevice.value },
986
988
  height: 256,
987
989
  width: 256
988
990
  };
@@ -1344,3 +1346,11 @@ elation.elements.define('janus-voip-client-incomingcall', class extends elation.
1344
1346
  }
1345
1347
  }
1346
1348
  });
1349
+ elation.elements.define('janus-voip-client-none', class extends elation.elements.base {
1350
+ create() {
1351
+ }
1352
+ connect() {
1353
+ }
1354
+ setInputStream(stream) {
1355
+ }
1356
+ });
@@ -21,6 +21,7 @@ janus-ui-editor-property-integer {
21
21
  .janus_editor ui-input>ui-label {
22
22
  padding: .2em;
23
23
  vertical-align: middle;
24
+ min-width: auto;
24
25
  }
25
26
  .janus_editor ui-input>input {
26
27
  width: 100%;
@@ -157,23 +157,30 @@ elation.elements.define('janus.ui.editor.panel', class extends elation.elements.
157
157
  col: 'lime',
158
158
  opacity: .4,
159
159
  outline: 3,
160
+ layers: '10',
160
161
  });
161
162
  this.outliner_hover = room.createObject('outliner', {
162
163
  col: 'gray',
163
164
  opacity: .4,
164
165
  outline: 1,
166
+ layers: '10',
165
167
  });
166
168
  setTimeout(() => {
167
169
  this.outliner_selected.col = 'lime';
168
170
  this.outliner_hover.col = 'gray';
171
+ this.outliner_selected.setLayers('10');
172
+ this.outliner_hover.setLayers('10');
169
173
  }, 0);
174
+ let editor = this;
170
175
  this.outliner_hover.update = function() {
176
+ /*
171
177
  let rc = player.raycast();
172
178
  if (rc.length > 0 && rc[0].object !== room) {
173
179
  this.select(rc[0].object);
174
180
  } else {
175
181
  this.deselect();
176
182
  }
183
+ */
177
184
  }
178
185
  } else if (this.outliner_selected.room !== room) {
179
186
  room.appendChild(this.outliner_selected);
@@ -255,7 +262,7 @@ setTimeout(() => {
255
262
  this.roomedit.rotationsnap = snap;
256
263
  let manipulator = this.getManipulator();
257
264
  if (snap == 'Off') snap = 0;
258
- if (manipulator) manipulator.setRotationSnap(+snap * THREE.Math.DEG2RAD);
265
+ if (manipulator) manipulator.setRotationSnap(+snap * THREE.MathUtils.DEG2RAD);
259
266
  /*
260
267
  if (this.elements.rotatesnap.value != snap) {
261
268
  this.elements.rotatesnap.value = snap || 'Off';
@@ -703,7 +710,7 @@ console.log('set translation snap', ev.data, ev);
703
710
  this.editObjectSnapVector(obj[attrname], this.roomedit.snap);
704
711
  } else if (attrtype == 'euler') {
705
712
  let rot = new THREE.Euler();
706
- let move = (ev.deltaY > 0 ? -1 : 1) * this.roomedit.rotationsnap * THREE.Math.DEG2RAD;
713
+ let move = (ev.deltaY > 0 ? -1 : 1) * this.roomedit.rotationsnap * THREE.MathUtils.DEG2RAD;
707
714
  if (ev.ctrlKey) {
708
715
  rot.x += move;
709
716
  }
@@ -721,7 +728,7 @@ console.log('set translation snap', ev.data, ev);
721
728
  let quat2 = new THREE.Quaternion().setFromEuler(rot);
722
729
  quat.multiply(quat2);
723
730
  obj[attrname].radians.setFromQuaternion(quat);
724
- //this.editObjectSnapVector(obj[attrname], this.roomedit.rotationsnap * THREE.Math.DEG2RAD);
731
+ //this.editObjectSnapVector(obj[attrname], this.roomedit.rotationsnap * THREE.MathUtils.DEG2RAD);
725
732
  } else if (attrtype == 'color') {
726
733
  let move = 4/255 * (ev.deltaY < 0 ? 1 : -1);
727
734
 
@@ -741,9 +748,9 @@ console.log('set translation snap', ev.data, ev);
741
748
  col.g += move;
742
749
  col.b += move;
743
750
  }
744
- col.r = THREE.Math.clamp(col.r, 0, 1);
745
- col.g = THREE.Math.clamp(col.g, 0, 1);
746
- col.b = THREE.Math.clamp(col.b, 0, 1);
751
+ col.r = THREE.MathUtils.clamp(col.r, 0, 1);
752
+ col.g = THREE.MathUtils.clamp(col.g, 0, 1);
753
+ col.b = THREE.MathUtils.clamp(col.b, 0, 1);
747
754
  console.log('opacity after', obj.opacity);
748
755
  obj[mode] = col;
749
756
  obj.opacity = obj.opacity;
@@ -769,7 +776,7 @@ obj.opacity = obj.opacity;
769
776
  } else {
770
777
  amount /= divisor;
771
778
  }
772
- obj[attrname] = THREE.Math.clamp(obj[attrname] + amount, min, max);
779
+ obj[attrname] = THREE.MathUtils.clamp(obj[attrname] + amount, min, max);
773
780
 
774
781
  } else if (attrtype == 'boolean' || attrtype == 'bool') {
775
782
  if (ev.deltaY < 1) {
@@ -893,10 +900,10 @@ obj.updateDirvecsFromOrientation();
893
900
  else if (this.roomedit.snap == .01) amount = 15;
894
901
  else if (this.roomedit.snap == .001) amount = 5;
895
902
 
896
- let rot = new THREE.Euler().setFromVector3(vec.clone().multiplyScalar(amount * THREE.Math.DEG2RAD));
903
+ let rot = new THREE.Euler().setFromVector3(vec.clone().multiplyScalar(amount * THREE.MathUtils.DEG2RAD));
897
904
  let quat = new THREE.Quaternion();
898
905
  quat.setFromEuler(rot);
899
- //obj.rotation = V(rot.x * THREE.Math.RAD2DEG, rot.y * THREE.Math.RAD2DEG, rot.z * THREE.Math.RAD2DEG);
906
+ //obj.rotation = V(rot.x * THREE.MathUtils.RAD2DEG, rot.y * THREE.MathUtils.RAD2DEG, rot.z * THREE.MathUtils.RAD2DEG);
900
907
  obj.orientation.multiply(quat);
901
908
  console.log('rotate it', vec.clone().multiplyScalar(amount), amount, rot, quat);
902
909
 
@@ -915,9 +922,9 @@ console.log('rotate it', vec.clone().multiplyScalar(amount), amount, rot, quat);
915
922
  break;
916
923
  case 'col':
917
924
  let snap = 10 / 255;
918
- obj.col = V(THREE.Math.clamp(obj.col.r + vec.x * snap, 0, 1),
919
- THREE.Math.clamp(obj.col.g + vec.y * snap, 0, 1),
920
- THREE.Math.clamp(obj.col.b + vec.z * snap, 0, 1));
925
+ obj.col = V(THREE.MathUtils.clamp(obj.col.r + vec.x * snap, 0, 1),
926
+ THREE.MathUtils.clamp(obj.col.g + vec.y * snap, 0, 1),
927
+ THREE.MathUtils.clamp(obj.col.b + vec.z * snap, 0, 1));
921
928
 
922
929
  console.log('change color', obj.col, vec);
923
930
  break;
@@ -65,9 +65,9 @@ janus.registerElement('locomotion_teleporter', {
65
65
  rand_pos: V(.5,0,.5),
66
66
  accel: V(0,-1,0),
67
67
  rand_accel: V(0,2,0),
68
- rate: 50,
68
+ rate: 10,
69
69
  count: 60,
70
- duration: .5,
70
+ duration: 3,
71
71
  collision_id: '',
72
72
  collidable: false,
73
73
  pickable: false,
@@ -337,6 +337,7 @@ janus.registerElement('locomotion_teleporter', {
337
337
  enableCursor() {
338
338
  if (!room.teleport) return;
339
339
  this.visible = true;
340
+ this.particles.resetParticles();
340
341
  this.particles.visible = true;
341
342
  if (this.laser.room !== room._target) room.appendChild(this.laser);
342
343
  if (this.particles.room !== room._target) room.appendChild(this.particles);
@@ -2,5 +2,6 @@
2
2
  { "assettype": "image", "name": "xrmenu-button-home", "src": "./images/home-button.png", "hasalpha": true },
3
3
  { "assettype": "image", "name": "xrmenu-button-back", "src": "./images/previous-button.png", "hasalpha": true },
4
4
  { "assettype": "image", "name": "xrmenu-button-reset", "src": "./images/address-location.png", "hasalpha": true },
5
- { "assettype": "image", "name": "xrmenu-button-reload", "src": "./images/redo-arrow.png", "hasalpha": true }
5
+ { "assettype": "image", "name": "xrmenu-button-reload", "src": "./images/redo-arrow.png", "hasalpha": true },
6
+ { "assettype": "image", "name": "xrmenu-button-sound", "src": "./images/audio-settings.png", "hasalpha": true }
6
7
  ]
@@ -18,11 +18,32 @@ janus.registerElement('xrmenu', {
18
18
  this.worlddir = V();
19
19
  this.playervec = V();
20
20
 
21
+ this.panels = {};
22
+
21
23
  let xrmenu = janus.ui.apps.default.apps.xrmenu;
22
24
  let asseturl = xrmenu.resolveFullURL('./xrmenu-assets.json');
23
25
  fetch(asseturl).then(res => res.json()).then(assetlist => {
24
26
  this.assetpack = elation.engine.assets.loadJSON(assetlist, xrmenu.resolveFullURL('./'));
25
27
 
28
+ /*
29
+ * Navigation
30
+ * Home
31
+ * Respawn
32
+ * Exit VR
33
+ * Refresh
34
+ * Sound
35
+ * Output
36
+ * Output Select
37
+ * Volume Levels
38
+ * Environment
39
+ * Media
40
+ * Voices
41
+ * Input
42
+ * Input Select
43
+ * Volume Levels
44
+ * Settings
45
+ */
46
+
26
47
  this.buttons = {
27
48
  home: this.createObject('xrmenu-button', {
28
49
  pos: V(.08, 0, 0),
@@ -54,12 +75,31 @@ janus.registerElement('xrmenu', {
54
75
  //image_id: 'xrmenu-button-exitvr',
55
76
  //onactivate: (ev) => this.engine.client.stopXR(),
56
77
  }),
78
+ sound: this.createObject('xrmenu-button', {
79
+ pos: V(.56, 0, 0),
80
+ label: 'Exit VR',
81
+ image_id: 'xrmenu-button-sound',
82
+ //onactivate: (ev) => this.engine.client.stopXR(),
83
+ }),
57
84
  };
58
85
  this.buttons.home.addEventListener('activate', ev => janus.navigateHome());
59
86
  this.buttons.back.addEventListener('activate', ev => janus.navigateBack());
60
87
  this.buttons.reset.addEventListener('activate', ev => player.reset_position());
61
88
  this.buttons.reload.addEventListener('activate', ev => location.reload());
62
89
  this.buttons.exitvr.addEventListener('activate', ev => this.engine.client.stopXR());
90
+ this.buttons.sound.addEventListener('activate', ev => {
91
+ if (!this.panels['sound']) {
92
+ this.panels['sound'] = this.buttons.sound.createObject('xrmenu-popup', {
93
+ content: 'janus-voip-picker'
94
+ });
95
+ } else {
96
+ if (this.panels['sound'].parent === this.buttons.sound) {
97
+ this.buttons.sound.removeChild(this.panels['sound']);
98
+ } else {
99
+ this.buttons.sound.appendChild(this.panels['sound']);
100
+ }
101
+ }
102
+ });
63
103
  this.reflow();
64
104
  });
65
105
  },
@@ -138,7 +178,7 @@ janus.registerElement('xrmenu-popup', {
138
178
 
139
179
  create() {
140
180
 
141
- let element = elation.elements.create(this.content);
181
+ let element = elation.elements.create(this.content, { deferred: false });
142
182
  //document.body.appendChild(element);
143
183
  //this.shadowdom.appendChild(element);
144
184
 
@@ -147,14 +187,9 @@ janus.registerElement('xrmenu-popup', {
147
187
  //container.appendChild(element);
148
188
 
149
189
  setTimeout(() => {
150
- for (let i = 0; i < document.styleSheets.length; i++) {
151
- let styleel = document.createElement('link');
152
- styleel.rel = 'stylesheet';
153
- styleel.href = document.styleSheets[i].href;
154
- this.shadowdom.appendChild(styleel);
155
- }
156
- }, 1000);
157
-
190
+ console.log('LOADED????', janus.ui, janus.ui.apps.default);
191
+ this.initShadowStylesheets();
192
+ }, 0);
158
193
  this.shadowdom.appendChild(element);
159
194
  document.body.appendChild(container);
160
195
 
@@ -172,24 +207,7 @@ container.style.opacity = 0;
172
207
 
173
208
  this.elementcontainer = container;
174
209
 
175
- setTimeout(() => {
176
- let canvas = element.toCanvas(this.width, this.height, 1);
177
- /*
178
- document.body.appendChild(canvas);
179
- canvas.style.position = 'absolute';
180
- canvas.style.top = '0';
181
- canvas.style.left = '0';
182
- canvas.style.zIndex = 1000;
183
- canvas.style.border = '1px solid red';
184
- */
185
- this.loadNewAsset('image', {
186
- id: 'xrmenu-element-canvas',
187
- canvas: canvas,
188
- });
189
- this.plane.image_id = 'xrmenu-element-canvas';
190
- this.canvas = canvas;
191
- elation.events.add(canvas, 'update', ev => this.refresh());
192
- }, 1000);
210
+ this.initElementCanvas();
193
211
 
194
212
  this.plane = this.createObject('object', {
195
213
  id: 'plane',
@@ -210,6 +228,59 @@ canvas.style.border = '1px solid red';
210
228
  this.plane.addEventListener('mouseover', ev => this.handleMouseOver(ev));
211
229
  this.plane.addEventListener('mouseout', ev => this.handleMouseOut(ev));
212
230
  },
231
+ initElementCanvas() {
232
+ let element = this.element;
233
+
234
+ if (!(element && element.isConnected && element.toCanvas)) {
235
+ setTimeout(() => this.initElementCanvas(), 100);
236
+ return;
237
+ }
238
+
239
+ console.log(element.isConnected, element);
240
+ let canvas = element.toCanvas(this.width, this.height, 1);
241
+ /*
242
+ document.body.appendChild(canvas);
243
+ canvas.style.position = 'absolute';
244
+ canvas.style.top = '0';
245
+ canvas.style.left = '0';
246
+ canvas.style.zIndex = 1000;
247
+ canvas.style.border = '1px solid red';
248
+ */
249
+ this.loadNewAsset('image', {
250
+ id: 'xrmenu-element-canvas',
251
+ canvas: canvas,
252
+ });
253
+ this.plane.image_id = 'xrmenu-element-canvas';
254
+ this.canvas = canvas;
255
+ elation.events.add(canvas, 'asset_update', ev => this.refresh());
256
+
257
+ element.updateStylesheets(elation.engine.assets.corsproxy).then(d => {
258
+ element.updateCanvas();
259
+ this.refresh();
260
+ });
261
+
262
+ },
263
+ initShadowStylesheets() {
264
+ let promises = [];
265
+ for (let i = 0; i < document.styleSheets.length; i++) {
266
+ //promises.push(new Promise(accept => {
267
+ let styleel = document.createElement('link');
268
+ styleel.rel = 'stylesheet';
269
+ styleel.href = elation.engine.assets.corsproxy + document.styleSheets[i].href;
270
+ //styleel.onload = accept;
271
+ this.shadowdom.appendChild(styleel);
272
+ console.log('add link', document.styleSheets[i].href);
273
+ //}));
274
+ }
275
+ /*
276
+ Promise.all(promises).then(() => {
277
+ console.log('stylesheets loaded!');
278
+ setTimeout(() => {
279
+ this.element.updateCanvas().then(() => this.refresh());
280
+ }, 400);
281
+ });
282
+ */
283
+ },
213
284
  handleMouse(ev) {
214
285
  if (this.element && this.canvas) {
215
286
  let mousexy = [ev.data.uv.x * this.canvas.width, (1 - ev.data.uv.y) * this.canvas.height];
@@ -245,6 +316,16 @@ canvas.style.border = '1px solid red';
245
316
  this.currenttarget.dispatchEvent(mouseout);
246
317
  }
247
318
  this.currenttarget = target;
319
+ let mousemove = new EventClass('mousemove', {
320
+ bubbles: true,
321
+ cancelable: true,
322
+ screenX: mousexy[0],
323
+ screenY: mousexy[1],
324
+ clientX: mousexy[0],
325
+ clientY: mousexy[1],
326
+ view: window,
327
+ });
328
+ this.currenttarget.dispatchEvent(mousemove);
248
329
  //let mouseover = elation.events.clone(fakeev, { type: 'mouseover' });
249
330
  let mouseover = new EventClass('mouseover', {
250
331
  bubbles: true,
@@ -255,6 +336,7 @@ canvas.style.border = '1px solid red';
255
336
  clientY: mousexy[1],
256
337
  view: window,
257
338
  });
339
+ console.log(mouseover);
258
340
  target.dispatchEvent(mouseover);
259
341
  }
260
342
  }
@@ -426,12 +426,21 @@ ui-tooltip {
426
426
  ui-input {
427
427
  display: flex;
428
428
  }
429
+ ui-input>ui-label {
430
+ min-width: 5em;
431
+ }
429
432
  ui-input>input {
430
433
  flex: 1 1;
434
+ background: #999;
435
+ border: 1px solid black;
436
+ border-radius: 4px;
431
437
  }
438
+ ui-input>input:hover,
432
439
  ui-input>input[hover] {
440
+ background: #aaa;
433
441
  }
434
442
  ui-input>input:focus {
443
+ background: #bbb;
435
444
  }
436
445
  ui-input>input:active {
437
446
  }
@@ -675,6 +684,18 @@ ui-slider-handle {
675
684
  cursor: pointer;
676
685
  box-shadow: 0 0 5px rgba(0,0,0,.8);
677
686
  }
687
+ ui-slider-handle>ui-label {
688
+ pointer-events: none;
689
+ position: absolute;
690
+ left: 20px;
691
+ z-index: 100;
692
+ background: rgba(0,0,0,.5);
693
+ border-radius: 20px;
694
+ padding: 0 .4em;
695
+ }
696
+ ui-slider-track[hover] ui-slider-handle>ui-label {
697
+ display: block !important;
698
+ }
678
699
 
679
700
 
680
701
  /***********
@@ -881,6 +902,10 @@ ui-select>select {
881
902
  ui-select:hover>select {
882
903
  background: #555;
883
904
  }
905
+ ui-select>ui-label {
906
+ min-width: 5em;
907
+ }
908
+
884
909
 
885
910
  ui-formgroup {
886
911
  position: relative;
@@ -1242,3 +1267,20 @@ ui-spinner[full] {
1242
1267
  right: 0;
1243
1268
  background: rgba(0,0,0,.1);
1244
1269
  }
1270
+ ui-image-picker {
1271
+ display: block;
1272
+ }
1273
+ ui-image-picker ui-label {
1274
+ vertical-align: top;
1275
+ min-width: 5em;
1276
+ display: inline-block;
1277
+ }
1278
+ ui-image-picker canvas {
1279
+ width: 30px;
1280
+ height: 30px;
1281
+ border: 1px solid black;
1282
+ border-radius: 2px;
1283
+ padding: 2px;
1284
+ display: inline-block;
1285
+ vertical-align: top;
1286
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "janusweb",
3
3
  "description": "Web client for JanusVR worlds",
4
- "version": "1.5.42",
4
+ "version": "1.5.43",
5
5
  "main": "scripts/janusweb.js",
6
6
  "author": "James Baicoianu",
7
7
  "license": "MIT",
@@ -18,7 +18,7 @@
18
18
  "url": "https://github.com/jbaicoianu/janusweb"
19
19
  },
20
20
  "dependencies": {
21
- "elation-engine": ">=0.9.73",
21
+ "elation-engine": ">=0.9.114",
22
22
  "uglify-es": "*"
23
23
  },
24
24
  "keywords": [
package/scripts/client.js CHANGED
@@ -1,4 +1,4 @@
1
- elation.require(['elements.elements', 'elements', 'engine.engine', 'engine.assets', 'engine.things.light_ambient', 'engine.things.light_directional', 'engine.things.light_point', 'janusweb.janusweb', 'janusweb.chat', 'janusweb.janusplayer', 'janusweb.janusxrplayer', 'janusweb.external.document-register-element', 'janusweb.ui.main', 'elements.elements'], function() {
1
+ elation.require(['elements.elements', 'elements', 'engine.engine', 'engine.assets', 'engine.things.light_ambient', 'engine.things.light_directional', 'engine.things.light_point', 'janusweb.janusweb', 'janusweb.janusplayer', 'janusweb.janusxrplayer', 'janusweb.ui.main'], function() {
2
2
  // If getCurrentScript returns non-null here, then it means we're in release mode
3
3
  var clientScript = elation.utils.getCurrentScript();
4
4