UNPKG

aframe-babia-components

Version:

A data visualization set of components for A-Frame.

372 lines (330 loc) 16.6 kB
<!-- All 3D models used in this scene as avatars are under the CC Attributes License or the CC Attribution-NonCommercial-ShareAlike License. All information is available at "../../assets/avatars/licenses_links.txt" --> <html> <head> <meta charset="utf-8" /> <title>Desert Demo — Networked-Aframe in BabiaXr</title> <meta name="description" content="New Demo NO sharing UI — Networked-Aframe in BabiaXr" /> <script src="https://aframe.io/releases/1.5.0/aframe.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.slim.js"></script> <script src="../easyrtc.js"></script> <script src="https://unpkg.com/networked-aframe@^0.8.0/dist/networked-aframe.js"></script> <script src="https://unpkg.com/aframe-teleport-controls/dist/aframe-teleport-controls.min.js"></script> <script src="https://unpkg.com/aframe-environment-component@1.3.3/dist/aframe-environment-component.min.js"></script> <script src="../../../dist/aframe-babia-components.js"></script> <script src="https://cdn.jsdelivr.net/gh/donmccurdy/aframe-extras@v7.2.0/dist/aframe-extras.min.js"></script> </head> <body> <a-scene id="AframeScene" networked-scene=" room: demo_desert; adapter: easyrtc; debug: true; audio: false; serverURL: empty_server; "> <a-assets> <!-- Dummy asset to make the scene sync (WIP)--> <img src="https://wallpapercave.com/wp/wp2345390.jpg?dummy=8484744"> <!-- Templates --> <!-- Avatar --> <template id="rig-template"> <a-entity class="rig"></a-entity> </template> <template id="camera-template"> <a-entity class="camera"></a-entity> </template> <template id="avatar-template"> <a-entity class="avatar" networked-audio-source></a-entity> </template> <!-- Bars --> <template id="bars-template"> <a-entity class="bars"></a-entity> </template> <!-- Querier, same one for all graphs --> <template id="querier-template"> <a-entity class="querier"></a-entity> </template> <!-- Avatar Assets --> <a-asset-item id="astro" src="../../assets/avatars/astro/scene.gltf"></a-asset-item> <a-asset-item id="bot" src="../../assets/avatars/bot/scene.gltf"></a-asset-item> <a-asset-item id="charmander" src="../../assets/avatars/charmander/scene.gltf"></a-asset-item> <a-asset-item id="dinosaur" src="../../assets/avatars/dinosaur/scene.gltf"></a-asset-item> <a-asset-item id="dwarf" src="../../assets/avatars/dwarf/scene.gltf"></a-asset-item> <a-asset-item id="nigiri" src="../../assets/avatars/nigiri/scene.gltf"></a-asset-item> <a-asset-item id="owl_sleep" src="../../assets/avatars/owl_sleep/scene.gltf"></a-asset-item> <a-asset-item id="penguin" src="../../assets/avatars/penguin/scene.gltf"></a-asset-item> <a-asset-item id="pidgeon" src="../../assets/avatars/pidgeon/scene.gltf"></a-asset-item> <a-asset-item id="rubberduck" src="../../assets/avatars/rubberduck/scene.gltf"></a-asset-item> <a-asset-item id="shiba" src="../../assets/avatars/shiba/scene.gltf"></a-asset-item> </a-assets> <!--Sync entities, not persistent--> <a-entity id="rig" position="0 0.5 -7" networked="template:#rig-template; attachTemplateToLocal:false"> <a-entity id="camera" camera look-controls wasd-controls="fly: false" networked="template:#camera-template;attachTemplateToLocal:false;"> <a-entity id="avatar" scale="0.25 0.25 0.25" gltf-model="#dinosaur" visible="false" rotation="0 180 0" networked="template:#avatar-template;attachTemplateToLocal:false"> </a-entity> </a-entity> <!-- Hand Controls --> <a-entity id="leftHand" oculus-touch-controls="hand: left" teleport-controls="cameraRig: #rig; teleportOrigin: #avatar; collisionEntities: #environmentGround; hitCylinderColor: #ff3468; curveHitColor: #ff3468; curveMissColor: #333333; curveLineWidth: 0.01; button: trigger"></a-entity> <a-entity id="rightHand" laser-controls="hand: right" oculus-touch-controls="hand: right" raycaster="objects: .babiaxraycasterclass, #audio_button"></a-entity> <a-entity id="cursor" cursor="rayOrigin:mouse" raycaster="objects: .babiaxraycasterclass, #audio_button"> </a-entity> </a-entity> <!-- Sync entities, persistent --> <a-entity id="querierData" babia-queryjson="url: ../data_vaccination.json;" networked="template:#querier-template; networkId:querier; persistent: true; owner: scene"></a-entity> <a-entity id="bars" babia-bars='index: country; height: partial; legend: true; axis: true; axis_name: true; palette: foxy; title: babia-bars; titleColor: #FFFFFF; titleFont: #optimerBoldFont; titlePosition: -8.5 0.3 0.5; heightMax: 100; animation: true; from: querierData' networked="template:#bars-template; networkId:bars; persistent: true; owner: scene" position="-5 0.2 -10" rotation="0 0 0" scale="0.25 0.5 0.25"></a-entity> <!--Not sync entities--> <a-plane id="audio_button" position="5 1.5 -10" rotation="0 -45 0" height="0.5" width="1.5" color="#E44B00"> <a-text id="audio_label" value="Stop Audio" color="#0582B5" width="4" position="-0.5 0 0" rotation="0 0 0"> </a-text> </a-plane> <a-entity id="ui_bars" babia-ui="target: bars" position="-15 1 -5" rotation="0 45 0" scale="0.5 0.5 0.5"> </a-entity> <a-entity environment="preset: yavapai; skyType: color; skyColor: #358DF8 "></a-entity> <a-light type="point" intensity="1" position="-10 20 30"></a-light> </a-scene> <script> /* GET DOM ELEMENTS */ let scene = document.getElementById('AframeScene'); let rig = document.querySelector('#rig'); let avatar = document.getElementById('avatar'); let hand_right = document.getElementById('rightHand'); let audioButton = document.getElementById('audio_button'); let audioLabel = document.getElementById('audio_label'); let bars = document.getElementById('bars'); let uiDesktop = document.getElementById('ui_bars'); /* SET AVATAR FROM QUERY STRING */ let y = 0; let chosenAvatar = getValueFromQueryString('avatar'); if (chosenAvatar) { if (chosenAvatar == 'astro') { avatar.setAttribute("gltf-model", "#astro"); avatar.setAttribute('scale', '0.0015 0.0015 0.0015'); avatar.setAttribute('position', '0 -0.5 0') } else if (chosenAvatar == 'bot') { avatar.setAttribute("gltf-model", "#bot"); avatar.setAttribute('scale', '0.1 0.1 0.1'); avatar.setAttribute('rotation', '0 90 0'); avatar.setAttribute('position', '0 0.1 0'); } else if (chosenAvatar == 'charmander') { avatar.setAttribute("gltf-model", "#charmander"); avatar.setAttribute('scale', '0.025 0.025 0.025'); avatar.setAttribute('position', '0 0.5 0'); } else if (chosenAvatar == 'dinosaur') { avatar.setAttribute("gltf-model", "#dinosaur"); avatar.setAttribute('scale', '0.25 0.25 0.25'); avatar.setAttribute('position', '0 0.3 0'); } else if (chosenAvatar == 'dwarf') { avatar.setAttribute("gltf-model", "#dwarf"); avatar.setAttribute('scale', '0.4 0.4 0.4'); avatar.setAttribute('position', '0 -0.5 0') } else if (chosenAvatar == 'nigiri') { avatar.setAttribute("gltf-model", "#nigiri"); avatar.setAttribute('scale', '0.015 0.015 0.015'); avatar.setAttribute('position', '0 -0.5 0') } else if (chosenAvatar == 'owl_sleep') { avatar.setAttribute("gltf-model", "#owl_sleep"); avatar.setAttribute('scale', '0.4 0.4 0.4'); avatar.setAttribute('position', '0 -0.5 0') } else if (chosenAvatar == 'penguin') { avatar.setAttribute("gltf-model", "#penguin"); avatar.setAttribute('scale', '1 1 1'); avatar.setAttribute('position', '0 1 0'); } else if (chosenAvatar == 'pidgeon') { avatar.setAttribute("gltf-model", "#pidgeon"); avatar.setAttribute('scale', '1.4 1.4 1.4'); avatar.setAttribute('rotation', '0 0 0'); avatar.setAttribute('position', '0 -0.5 0') } else if (chosenAvatar == 'rubberduck') { avatar.setAttribute("gltf-model", "#rubberduck"); avatar.setAttribute('scale', '1.5 1.5 1.5'); avatar.setAttribute('rotation', '0 90 0'); avatar.setAttribute('position', '0 -0.5 0') } else if (chosenAvatar == 'shiba') { avatar.setAttribute("gltf-model", "#shiba"); avatar.setAttribute('scale', '0.75 0.75 0.75'); avatar.setAttribute('position', '0 1 0'); } } /* SET SERVER URL FROM QUERY STRING */ let serverURL = getValueFromQueryString('serverURL'); console.log("Empty server URL, networked-scene: ", scene.getAttribute('networked-scene')); if (serverURL) { scene.setAttribute('networked-scene', 'serverURL', serverURL); scene.setAttribute('networked-scene', 'audio', 'true'); } /* UI Event Listeners */ // VR started document.addEventListener('controllerconnected', (event) => { rig.setAttribute('position', "0 0 -7"); if (chosenAvatar == 'astro') { avatar.setAttribute('position', '0 -1.25 0') } else if (chosenAvatar == 'bot') { avatar.setAttribute('position', '0 -0.65 0'); } else if (chosenAvatar == 'charmander') { avatar.setAttribute('position', '0 -0.25 0'); } else if (chosenAvatar == 'dinosaur') { avatar.setAttribute('position', '0 -0.45 0'); } else if (chosenAvatar == 'dwarf') { avatar.setAttribute('position', '0 -1.25 0') } else if (chosenAvatar == 'nigiri') { avatar.setAttribute('position', '0 -1.25 0') } else if (chosenAvatar == 'owl_sleep') { avatar.setAttribute('position', '0 -1.25 0') } else if (chosenAvatar == 'penguin') { avatar.setAttribute('position', '0 0.25 0'); } else if (chosenAvatar == 'pidgeon') { avatar.setAttribute('position', '0 -1.25 0') } else if (chosenAvatar == 'rubberduck') { avatar.setAttribute('position', '0 -1.25 0') } else if (chosenAvatar == 'shiba') { avatar.setAttribute('position', '0 0.25 0'); } }); // AudioButton audioButton.addEventListener('click', function (event) { if (audioLabel.getAttribute('value') === 'Stop Audio') { stopAudio(); } else { turnOnAudio(); } }); // uiDesktop uiDesktop.addEventListener('click', function (event) { if (!NAF.utils.isMine(bars)) { NAF.utils.takeOwnership(bars); } }); document.addEventListener('controllerconnected', (event) => { console.log("controller connected"); }); scene.addEventListener('child-attached', function (event) { if (event.detail.el.id === 'babia-menu-hand') { console.log('uiVR has been added: ', event.target.children["babia-menu-hand"]); let uiVR = document.querySelector('#babia-menu-hand'); uiVR.addEventListener('click', function (event) { if (!NAF.utils.isMine(bars)) { NAF.utils.takeOwnership(bars); }; }); } }); /* NAF Messages */ // Subscriptions NAF.connection.subscribeToDataChannel('hello_message', function (senderId, dataType, data, targetId) { console.log('Message received: ', data); }) // Senders // One client function sendMessage(client, dataType, data) { NAF.connection.sendDataGuaranteed(client, dataType, data); console.log(`message sent to ${client}`); }; // To everyone function broadcastMessage(dataType, data) { NAF.connection.broadcastDataGuaranteed(dataType, data); console.log(`message broadcasted`); }; /* NAF Event Listeners */ // Connected document.body.addEventListener('connected', function (event) { console.log('connected event. clientId =', event.detail.clientId); console.log("Filled serverURL, networked-scene: ", scene.getAttribute('networked-scene')); let message = 'Hello everyone! I am: ' + event.detail.clientId; broadcastMessage('hello_message', message); }); // Client Connected document.body.addEventListener('clientConnected', function (event) { let clientId = event.detail.clientId; console.log('clientConnected event. clientId =', clientId); let message = 'Hello, ' + clientId + '! I am ' + NAF.clientId; sendMessage(clientId, 'hello_message', message); }); // Client Disconnected document.body.addEventListener('clientDisconnected', function (event) { let clientId = event.detail.clientId; console.log('clientDisconnected event. clientId =', clientId); }); /* Ownership Event Listeners */ // Bars bars.addEventListener('ownership-gained', e => { console.log("Bars ownership gained"); }); bars.addEventListener('ownership-lost', e => console.log("Bars ownership lost")); /* Other methods */ // Get Server function getValueFromQueryString(string) { string = string.replace(/[\[\]]/g, '\\$&'); var regex = new RegExp('[?&]' + string + '(=([^&#]*)|&|#|$)'), results = regex.exec(window.location.href); if (!results) return null; if (!results[2]) return ''; return decodeURIComponent(results[2].replace(/\+/g, ' ')); } // Audio function turnOnAudio() { NAF.connection.adapter.enableMicrophone(true); audioButton.setAttribute('color', '#E44B00'); audioLabel.setAttribute('value', 'Stop Audio'); } function stopAudio() { NAF.connection.adapter.enableMicrophone(false); audioButton.setAttribute('color', '#F8F6F2'); audioLabel.setAttribute('value', 'Turn on Audio'); } </script> <script> // Schemas with components and attributes for syncronization NAF.schemas.add({ template: '#rig-template', components: [ 'position', 'rotation' ] }); NAF.schemas.add({ template: '#camera-template', components: [ 'position', 'rotation' ] }); NAF.schemas.add({ template: '#avatar-template', components: [ 'position', 'rotation', 'scale', 'gltf-model' ] }); // Important to add here the graph component NAF.schemas.add({ template: '#bars-template', components: [ 'position', 'rotation', 'scale', 'babia-bars' ] }); NAF.schemas.add({ template: '#querier-template', components: [ 'babia-queryjson' ] }); </script> </body> </html>