diff --git a/index.html b/index.html index c81b2f3..0989838 100644 --- a/index.html +++ b/index.html @@ -62,11 +62,16 @@ setTimeout( _ => // e.g background https://fabien.benetou.fr/pub/home/metaverse.png might have to allow options like scale to allow for modifying both size and ratio AFRAME.registerComponent('background-via-url', { // non interactive mode init: function () { + let generatorName = this.attrName var src = AFRAME.utils.getUrlParameter('background') if (src && src != "") { this.el.setAttribute( "visible", "true") this.el.setAttribute( "src", src ) - Array.from( document.querySelectorAll(".mural-instructions") ).map( i => i.setAttribute("visible", "true") ) + this.el.className += generatorName + Array.from( document.querySelectorAll(".mural-instructions") ).map( i => { + i.setAttribute("visible", "true") + i.className += generatorName + }) } } }) @@ -80,10 +85,12 @@ AFRAME.registerComponent('web-url', { var src = AFRAME.utils.getUrlParameter('url') // could also be a component parameter var el = this.el + let generatorName = this.attrName if (src && src != "") target = src fetch(target).then( res => res.text() ).then( r => { document.querySelector("#page").innerHTML = r; el.setAttribute("html", "html:#page;cursor:#cursor;" ) + el.className += generatorName //backdrop const geometry = new THREE.PlaneGeometry( el.object3D.children[0].geometry.parameters.width*1.1, el.object3D.children[0].geometry.parameters.height*1.1 ); @@ -345,7 +352,7 @@ function coloredBlocksFromScreens(colors, el){ }) } -function imagesFromURLs(urls, el){ +function imagesFromURLs(urls, el, classes=null){ urls.map( (u,i) => { var e = document.createElement("a-image") if (u.indexOf("http")>-1) @@ -359,6 +366,8 @@ function imagesFromURLs(urls, el){ // could instead rely on https://github.com/visjs/vis-timeline // as previously used in https://mobile.twitter.com/utopiah/status/1110576751577567233 e.setAttribute("width","2") + if (classes) e.className += classes + el.appendChild(e) targets.push(e) }) @@ -463,15 +472,18 @@ AFRAME.registerComponent('line-link-entities', { steps: {type: 'number', default: 1}, }, init: function () { + let generatorName = this.attrName setTimeout( _ => { // stupid... but works. var sourcePos = this.data.source.object3D.position var targetPos = this.data.target.object3D.position + if (!sourcePos || !targetPos) return // adding a gltf inside an element prevents the parent from having coordinates (fast enough?) var step = 0 var points = cut ([sourcePos, targetPos], 0, ++step) points = cut (points, 0, ++step) points = cut (points, points.length-2, step) var el = this.el + el.className += generatorName points.map( (p,i,arr) => { if (arr[i+1]) el.setAttribute("line__"+i, "start:" + AFRAME.utils.coordinates.stringify( arr[i] ) + ";end: " + AFRAME.utils.coordinates.stringify( arr[i+1] ) ) @@ -529,12 +541,13 @@ AFRAME.registerComponent('screenstack', { //if (cabin && cabin.length > 0) return // test doesn't seem to work well on new page / 1st load // see CEREMA project, seems to handle caching better var el = this.el + let generatorName = this.attrName fetch(wikiAsImages).then(response => response.json()).then(data => imagesFromURLs( tryCachedImageOtherwiseRenderLive( Object.entries(data.Nodes).map(( [k, v] ) => { return {group:v.Group, name:v.Label} } ).slice(0,maxItems) ) - , el ) + , el, generatorName ) ) // example time sorting /* fetch('/screens').then(response => response.json()).then(data => console.log( @@ -968,7 +981,7 @@ AFRAME.registerComponent('hud', { } }) -function addNewNote( text, position=`-0.2 1.1 -0.1`, scale= "0.1 0.1 0.1", id=null ){ +function addNewNote( text, position=`-0.2 1.1 -0.1`, scale= "0.1 0.1 0.1", id=null, classes=null ){ //var newnote = document.createElement("a-text") var newnote = document.createElement("a-troika-text") newnote.setAttribute("anchor", "left" ) @@ -976,6 +989,7 @@ function addNewNote( text, position=`-0.2 1.1 -0.1`, scale= "0.1 0.1 0.1", id=nu newnote.setAttribute("outline-color", "black" ) if (id) newnote.id = id + if (classes) newnote.className += classes newnote.setAttribute("side", "double" ) var userFontColor = AFRAME.utils.getUrlParameter('fontcolor') if (userFontColor && userFontColor != "") @@ -1169,17 +1183,21 @@ let alphabet = 'abcdefghijklmnopqrstuvwxyz'; AFRAME.registerComponent('keyboard', { init:function(){ + let generatorName = this.attrName const horizontaloffset = .5 const horizontalratio = 1/30 for (var i = 0; i < alphabet.length; i++) { - var e = document.createElement("a-text") + var pos = i * horizontalratio - horizontaloffset + addNewNote( alphabet[i], pos+" 1.6 -.4", ".1 .1 .1", null, generatorName) + /* + var e = document.createElement("a-text") // could also rely on addNewNote() e.setAttribute("side", "double" ) e.setAttribute("value", alphabet[i]) e.setAttribute("target", true) e.setAttribute("scale", ".1 .1 .1") - var pos = i * horizontalratio - horizontaloffset e.setAttribute("position",`${pos} 1.6 -0.4`) this.el.appendChild(e) + */ } } }) @@ -1199,37 +1217,67 @@ AFRAME.registerComponent('capturegesture', { const maxItemsFromSources = 20 AFRAME.registerComponent('timeline', { init:function(){ + let generatorName = this.attrName fetch("../content/fot_timeline.json").then(res => res.json() ).then(res => { - res.fot_timeline.slice(0,maxItemsFromSources).map( (c,i) => addNewNote( c.year+"_"+c.event, "1 "+i/10+" -1", ".1 .1 .1") ) + res.fot_timeline.slice(0,maxItemsFromSources).map( (c,i) => addNewNote( c.year+"_"+c.event, "1 "+i/10+" -1", ".1 .1 .1", null, generatorName) ) }) }, }); AFRAME.registerComponent('glossary', { init:function(){ + let generatorName = this.attrName fetch("content/glossary.json").then(res => res.json() ).then(res => { - Object.values(res.entries).slice(0,maxItemsFromSources).map( (c,i) => addNewNote( c.phrase + c.entry.slice(0,50)+"..." , "-1 "+i/10+" -1", ".1 .1 .1") ) + Object.values(res.entries).slice(0,maxItemsFromSources).map( (c,i) => addNewNote( c.phrase + c.entry.slice(0,50)+"..." , "-1 "+i/10+" -1", ".1 .1 .1", null, generatorName) ) }) }, }); AFRAME.registerComponent('issues', { init:function(){ + let generatorName = this.attrName // fetch("https://api.github.com/repos/Utopiah/relax-plus-think-space/issues").then(res => res.json() ).then(res => { fetch("https://git.benetou.fr/api/v1/repos/utopiah/text-code-xr-engine/issues").then(res => res.json() ).then(res => { - res.slice(0,maxItemsFromSources).map( (n,i) => addNewNote( n.title, "0 "+(1+i/10)+" -1", ".1 .1 .1" ) ) + res.slice(0,maxItemsFromSources).map( (n,i) => addNewNote( n.title, "0 "+(1+i/10)+" -1.5", ".1 .1 .1", null, generatorName ) ) }) }, }); AFRAME.registerComponent('dynamic-view', { init:function(){ + let generatorName = this.attrName fetch("content/DynamicView.json").then(res => res.json() ).then(res => { - res.nodes.slice(0,maxItemsFromSources).map( n => addNewNote( n.title, "" + res.layout.nodePositions[n.identifier].x/100 + " " + res.layout.nodePositions[n.identifier].y/100 + " -1", ".1 .1 .1" ) ) + res.nodes.slice(0,maxItemsFromSources).map( n => addNewNote( n.title, "" + res.layout.nodePositions[n.identifier].x/100 + " " + res.layout.nodePositions[n.identifier].y/100 + " -1", ".1 .1 .1", null, generatorName ) ) }) }, }); +function toggleVisibilityEntitiesFromClass(classname){ + let entities = Array.from( document.querySelectorAll("."+classname) ) + if (entities.length == 0) return + let state = entities[0].getAttribute("visible") // assume they are all the same + if (state) + entities.map( e => e.setAttribute("visible", "false")) + else + entities.map( e => e.setAttribute("visible", "true")) +} + +function toggleVisibilityAllGenerators(){ + generators.split(" ").map( g => toggleVisibilityEntitiesFromClass(g) ) + // note hidableassets though +} + +function toggleVisibilityAll(){ + toggleVisibilityAllGenerators() + toggleVisibilityEntitiesFromClass("hidableassets") +} + +function toggleVisibilityAllButClass(classname){ + generators.split(" ").filter( e => e != classname).map( g => toggleVisibilityEntitiesFromClass(g) ) + toggleVisibilityEntitiesFromClass("hidableassets") +} + + AFRAME.registerComponent('commands-from-external-json', { /* // following discussion with Yanick @@ -1253,6 +1301,7 @@ fetch('./templates.json') */ init:function(){ var el = this.el + let generatorName = this.attrName var links = [ // could be in the commands file instead "target:#instructionA; source:#instructionB", "target:#instructionA; source:#instructionC", @@ -1262,7 +1311,7 @@ fetch('./templates.json') fetch("https://fabien.benetou.fr/PIMVRdata/CabinCommands?action=source").then(res => res.json() ).then(res => { // to consider for remoteload/remotesave instead, to distinguish from url though. // also potential security concern so might insure that only a specific user, with mandatory password access, added commands. - res.map( c => addNewNote( c.value, c.position, c.scale, c.id) ) // missing name/title, autorun (true/false), description, 3D icon/visual + res.map( c => addNewNote( c.value, c.position, c.scale, c.id, generatorName) ) // missing name/title, autorun (true/false), description, 3D icon/visual links.map( l => { var linkEl = document.createElement("a-entity"); linkEl.setAttribute("line-link-entities", l) el.appendChild(linkEl) @@ -1325,15 +1374,19 @@ function remotesave(){ }).then(res => res).then(res => console.log("saved remotely", res)) } +var generators = "line-link-entities link screenstack dynamic-view selectionboxonpinches keyboard " + + "commands-from-external-json glossary timeline issues web-url background-via-url observableui hidableenvironment" +// could be an array proper completed on each component registration + // could change model opacity based on hand position, fading out when within a (very small here) safe space
- + @@ -1364,7 +1417,7 @@ function remotesave(){ - + @@ -1379,8 +1432,7 @@ function remotesave(){ rotation="0 45 0" position="-1.5 1.7 -.7" scale=".4 .2 .2" > - - +