diff --git a/index.html b/index.html
index e835c53..c1ffc3b 100644
--- a/index.html
+++ b/index.html
@@ -23,23 +23,31 @@ AFRAME.registerComponent('startfunctions', {
}
})
+// import from https://fabien.benetou.fr/PIMVRdata/SpaSca3DPrinterInstructions?action=source
+ // but as text editable format, not code
+ // would be safer to do few examples BEFORE synthesizing to a flexible enough format, just with mini games before
//___________________________________________________________________________________________________________________________________
AFRAME.registerComponent('instruction-machine', {
// other content next, ideally combinable
// tournevie metal workshop
// laser cutter at the EP
// todo
+ // split UI versus content
// visual timeline and where we are on it, e.g 1/4 steps
// a la Lego instruction, i.e horizontal bar with dot on current position
// could use a cylinder and a moving sphere
-// could be helpful to persist once position is ok, after step 1 then
- // https://aframe.io/docs/1.5.0/components/anchored.html
- // timeout for increasingly explicit feedback
- // jump to specific step via hash to better discussion
-// port a text version, i.e no 6DoF or hand tracking, to Monocle/Frame
- // adapt from wiki sequential instructions part, possibly with some images
-// consider https://threejs.org/docs/?q=grid#api/en/helpers/GridHelper too
+ // could be helpful to persist once position is ok, after step 1 then
+ // https://aframe.io/docs/1.5.0/components/anchored.html
+ // timeout for increasingly explicit feedback
+ // jump to specific step via hash to better discussion
+ // port a text version, i.e no 6DoF or hand tracking, to Monocle/Frame
+ // adapt from wiki sequential instructions part, possibly with some images
+ // consider https://threejs.org/docs/?q=grid#api/en/helpers/GridHelper too
+
+ schema: {default:
+ "https://fabien.benetou.fr/PIMVRdata/SpaSca3DPrinterInstructions?action=source"
+ }, // type: "string"
init: function(){
// shortcut to navigate through steps, 2D only
@@ -52,13 +60,14 @@ AFRAME.registerComponent('instruction-machine', {
let generatorName = this.attrName
const idSuffix = "_framing_box"
+ this.buttonSuffix = "_step_button"
let el = this.el
+
+ //---------------------------CONTENT--------------------------
this.scale = 1/10
- this.steps = ["pick the grey box and align it with your 3D printer", "press change filament button", "remove the filament spool"]
- // symplistic, could instead be a directed graph of named nodes, each with optionally multiple outgoing edges
- this.buttonSuffix = "_step_button"
- this.endOfInstructions = "You have finished the instructions. Feel free to reset and try again."
- const confirmationStep = "Done" // could also consider a "done" area, moving the text there
+ // size of the initial bounding box
+
+ // main element
let newEl = document.createElement('a-box')
newEl.setAttribute("scale", ""+this.scale+" "+this.scale+" "+this.scale)
newEl.setAttribute("wireframe", "true")
@@ -74,17 +83,7 @@ AFRAME.registerComponent('instruction-machine', {
newEl.id = generatorName+idSuffix
el.appendChild(newEl)
- let timelinegEl = document.createElement('a-cylinder')
- timelinegEl.setAttribute("height", "1")
- timelinegEl.setAttribute("radius", ".1")
- timelinegEl.setAttribute("color", "white")
- timelinegEl.setAttribute("rotation", "90 0 0")
- timelinegEl.setAttribute("position", "0.1 0.1 0.5")
- timelinegEl.setAttribute("visible","false")
- timelinegEl.classList.add( generatorName )
- timelinegEl.id = generatorName+"_timeline"
- //newEl.appendChild(timelinegEl)
-
+ // button for step 1 with hinting arrow
let buttonEl = document.createElement('a-box')
buttonEl.setAttribute("scale", ".2 .1 .1")
buttonEl.setAttribute("wireframe", "true")
@@ -98,6 +97,7 @@ AFRAME.registerComponent('instruction-machine', {
newEl.appendChild(buttonEl)
this.addArrow([-4.5, 0, 0], buttonEl)
+ // cylinder example for step 2 with hinting arrow
buttonEl = document.createElement('a-cylinder')
buttonEl.setAttribute("scale", ".5 .5 .5")
buttonEl.setAttribute("wireframe", "true")
@@ -111,10 +111,48 @@ AFRAME.registerComponent('instruction-machine', {
buttonEl.id = generatorName+this.buttonSuffix+"_2"
newEl.appendChild(buttonEl)
this.addArrow([-4.5, 0, 0], buttonEl)
+
+ //---------------------------END OF CONTENT--------------------------
+ // generic UI
+
+ this.steps = []
+ //this.steps = ["pick the grey box and align it with your 3D printer", "press change filament button", "remove the filament spool"]
+
+ fetch(this.data)
+ .then( r => r.text() )
+ .then( r => {
+ this.steps = r.split('\n')
+ this.steps.push( this.endOfInstructions )
+ document.querySelector("["+generatorName+"]").emit('reset')
+ })
+
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")
+ // symplistic, could instead be a directed graph of named nodes, each with optionally multiple outgoing edges
+ this.endOfInstructions = "You have finished the instructions. Feel free to reset and try again."
+ this.steps.push( this.endOfInstructions )
+ const confirmationStep = "Done" // could also consider a "done" area, moving the text there
+
+ let timelinegEl = document.createElement('a-cylinder')
+ timelinegEl.setAttribute("height", "1")
+ timelinegEl.setAttribute("radius", ".01")
+ timelinegEl.setAttribute("color", "white")
+ timelinegEl.setAttribute("rotation", "0 0 90")
+ timelinegEl.setAttribute("position", "0 1.15 -0.5")
+ timelinegEl.setAttribute("target","true")
+ timelinegEl.classList.add( generatorName )
+ timelinegEl.id = generatorName+"_timeline"
+ el.appendChild(timelinegEl)
+ let tlcursorgEl = document.createElement('a-sphere')
+ tlcursorgEl.setAttribute("radius", ".02")
+ tlcursorgEl.setAttribute("color", "red")
+ tlcursorgEl.setAttribute("position", "0 .5 0")
+ tlcursorgEl.classList.add( generatorName )
+ tlcursorgEl.id = generatorName+"_timelinecursor"
+ timelinegEl.appendChild(tlcursorgEl)
+
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)",
@@ -122,7 +160,7 @@ AFRAME.registerComponent('instruction-machine', {
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.replace(/xxx/,''))
+ n.setAttribute("annotation", "content: "+a.replace(/xxx/,'')) // could be simplified a bit
})
el.appendChild(newEl)
@@ -148,6 +186,7 @@ AFRAME.registerComponent('instruction-machine', {
let generatorName = this.attrName
this.currentInstructionStep=-1
document.querySelector("["+generatorName+"]").emit('nextStep')
+ document.getElementById( generatorName+"_timelinecursor" ).object3D.position.y = .5
},
nextStep: function (evt) {
let generatorName = this.attrName
@@ -155,16 +194,19 @@ AFRAME.registerComponent('instruction-machine', {
this.currentInstruction.setAttribute("value",this.steps[++this.currentInstructionStep])
Array.from( document.querySelectorAll( "."+generatorName+this.buttonSuffix) ).map( el => el.setAttribute("visible", "false" ) )
document.getElementById( generatorName+this.buttonSuffix +"_"+this.currentInstructionStep )?.setAttribute("visible", "true" )
- } else {
- this.currentInstruction.setAttribute("value", this.endOfInstructions)
+ document.getElementById( generatorName+"_timelinecursor" ).object3D.translateY( -1/(this.steps.length-1) )
}
},
previousStep: function (evt) {
+ // going back after the end does NOT work as expected!
let generatorName = this.attrName
if (this.currentInstructionStep>0){
this.currentInstruction.setAttribute("value",this.steps[--this.currentInstructionStep])
Array.from( document.querySelectorAll( "."+generatorName+this.buttonSuffix) ).map( el => el.setAttribute("visible", "false" ) )
document.getElementById( generatorName+this.buttonSuffix +"_"+this.currentInstructionStep )?.setAttribute("visible", "true" )
+ document.getElementById( generatorName+"_timelinecursor" ).object3D.translateY( 1/(this.steps.length-1) )
+ } else {
+ document.querySelector("["+generatorName+"]").emit('reset')
}
},
},