Open kylebakerio opened 3 years ago
So, for now I've at least built out this component to wrap web2vr and make it correspond to a more idiomatic usage:
// restructuring web2vr to work as an aframe component
AFRAME.registerComponent('add-web2vr', {
schema: {
pos: {
// relative to parent component (this.el), instead of world position
type: 'vec3',
default: {
x: 0, y: 0, z: 0
}
},
keyboardPos: {
// relative to parent component (this.el), instead of world position
type: 'vec3',
default: {
x: 0, y: 0, z: 0
}
},
"selfSelector": {
// probably ignore this
type: 'string',
default: '',
},
'htmlSelector': {
// the html element to clone into VR
// note: when you pass in e.g. '#html-container', because this schema specifies
// type: 'selector',
// a-frame will parse that and this.data.htmlSelector will actually be the dom node itself, not the text
type: 'selector',
default: '',
},
debug: {
// turn on web2vr's built-in verbose mode
type: 'bool',
default: false,
},
},
setSelector() {
// this is... not pretty, but this is a work around for web2vr's odd choice of only allowing specifying an anchor
// by selector, instead of more idiomatically by attaching a component. So, we define a unique selector, add it, and then
// pass that in to web2vr
this.data.selfSelector = this.data.selfSelector || `anchor${Math.round(Math.random()*1000000)}`;
this.el.setAttribute(
'class',
this.el.getAttribute('class') + " " + this.data.selfSelector
)
},
init() {
if (!this.data.htmlSelector) {
throw new Error("no html to inject specified");
}
this.setSelector();
const web2vr = new Web2VR(this.data.htmlSelector/*document.getElementById("html-container")*/, {
parentSelector: this.data.selfSelector,
position: this.data.pos, //{ x: 0, y: 1.5, z: 0 },
debug: this.data.bool,
skybox: false, // this is very non-idiomatic, so we remove access to this option
createControllers: false, // this is very non-idiomatic, so we remove access to this option
});
web2vr.start();
document.querySelector('.vr-container').addEventListener('click',evt => {
console.log('clicked container', evt)
document.querySelector('#vr-keyboard').setAttribute('position', this.data.keyboardPos)
});
}
})
example html that uses it:
<!-- The div we're adding into the scene; notice the id of the parent that we grab here -->
<div id="html-container" style="border-radius:10px;">
<h1>Input-Test</h1>
<div style="border-radius:10px;">
<input type="radio" id="bike" name="vehicle" value="bike">
<label for="bike">Bike</label>
<input type="radio" id="car" name="vehicle" value="car">
<label for="car">Car</label>
<input type="radio" id="boat" name="vehicle" value="boat">
<label for="boat">Boat</label>
</div>
<div>
<input type="checkbox" id="vehicle1" name="vehicle1" value="Bike" style="border-radius:10px;">
<label for="vehicle1"> I have a bike</label>
<input type="checkbox" id="vehicle2" name="vehicle2" value="Car">
<label for="vehicle2"> I have a car</label>
<input type="checkbox" id="vehicle3" name="vehicle3" value="Boat">
<label for="vehicle3"> I have a boat</label>
</div>
<input type="range" id="points" name="points" min="0" max="10">
<br/><br/>
<input id="name-input" type="text" placeholder="Name">
<br/><br/>
<input type="text" placeholder="Sex">
<br/>
<input type="text" placeholder="Location"><br/><br/>
<textarea placeholder="your complaints..." id="w3review" name="w3review" rows="4" cols="17" maxlength="200"></textarea>
</div>
<!-- the actual scene; notice the add-web2vr component on the #anchor box -->
<a-scene add-inputs vr-super-stats="alwaysshow3dstats:true; showgraphs:null;">
<a-super-sky orbitduration="100000" startpercent=".2" super-sky-debug="false"></a-super-sky>
<a-circle rotation="-90 0 0" radius="100"></a-circle>
<a-box material="color:red;"
add-web2vr="
pos: 0 1.5 -5;
htmlSelector: #html-container;
keyboardPos: -.27 .8 -5;"
id="anchor"
position="0 0 -5">
</a-box>
<a-entity position="0 1.6 0" movement-controls="camera:[camera]; fly:true; enabled:true;">
<a-entity look-controls camera>
<a-entity
id="cursor-mouse"
cursor="fuse: false; rayOrigin:mouse;"
raycaster="enabled: true; showLine: false; far: 4; interval:100; near: 0.03; objects: .vr-interactable, .raycastable; origin: 0.001 0 0;"
position="0 0 -0.1"
></a-entity>
</a-entity>
<!-- we have to add .vr-interactable to click the inputs, .collidable to interact with keyboard-->
<a-entity id="leftHand" laser-controls="hand:left" raycaster="showLine:true; far:10; objects:.vr-interactable, .collidable;"></a-entity>
<a-entity id="rightHand" laser-controls="hand:right" raycaster="showLine:true; far:10; objects:.vr-interactable, .collidable;"></a-entity>
</a-entity>
</a-scene>
(you can see and remix a demo using it here: https://glitch.com/edit/#!/web2vr-demo?path=index.html%3A27%3A0)
The basic example is a bit surprising, since there's not even an a-scene necessary to be present, and since the javascript called is raw JS, outside of an A-Frame component. Further, one has to turn off the default feature to create its own sky (which is again, pretty surprising), and specify position and parent element through params.
It would be nice to have an interface that is syntactic sugar that enables a flow more like this:
Or, another possible option:
I'm thinking I want to switch over to this library for my in-game menu system, and if I do, I'll probably write a wrapper to accomplish this. Would you be interested in a pull request for this type of feature?