janusweb 1.5.42 → 1.5.44

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 (34) hide show
  1. package/CHANGELOG +23 -0
  2. package/css/janusweb.css +7 -2
  3. package/media/assets/webui/apps/buttons/buttons.js +17 -3
  4. package/media/assets/webui/apps/comms/comms.css +1 -1
  5. package/media/assets/webui/apps/comms/comms.js +1 -1
  6. package/media/assets/webui/apps/comms/voip.css +12 -3
  7. package/media/assets/webui/apps/comms/voip.js +16 -6
  8. package/media/assets/webui/apps/editor/editor.css +1 -0
  9. package/media/assets/webui/apps/editor/editor.js +19 -12
  10. package/media/assets/webui/apps/locomotion/teleporter.js +11 -4
  11. package/media/assets/webui/apps/xrmenu/images/audio-settings.png +0 -0
  12. package/media/assets/webui/apps/xrmenu/xrmenu-assets.json +2 -1
  13. package/media/assets/webui/apps/xrmenu/xrmenu.js +142 -40
  14. package/media/assets/webui/themes/default.css +42 -0
  15. package/package.json +2 -2
  16. package/scripts/client.js +12 -1
  17. package/scripts/config.js +1 -1
  18. package/scripts/elements/outliner.js +7 -1
  19. package/scripts/external/JanusClientConnection.js +14 -8
  20. package/scripts/image.js +1 -1
  21. package/scripts/janusbase.js +49 -27
  22. package/scripts/janusghost.js +14 -10
  23. package/scripts/januslight.js +46 -4
  24. package/scripts/janusparticle.js +116 -13
  25. package/scripts/janusplayer.js +97 -22
  26. package/scripts/janusweb.js +18 -5
  27. package/scripts/janusxrplayer.js +117 -17
  28. package/scripts/object.js +75 -31
  29. package/scripts/parts.js +1 -1
  30. package/scripts/portal.js +21 -10
  31. package/scripts/remoteplayer.js +3 -2
  32. package/scripts/room.js +159 -49
  33. package/scripts/text.js +7 -4
  34. package/scripts/websurface.js +3 -3
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
@@ -169,4 +169,4 @@ janus-voip-picker>ul li button[disabled] {
169
169
  color: #888;
170
170
  text-shadow: 0 0 5px #444;
171
171
  cursor: not-allowed;
172
-
172
+ }
@@ -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,
@@ -167,8 +167,14 @@ janus.registerElement('locomotion_teleporter', {
167
167
  speed = dir.length();
168
168
  dir.divideScalar(speed);
169
169
  let hits = room.raycast(dir, p0, null, speed);
170
- if (hits.length > 0) {
171
- let hit = hits[0];
170
+ let hit = false;
171
+ for (let j = 0; j < hits.length; j++) {
172
+ if (hits[j].object !== player) {
173
+ hit = hits[j];
174
+ break;
175
+ }
176
+ }
177
+ if (hit) {
172
178
  p1.copy(hit.point);
173
179
  if (hit.distance < 200) {
174
180
  this.pos = player.worldToLocal(hit.point);
@@ -337,6 +343,7 @@ janus.registerElement('locomotion_teleporter', {
337
343
  enableCursor() {
338
344
  if (!room.teleport) return;
339
345
  this.visible = true;
346
+ this.particles.resetParticles();
340
347
  this.particles.visible = true;
341
348
  if (this.laser.room !== room._target) room.appendChild(this.laser);
342
349
  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,33 @@ 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;
24
+ if (!xrmenu) return;
22
25
  let asseturl = xrmenu.resolveFullURL('./xrmenu-assets.json');
23
26
  fetch(asseturl).then(res => res.json()).then(assetlist => {
24
27
  this.assetpack = elation.engine.assets.loadJSON(assetlist, xrmenu.resolveFullURL('./'));
25
28
 
29
+ /*
30
+ * Navigation
31
+ * Home
32
+ * Respawn
33
+ * Exit VR
34
+ * Refresh
35
+ * Sound
36
+ * Output
37
+ * Output Select
38
+ * Volume Levels
39
+ * Environment
40
+ * Media
41
+ * Voices
42
+ * Input
43
+ * Input Select
44
+ * Volume Levels
45
+ * Settings
46
+ */
47
+
26
48
  this.buttons = {
27
49
  home: this.createObject('xrmenu-button', {
28
50
  pos: V(.08, 0, 0),
@@ -54,12 +76,31 @@ janus.registerElement('xrmenu', {
54
76
  //image_id: 'xrmenu-button-exitvr',
55
77
  //onactivate: (ev) => this.engine.client.stopXR(),
56
78
  }),
79
+ sound: this.createObject('xrmenu-button', {
80
+ pos: V(.56, 0, 0),
81
+ label: 'Exit VR',
82
+ image_id: 'xrmenu-button-sound',
83
+ //onactivate: (ev) => this.engine.client.stopXR(),
84
+ }),
57
85
  };
58
86
  this.buttons.home.addEventListener('activate', ev => janus.navigateHome());
59
87
  this.buttons.back.addEventListener('activate', ev => janus.navigateBack());
60
88
  this.buttons.reset.addEventListener('activate', ev => player.reset_position());
61
89
  this.buttons.reload.addEventListener('activate', ev => location.reload());
62
90
  this.buttons.exitvr.addEventListener('activate', ev => this.engine.client.stopXR());
91
+ this.buttons.sound.addEventListener('activate', ev => {
92
+ if (!this.panels['sound']) {
93
+ this.panels['sound'] = this.buttons.sound.createObject('xrmenu-popup', {
94
+ content: 'janus-voip-picker'
95
+ });
96
+ } else {
97
+ if (this.panels['sound'].parent === this.buttons.sound) {
98
+ this.buttons.sound.removeChild(this.panels['sound']);
99
+ } else {
100
+ this.buttons.sound.appendChild(this.panels['sound']);
101
+ }
102
+ }
103
+ });
63
104
  this.reflow();
64
105
  });
65
106
  },
@@ -138,7 +179,7 @@ janus.registerElement('xrmenu-popup', {
138
179
 
139
180
  create() {
140
181
 
141
- let element = elation.elements.create(this.content);
182
+ let element = elation.elements.create(this.content, { deferred: false });
142
183
  //document.body.appendChild(element);
143
184
  //this.shadowdom.appendChild(element);
144
185
 
@@ -146,50 +187,36 @@ janus.registerElement('xrmenu-popup', {
146
187
  this.shadowdom = container.attachShadow({mode: 'open'});
147
188
  //container.appendChild(element);
148
189
 
149
- 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
-
158
- this.shadowdom.appendChild(element);
190
+ setTimeout(() => {
191
+ this.initShadowStylesheets();
192
+ }, 0);
193
+ //this.shadowdom.appendChild(element);
194
+ let a = document.createElement('html');
195
+ let b = document.createElement('body');
196
+ b.className = 'dark janusweb';
197
+ a.appendChild(b);
198
+ this.shadowdom.appendChild(a);
199
+ b.appendChild(element);
159
200
  document.body.appendChild(container);
160
201
 
202
+ elation.events.add(element, 'styleupdate', ev => {
203
+ this.initShadowStylesheets();
204
+ });
161
205
 
162
- container.style.position = 'absolute';
163
- container.style.top = '0';
164
- container.style.left = '0';
165
- container.style.zIndex = -1000;
166
- container.style.width = this.width + 'px';
167
- container.style.height = this.height + 'px';
168
- container.style.overflow = 'auto';
169
- container.style.opacity = 0;
170
- //container.style.transform = 'translateX(-40000px)';
171
- //container.style.border = '1px solid red';
206
+ container.style.position = 'absolute';
207
+ container.style.top = '0';
208
+ container.style.left = '0';
209
+ container.style.zIndex = -1000;
210
+ container.style.width = this.width + 'px';
211
+ container.style.height = this.height + 'px';
212
+ container.style.overflow = 'hidden';
213
+ container.style.opacity = 0;
214
+ //container.style.transform = 'translateX(-40000px)';
215
+ //container.style.border = '1px solid red';
172
216
 
173
- this.elementcontainer = container;
217
+ this.elementcontainer = container;
174
218
 
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);
219
+ this.initElementCanvas();
193
220
 
194
221
  this.plane = this.createObject('object', {
195
222
  id: 'plane',
@@ -210,6 +237,71 @@ canvas.style.border = '1px solid red';
210
237
  this.plane.addEventListener('mouseover', ev => this.handleMouseOver(ev));
211
238
  this.plane.addEventListener('mouseout', ev => this.handleMouseOut(ev));
212
239
  },
240
+ initElementCanvas() {
241
+ let element = this.element;
242
+
243
+ if (!(element && element.isConnected && element.toCanvas)) {
244
+ setTimeout(() => this.initElementCanvas(), 100);
245
+ return;
246
+ }
247
+
248
+ console.log(element.isConnected, element);
249
+ let canvas = element.toCanvas(this.width, this.height, 1);
250
+ /*
251
+ document.body.appendChild(canvas);
252
+ canvas.style.position = 'absolute';
253
+ canvas.style.top = '0';
254
+ canvas.style.left = '0';
255
+ canvas.style.zIndex = 1000;
256
+ canvas.style.border = '1px solid red';
257
+ */
258
+ this.loadNewAsset('image', {
259
+ id: 'xrmenu-element-canvas',
260
+ canvas: canvas,
261
+ transparent: true,
262
+ });
263
+ this.plane.image_id = 'xrmenu-element-canvas';
264
+ this.canvas = canvas;
265
+ elation.events.add(canvas, 'asset_update', ev => this.refresh());
266
+
267
+ element.updateStylesheets(elation.engine.assets.corsproxy).then(d => {
268
+ element.updateCanvas();
269
+ this.refresh();
270
+ });
271
+
272
+ },
273
+ initShadowStylesheets() {
274
+ let promises = [];
275
+ for (let i = 0; i < document.styleSheets.length; i++) {
276
+ //promises.push(new Promise(accept => {
277
+ if (document.styleSheets[i].href ) {
278
+ // external stylesheet
279
+ let styleel = document.createElement('link');
280
+ styleel.rel = 'stylesheet';
281
+ styleel.href = elation.engine.assets.corsproxy + document.styleSheets[i].href;
282
+ this.shadowdom.appendChild(styleel);
283
+ } else if (document.styleSheets[i].cssRules.length > 0) {
284
+ // inline <style> definition
285
+ let txt = '';
286
+ let sheet = document.styleSheets[i];
287
+ for (let i = 0; i < sheet.cssRules.length; i++) {
288
+ txt += sheet.cssRules[i].cssText + '\n';
289
+ }
290
+ let styleel = document.createElement('style');
291
+ styleel.appendChild(document.createTextNode(txt));
292
+ this.shadowdom.appendChild(styleel);
293
+ }
294
+ //}));
295
+ }
296
+ /*
297
+ Promise.all(promises).then(() => {
298
+ console.log('stylesheets loaded!');
299
+ setTimeout(() => {
300
+ this.element.updateCanvas().then(() => this.refresh());
301
+ }, 400);
302
+ });
303
+ */
304
+ },
213
305
  handleMouse(ev) {
214
306
  if (this.element && this.canvas) {
215
307
  let mousexy = [ev.data.uv.x * this.canvas.width, (1 - ev.data.uv.y) * this.canvas.height];
@@ -245,6 +337,16 @@ canvas.style.border = '1px solid red';
245
337
  this.currenttarget.dispatchEvent(mouseout);
246
338
  }
247
339
  this.currenttarget = target;
340
+ let mousemove = new EventClass('mousemove', {
341
+ bubbles: true,
342
+ cancelable: true,
343
+ screenX: mousexy[0],
344
+ screenY: mousexy[1],
345
+ clientX: mousexy[0],
346
+ clientY: mousexy[1],
347
+ view: window,
348
+ });
349
+ this.currenttarget.dispatchEvent(mousemove);
248
350
  //let mouseover = elation.events.clone(fakeev, { type: 'mouseover' });
249
351
  let mouseover = new EventClass('mouseover', {
250
352
  bubbles: true,