<!DOCTYPE html>
< html >
< title > SpaSca : Spatial Scaffolding< / title >
< head >
<!-- Suggestions? https://git.benetou.fr/utopiah/text - code - xr - engine/issues/ -->
< script src = 'dependencies/aframe.offline.min.js' > < / script >
< script src = "dependencies/a-console.js" > < / script >
< script src = 'dependencies/aframe-troika-text.min.js' > < / script >
< script src = 'dependencies/webdav.js' > < / script >
< script src = 'jxr-core.js?1234' > < / script >
< script src = 'jxr-postitnote.js?13235' > < / script >
< / head >
< body >
< script >
scaffoldingInnerHTMLTemplate = `
< a-box teleporter height = ".01" depth = ".4" width = "1" class = "teleportable" material = "color: white" position = ".5 0 -.2" > < / a-box >
< a-entity position = "0 0.5 0" class = "scaffolding_front" >
< a-cylinder radius = ".05" > < / a-cylinder >
< a-cylinder radius = ".05" position = ".5 -.5 0" rotation = "0 0 90" > < / a-cylinder >
< a-cylinder radius = ".05" height = 1.2 position = ".5 0 0" rotation = "0 0 45" > < / a-cylinder >
< a-cylinder radius = ".05" height = ".4" position = "0 -.5 -.2" rotation = "90 0 0" > < / a-cylinder >
< / a-entity >
< a-entity position = "0 0.5 -.4" class = "scaffolding_back" >
< a-cylinder radius = ".05" position = "0 0 0" > < / a-cylinder >
< a-cylinder radius = ".05" position = ".5 -.5 0" rotation = "0 0 90" > < / a-cylinder >
< a-cylinder radius = ".05" height = 1.2 position = ".5 0 0" rotation = "0 0 -45" > < / a-cylinder >
< a-cylinder radius = ".05" height = ".4" position = "1 -.5 .2" rotation = "90 0 0" > < / a-cylinder >
< / a-entity > `
setTimeout( _ => {
let rot = "0 0 0"
let positions = [ "-1 1 -3.5", "-1 2 -3.5", "0 0 -3.5", "0 1 -3.5", "1 0 -3.5", "-1 0 -3.5" ]
// triangle example, could be based on room boundaries instead
positions.map( pos => { addFromTemplate(pos, rot, scaffoldingInnerHTMLTemplate) })
}, 9000)
function addFromTemplate(pos="0 0 0", rot="0 0 0", template="< a-box > < / a-box > "){
let el = document.createElement("a-entity")
el.innerHTML = template
AFRAME.scenes[0].appendChild(el)
el.setAttribute("position", pos)
el.setAttribute("rotation", rot)
}
AFRAME.registerComponent('onemptypinch', { // changed from ondrop to be coherent with event name
init: function(){
AFRAME.scenes[0].addEventListener('enter-vr', e => {
console.log('entered vr')
document.querySelector("[cursor]").setAttribute("visible", "true")
document.querySelector("[camera]").setAttribute("cursor", "")
})
},
// could support multi
events: {
emptypinch: function (e) {
// works with AFRAME.scenes[0].emit('emptypinch', {position:"0 0 0"})
let code = this.el.getAttribute('onemptypinch')
// if multi, should also look for onreleased__ not just onreleased
try {
eval( code ) // should be jxr too e.g if (txt.match(prefix)) interpretJXR(txt)
} catch (error) {
console.error(`Evaluation failed with ${error}`);
}
}
}
})
AFRAME.registerComponent('scaffolding', {
init: function(){
console.log(this.el.innerHTML)
// should become editable then saved back/replaced (or cloned)
// could do a test with switching to wireframe or grey color
// BT keyboard does get focus on Vision Pro too
// enter key does not seem to work though
// it does work on desktop tso should console.log() what keypresses are actually received
// Meta+Enter does work though! (on Corne-ish Zen it's Linux key with Enter)
// still prepare jxr regexes
// e.g el = document.querySelector("[scaffolding]")l el.innerHTML = el.innerHTML.replaceAll("< a-cylinder " , " < a-cylinder wireframe = true")
// block based too
// responsive pedagogical way, as discuss with Adam particularly, metaphor of the electrician and consecutive pannels with limited access
// put this.el.innerHTML on a plane, e.g 1x1 black plane at back of current scaffolding
// arrow keys (on physical keyboard) move through that, initially changing color or current char
// use a font that faciliates positionning
// as done before, make the carret, e.g | directly in the content text itself
// on save (ESC? to define and test), remove carret then save back to this.el.innerHTML
}
});
< / script >
< div style = 'position:fixed;z-index:1; top: 0%; left: 0%; border-bottom: 70px solid transparent; border-left: 70px solid #eee; ' >
< a href = "https://git.benetou.fr/utopiah/text-code-xr-engine/issues/" >
< img style = 'position:fixed;left:10px;' title = 'code repository' src = 'gitea_logo.svg' >
< / a >
< / div >
< a-scene startfunctions onemptypinch = "onHoveredTeleport()" >
< a-assets >
< video id = "dolomites1_preview" src = "/pub/home/360s/Dolomites2024Videos/R0012604_preview.MP4" > < / video >
< video id = "dolomites1" autoplay src = "/pub/home/360s/Dolomites2024Videos/R0012604.MP4" > < / video >
< video id = "dolomites2" autoplay src = "/pub/home/360s/Dolomites2024Videos/R0012610.MP4" > < / video >
< / a-assets >
< a-videosphere src = "#dolomites2" > < / a-videosphere >
< a-entity id = "rig" >
< a-entity id = "player" networked = "template:#avatar-template;attachTemplateToLocal:false;"
hud camera look-controls wasd-controls position="0 1.6 0">
< a-entity cursor position = "0 0 -1"
geometry="primitive: ring; radiusInner: 0.005; radiusOuter: 0.01"
material="color: black; shader: flat; opacity:.05;"
>< / a-entity >
< / a-entity >
< a-entity id = "rightHand" pinchprimary hand-tracking-controls = "hand: right;" > < / a-entity >
< a-entity id = "leftHand" pinchsecondary wristattachsecondary = "target: #box" hand-tracking-controls = "hand: left;" > < / a-entity >
< a-console position = "2 2 0" rotation = "0 -45 0" font-size = "34" height = 1 skip-intro = true > < / a-console >
< / a-entity >
< a-box pressable start-on-press id = "box" scale = "0.05 0.05 0.05" color = "pink" > < / a-box >
< a-troika-text value = "SpaSca : Spatial Scaffolding" anchor = "left" outline-width = "5%" font = "../content/ChakraPetch-Regular.ttf" position = "-3 5 -2"
scale="3 3 3" rotation="80 0 0" troika-text="outlineWidth: 0.01; strokeColor: #ffffff" material="flatShading: true; blending: additive; emissive: #c061cb">< / a-troika-text >
< a-troika-text anchor = left target value = "instructions : \n--right pinch to move\n--left pinch to execute" position = "0 0.65 -0.2" scale = "0.1 0.1 0.1" > < / a-troika-text >
< a-troika-text anchor = left value = "jxr location.reload()" target position = " -0.3 1.30 0" rotation = "0 40 0" scale = "0.1 0.1 0.1" > < / a-troika-text >
< a-troika-text anchor = left value = "jxr makeAnchorsVisibleOnTargets()" target position = " -0.3 1.20 0" rotation = "0 40 0" scale = "0.1 0.1 0.1" > < / a-troika-text >
< a-plane color = "black" opacity = ".3" position = "1.0095 0.81549 0.3473" rotation = "0 -40 0" material = "" geometry = "" scale = "1.37 1.73 1" > < / a-plane >
< a-troika-text anchor = left value = "View-source for WebXR" target position = "0.5 1.55 0" rotation = "0 -40 0" scale = "0.3 0.3 0.3" > < / a-troika-text >
< a-troika-text anchor = left value = "Why immersive Web needs visible scaffolding" target position = "0.5 1.45 0" rotation = "0 -40 0" scale = "0.2 0.2 0.2" > < / a-troika-text >
< a-troika-text anchor = left line-height = "1" value = "Lorem ipsum dolor sit amet , consectetur adipiscing elit , sed do eiusmod tempor incididunt ut labore et dolore magna aliqua .
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. " target position="0.5 1.25 0" rotation="0 -40 0" scale="0.1 0.1 0.1">< / a-troika-text >
< a-troika-text anchor = left value = "jxr addFromTemplate( '0 1 -1', '', scaffoldingInnerHTMLTemplate)" target position = "0.5 1.05 0" rotation = "0 -40 0" scale = "0.1 0.1 0.1" >
< a-triangle scale = ".5 .5 .5" position = "-.5 0 0" rotation = "0 0 30" > < / a-triangle >
< / a-troika-text >
< a-troika-text anchor = left line-height = "1" value = "Lorem ipsum dolor sit amet , consectetur adipiscing elit , sed do eiusmod tempor incididunt ut labore et dolore magna aliqua .
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. " target position="0.5 .85 0" rotation="0 -40 0" scale="0.1 0.1 0.1">< / a-troika-text >
< a-troika-text anchor = left value = "jxr document.querySelector('video').play()" target position = "-0.3 1.20 -.5" rotation = "0 0 0" scale = "0.1 0.1 0.1" > < / a-troika-text >
<!-- only plays audio, might need permission via user action, i.e a button -->
< / a-scene >
< / body >
< / script >
< / html >