SpaSca : open SCAffolding to SPAcially and textualy explore interfaces https://fabien.benetou.fr/pub/home/future_of_text_demo/engine/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
text-code-xr-engine/index.html

162 lines
6.7 KiB

<!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="https://cdn.jsdelivr.net/gh/c-frame/aframe-extras@7.1.0/dist/aframe-extras.min.js"></script>
<script src='jxr-core.js?12345'></script>
<script src='jxr-postitnote.js?13235'></script>
</head>
<body>
<script>
AFRAME.registerComponent('startfunctions', {
init: function(){
let newEl = document.createElement('a-entity')
newEl.setAttribute('instruction-coffee-machine', '')
AFRAME.scenes[0].appendChild(newEl)
}
})
//___________________________________________________________________________________________________________________________________
AFRAME.registerComponent('instruction-coffee-machine', {
// once done, equivalent for
// tournevie metal workshop
// laser cutter at the EP
// todo
// describe the target task, e.g "Make extra long coffee (on PicoBarista)"
// 3D model of target object to align efficiently
// list the steps then iterate over them :
// highlight, e.g via arrow pointer, the next element to interact with
// confirm that the instruction was properly conducted
// optionally allow to
// rollback 1 step
// restart from scratch
// adjust bounding box
// port a much simplified version, i.e no 6DoF or hand tracking, to Monocle/Frame
// probably text only then, so only the load from wiki sequential instructions part
init: function(){
let generatorName = this.attrName
const idSuffix = "_framing_box"
let el = this.el
this.scale = 1/10
this.steps = ["pick the grey box and align it with your coffee machine", "press button A", "press button B"]
const confirmationStep = "Done" // could also consider a "done" area, moving the text there
let newEl = document.createElement('a-box')
newEl.setAttribute("scale", ""+this.scale+" "+this.scale+" "+this.scale)
newEl.setAttribute("wireframe", "true")
newEl.setAttribute("position", "0 1.3 -.5")
newEl.setAttribute("target","true")
// newEl.setAttribute("onpicked", "document.querySelector('["+generatorName+"]').emit('check')")
// newEl.setAttribute("onreleased", "document.querySelector('["+generatorName+"]').emit('reset')")
// should now also handle event details properly e.g
// newEl.setAttribute("onreleased", 'document.querySelector("['+generatorName+']").emit("check",{color:"'+color+'"})')
// then in event
// let box = this.el.querySelector("a-box[color="+evt.detail.color+"]")
newEl.classList.add( generatorName )
newEl.id = generatorName+idSuffix
el.appendChild(newEl)
let n = addNewNote("jxr qs #"+newEl.id+" sa rotation 0", "0.5 0.9 -.5")
n.setAttribute("rotation", "90 0 0")
n.setAttribute("annotation", "content: snap")
let actions = [
"translateX(.1)", "translateX(-.1)", "translateY(.1)", "translateY(-.1)", "translateZ(.1)", "translateZ(-.1)",
"rotateX(-.1)", "rotateX(.1)", "rotateY(.1)", "rotateY(-.1)", "rotateZ(.1)", "rotateZ(-.1)",
]
actions.reverse().map( (a,i) => {
let n = addNewNote("jxr qs #"+newEl.id+" .object3D."+a, ".5 "+(1+i/20)+" -.5")
n.setAttribute("rotation", "90 0 0")
n.setAttribute("annotation", "content: "+a)
})
el.appendChild(newEl)
n = addNewNote("jxr qs #"+newEl.id+" .emit('nextStep')" , "0 1.1 -.5")
n.setAttribute("rotation", "90 0 0")
n.setAttribute("annotation", "content: confirm/reset")
this.currentInstructionStep = 0
this.currentInstruction = addNewNote(this.steps[this.currentInstructionStep], "-.3 1.2 -.5")
},
events: {
reset: function (evt) {
console.log(this.attrName, 'component was resetted!');
let generatorName = this.attrName
},
nextStep: function (evt) {
this.currentInstruction.setAttribute("value",this.steps[++this.currentInstructionStep])
},
},
})
function cloneTarget(target){
let el = target.cloneNode(true)
if (!el.id)
el.id = "clone_" + crypto.randomUUID()
else
el.id += "_clone_" + crypto.randomUUID()
AFRAME.scenes[0].appendChild(el)
}
function deleteTarget(target){
targets = targets.filter( e => e != target)
target.remove()
}
function runClosestJXR(){
// ideally this would come from event details
let latest = selectedElements[selectedElements.length-1].element
let nearby = getClosestTargetElements( latest.getAttribute('position') )
// if (nearby.length>0){ interpretJXR( nearby[0].el.getAttribute("value") ) }
nearby.map( n => interpretJXR( n.el.getAttribute("value") ) )
}
</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 >
<a-assets>
<template id="left-hand-default-template">
<a-entity networked-hand-controls="hand:left"></a-entity>
</template>
<template id="right-hand-default-template">
<a-entity networked-hand-controls="hand:right"></a-entity>
</template>
</a-assets>
<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>
<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-entity>
<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-sky hide-on-enter-ar color="lightgray"></a-sky>
<a-troika-text anchor=left target value="instructions : \n--right pinch to move\n--left pinch to execute" position="0 1.65 -0.2" scale="0.1 0.1 0.1"></a-troika-text>
<a-troika-text anchor=left value="jxr location.reload()" target position="-.5 1.30 0" rotation="0 40 0" scale="0.1 0.1 0.1"></a-troika-text>
<a-console position="2 2 0" rotation="0 -45 0" font-size="34" height=1 skip-intro=true></a-console>
<a-box id="box" visible="false"></a-box>
<!-- bug if #box missing, so hiding for now -->
<!-- bug in start-on-press after XR init, as mentioned there -->
</a-scene>
</body>
</script>
</html>