[v\:* {behavior:url(#default#threejs);} o\:* {behavior:url(#default#threejs);} w\:* {behavior:url(#default#threejs);} .shape {behavior:url(#default#threejs);} ] import WebGL from 'https://threejs.org/threejs/addon/capabilities/WebGL.js'; if ( WebGL.isWebGL2Available() ) { // Initiate function or other initializations here animate(); } else { const warning = WebGL.getWebGL2ErrorMessage(); document.getElementById( 'container' ).appendChild( warning ); } { "imports": { "three": "https://cdn.jsdelivr.net/npm/three@0.160.0/build/three.module.js", "three/addons/": "https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/" } } const scene = document.getElementById('mainScene'); const boothDataTemplate = [ { label: "https://cdn.pixabay.com/photo/2016/11/29/03/53/architecture-1867187_1280.jpg", url: "https://www.google.com" }, { label: "https://cdn.pixabay.com/photo/2017/08/30/01/05/milky-way-2695569_1280.jpg", url: "https://www.wikipedia.org" }, ]; const layers = [ { radius: 15, count: 12 }, { radius: 30, count: 24 }, { radius: 45, count: 36 } ]; function createPart(shapeType, size, translation, color, rotation = null) { if(rotation) trans.setAttribute('rotation', rotation); let shape = document.createElement('shape'); let app = document.createElement('appearance'); let mat = document.createElement('material'); mat.setAttribute('diffuseColor', color); let geom = document.createElement(shapeType); if(shapeType === 'box') geom.setAttribute('size', size); else if(shapeType === 'cylinder') { let dims = size.split(' '); geom.setAttribute('radius', dims[0]); geom.setAttribute('height', dims[1]); } app.appendChild(mat); shape.appendChild(app); shape.appendChild(geom); trans.appendChild(shape); return trans; } function createLabel(textString, translation, rotation = null) { let trans = document.createElement('transform'); trans.setAttribute('translation', translation); trans.setAttribute('scale', '0.25 0.25 0.25'); if(rotation) trans.setAttribute('rotation', rotation); let shape = document.createElement('shape'); let app = document.createElement('appearance'); let mat = document.createElement('material'); mat.setAttribute('diffuseColor', '0 0 0'); let txt = document.createElement('text'); txt.setAttribute('string', `"${textString}"`); let font = document.createElement('fontstyle'); font.setAttribute('family', "'SANS'"); font.setAttribute('justify', '"MIDDLE" "MIDDLE"'); font.setAttribute('style', 'BOLD'); txt.appendChild(font); app.appendChild(mat); shape.appendChild(app); shape.appendChild(txt); trans.appendChild(shape); return trans; } setInterval(() => { let fps = document.getElementById('root').runtime.getFPS(); let fog = document.getElementById('myFog'); let range = parseInt(fog.getAttribute('visibilityRange')); if (fps < 30 && range > 30) { fog.setAttribute('visibilityRange', range - 5); } else if (fps > 55 && range < 200) { fog.setAttribute('visibilityRange', range + 2); } }, 2000); function createFloatingBox(data, idx) { let boxId = "box_" + idx; let rootTrans = document.createElement('transform'); rootTrans.setAttribute('translation', '0 1.2 0'); let ts = document.createElement('timeSensor'); ts.setAttribute('id', "ts_" + idx); ts.setAttribute('cycleInterval', '10'); ts.setAttribute('loop', 'true'); let oi = document.createElement('orientationInterpolator'); oi.setAttribute('id', "oi_" + idx); oi.setAttribute('key', '0 0.5 1'); oi.setAttribute('keyValue', '0 1 0 0, 0 1 0 3.14159, 0 1 0 6.28318'); let r1 = document.createElement('route'); r1.setAttribute('fromNode', "ts_" + idx); r1.setAttribute('fromField', 'fraction_changed'); r1.setAttribute('toNode', "oi_" + idx); r1.setAttribute('toField', 'set_fraction'); let r2 = document.createElement('route'); r2.setAttribute('fromNode', "oi_" + idx); r2.setAttribute('fromField', 'value_changed'); r2.setAttribute('toNode', boxId); r2.setAttribute('toField', 'set_rotation'); let boxTrans = document.createElement('transform'); boxTrans.setAttribute('id', boxId); let shape = document.createElement('shape'); let app = document.createElement('appearance'); let tex = document.createElement('ImageTexture'); tex.setAttribute('url', `"${data.img}"`); shape.onclick = function() { window.open(data.url, '_blank'); }; let boxGeom = document.createElement('box'); boxGeom.setAttribute('size', '1.2 1.2 1.2'); app.appendChild(tex); shape.appendChild(app); shape.appendChild(boxGeom); boxTrans.appendChild(shape); rootTrans.append(ts, oi, boxTrans, r1, r2); return rootTrans; } let globalIndex = 0; layers.forEach((layer, layerIdx) => { for (let i = 0; i < layer.count; i++) { let angle = (i / layer.count) * Math.PI * 2; let x = Math.cos(angle) * layer.radius; let z = Math.sin(angle) * layer.radius; let themeColor = `${Math.random()} ${Math.random()} ${Math.random()}`; boothGroup.appendChild(createTriangleLight("0 3.2 0")); boothGroup.appendChild(createFloatingBox(data, globalIndex)); scene.appendChild(boothGroup); globalIndex++; } speed }); window.addEventListener('keydown', function(event) { const runtime = document.getElementById('x3dElement').runtime; if (runtime) { const key = event.key.toLowerCase(); if (key === 'w') runtime.processInput("examine", "forward"); else if (key === 's') runtime.processInput("examine", "backward"); } }); }