Closed hjnieuwenhuizen closed 7 years ago
1) React VR is based on React Native which doesn't work with DOM elements 2) As the React code is running in a webworker there is no ability to create/destroy dom elements
You would need create
native view information can be found at https://github.com/facebook/react-vr/blob/master/docs/NativeModules.md
Sorry Mike I am really struggling with this. Are you able to give me a small code snippet on my example above. Pretty please. Also not 100% what modules i need to import etc.
I'll try and put something together over the weekend
Shot dude. I will buy you a beer one day :-)
I think my best bet is to iFrame my ReactVR app into my current App. Are you able to make the code snippet reflect how you would post messages between these two.
Hi Mike, did you find a chance to put together a simple code snippet? Or could you guide me to an example. Struggling to find much content out there on this matter.
You'll have to work out the specifics for your requirements but attached should help give you a starter. With this you should have a means to create and drive with a dom element
client.js
/**
* The examples provided by Oculus are for non-commercial testing and
* evaluation purposes only.
*
* Oculus reserves all rights not expressly granted.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
* OCULUS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
import {VRInstance} from 'react-vr-web';
import {Module} from 'react-vr-web';
import * as THREE from 'three';
import * as ReactVR from 'react-vr-web';
import * as OVRUI from 'ovrui';
import merge from '../../../ReactVR/ReactVR/js/Utils/merge';
class RCTTestDom extends ReactVR.RCTBaseView {
constructor(guiSys: GuiSys) {
super();
this.view = new OVRUI.UIView(guiSys);
this.newContent = document.createTextNode("Hi there and greetings!");
document.body.appendChild(this.newContent)
}
discard() {
super.discard();
document.body.removeChild(this.newContent);
this.newContent = null;
}
static describe() {
return merge(super.describe(), {
// declare the native props sent from react to runtime
NativeProps: {
},
});
}
}
function init(bundle, parent, options) {
// Create a scene so we can add to it; otherwise the VRInstance creates one.
const scene = new THREE.Scene();
// Create Native Module so React context can modify native (Three.js) cube.
const cubeModule = new CubeModule();
const vr = new VRInstance(bundle, 'CubeSample', parent, {
cursorVisibility: 'visible',
nativeModules: [cubeModule],
customViews: [{name: 'TestDom', view: RCTTestDom}],
scene: scene,
});
// Custom scene setup goes here. Add a cube to the scene.
// Must be done after providing the scene to VRInstance above.
const cube = new THREE.Mesh(new THREE.BoxGeometry(1, 1, 1), new THREE.MeshBasicMaterial());
cube.position.z = -4;
scene.add(cube);
// Give cubeModule a handle to our cube.
cubeModule.init(cube);
vr.render = function(timestamp) {
// Custom per-frame updates go here. Bounce the cube up and down.
const seconds = timestamp / 1000;
cube.position.x = 0 + 1 * Math.cos(seconds);
cube.position.y = 0.2 + 1 * Math.abs(Math.sin(seconds));
};
// Begin the animation loop
vr.start();
return vr;
}
export default class CubeModule extends Module {
// CubeModule is a React Native Module, which implements functionality
// that can be called asynchronously across the React Native brige.
// Constructor calls super() with one argument: module name.
constructor() {
super('CubeModule');
}
// Called directly after the module is created.
init(cube) {
this.cube = cube;
}
// Change the cube material color to the given value.
// Called remotely by the CubeModule on the React side.
changeCubeColor(color) {
// THREE.Color() accepts either a six-digit hex color or a CSS style.
// e.g. 0xff0000, 'rgb(255,0,0)', 'red'
this.cube.material.color = new THREE.Color(color);
}
}
window.ReactVR = {init};
index.vr.js
/**
* The examples provided by Oculus are for non-commercial testing and
* evaluation purposes only.
*
* Oculus reserves all rights not expressly granted.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
* OCULUS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
'use strict';
/**
*
* CubeSample displays a ReactVR button and text, along with a Three.js cube.
* The cube will change color when the button is selected. The React context
* and Three.js scene are in separate threads, so they communicate over the
* React Native bridge via the CubeModule, a custom Native Module. This
* shows how ReactVR UI elements can be added to an existing Three.js scene.
*/
import React from 'react';
import {AppRegistry, asset, Pano, Text, View, VrButton, NativeModules} from 'react-vr';
const NativeMethodsMixin = require('NativeMethodsMixin');
const StyleSheetPropType = require('StyleSheetPropType');
const LayoutAndTransformPropTypes = require('LayoutAndTransformPropTypes');
const ReactNativeViewAttributes = require('ReactNativeViewAttributes');
const requireNativeComponent = require('requireNativeComponent');
// Native Module defined in vr/client.js
const CubeModule = NativeModules.CubeModule;
const TestDom = React.createClass({
mixins: [NativeMethodsMixin],
propTypes: {
...View.propTypes,
style: StyleSheetPropType(LayoutAndTransformPropTypes),
},
viewConfig: {
uiViewClassName: 'TestDom',
validAttributes: {
...ReactNativeViewAttributes.RCTView,
},
},
getDefaultProps: function() {
return {};
},
render: function() {
return (
<RKTestDom/>
);
},
});
const RKTestDom = requireNativeComponent('TestDom', TestDom, {
nativeOnly: {},
});
/**
* CubeSample implements a custom button that calls a native module method,
* changing the color of a cube that is managed on the native (Three.js) side.
*/
class CubeSample extends React.Component {
constructor(props) {
super(props);
this.state = {
borderColor: 'rgba(0, 0, 0, 0)', // transparent
btnColor: 'grey',
cubeColor: 'yellow',
};
CubeModule.changeCubeColor(this.state.cubeColor);
}
render() {
return (
<View
style={{
transform: [{translate: [0, 0, -3]}],
layoutOrigin: [0.5, 0, 0],
alignItems: 'center',
}}
>
<Pano source={asset('chess-world.jpg')} />
<TestDom />
</View>
);
}
}
AppRegistry.registerComponent('CubeSample', () => CubeSample);
So, I was trying to get the CubeModule example working and I keep getting the following error. What am I doing wrong?
Uncaught TypeError: a.onBeforeRender is not a function
import {VRInstance} from 'react-vr-web'; import {Module} from 'react-vr-web'; import as THREE from 'three'; import as ReactVR from 'react-vr-web'; import * as OVRUI from 'ovrui';
function init(bundle, parent, options) {
const scene = new THREE.Scene(); const cubeModule = new CubeModule();
const vr = new VRInstance(bundle, 'RaignVR', parent, { cursorVisibility: 'visible', nativeModules: [ cubeModule ], scene: scene, });
const cube = new THREE.Mesh( new THREE.BoxGeometry(1, 1, 1), new THREE.MeshBasicMaterial() );
cube.position.z = -4; scene.add(cube); cubeModule.init(cube);
vr.render = function(timestamp) { const seconds = timestamp / 1000; cube.position.x = 0 + (1 (Math.cos(seconds))); cube.position.y = 0.2 + (1 Math.abs(Math.sin(seconds))); };
// Begin the animation loop vr.start(); return vr; }
export default class CubeModule extends Module { // CubeModule is a React Native Module, which implements functionality // that can be called asynchronously across the React Native brige.
// Constructor calls super() with one argument: module name. constructor() { super('CubeModule'); }
// Called directly after the module is created. init(cube) { this.cube = cube; }
// Change the cube material color to the given value. // Called remotely by the CubeModule on the React side. changeCubeColor(color) { // THREE.Color() accepts either a six-digit hex color or a CSS style. // e.g. 0xff0000, 'rgb(255,0,0)', 'red' this.cube.material.color = new THREE.Color(color); } }
window.ReactVR = {init}; `
Hi, this may be a silly question and I apologize in advance if that is the case, but I am struggling to get a React component to render within one of my ReactVR components. Do you have a basic example of how i can do this?
React Component:
ReactVR Component