InApps Technology
How to make React VR Apps
How to make react vr apps in 2022

How to make React VR Apps

Anh Hoang June 23, 2022 13 min read

VR web apps can be built with React VR apps. WebVR is an experimental API enabling the creation and viewing of VR experiences in your browser. This new technology enables you to grant access to virtual reality regardless of the devices at hand.

The only thing you need to make a React VR app is a headset and a compatible browser. If you are just viewing a web VR application then you don’t need even for a headset.

React VR is a great framework to build VR websites or apps on JavaScript. It utilizes the same design as React Native and lets you make virtual reality tours and under interfaces with the provided components.

vr-app

How to make a VR app

Key Summary

The article from InApps.net provides a guide on building virtual reality (VR) web applications using React VR, leveraging the WebVR API for browser-based VR experiences. Key points include:

  • Overview: React VR, built on JavaScript and similar to React Native, enables creation of VR tours and interfaces. Requires only a compatible browser and optionally a headset for full VR mode.
  • React VR, built on JavaScript and similar to React Native, enables creation of VR tours and interfaces.
  • Requires only a compatible browser and optionally a headset for full VR mode.
  • Technical Requirements: Install Node.js (latest version): MacOS: Use Homebrew. Windows: Download from nodejs.org. Linux: sudo apt-get install nodejs. Install React VR CLI: npm install -g react-vr-cli.
  • Install Node.js (latest version): MacOS: Use Homebrew. Windows: Download from nodejs.org. Linux: sudo apt-get install nodejs.
  • MacOS: Use Homebrew.
  • Windows: Download from nodejs.org.
  • Linux: sudo apt-get install nodejs.
  • Install React VR CLI: npm install -g react-vr-cli.
  • Getting Started: Create a project: react-vr init MyFirstReactVR. Navigate to project directory and run: npm start. View in browser, drag cursor to explore, or use a headset for full VR.
  • Create a project: react-vr init MyFirstReactVR.
  • Navigate to project directory and run: npm start.
  • View in browser, drag cursor to explore, or use a headset for full VR.
  • Developing a VR Tour: Architecture Setup: Define scenes with images and navigation buttons in index.js.vr constructor (e.g., scenes array with scene_image, step, navigations). State Management: Initialize current_scene in constructor state. Rendering: Use <Pano> for scene images and <Mesh> with <VrButton> for navigations; map navigation data for dynamic buttons. Scene Initialization: Set initial scene in componentWillMount.
  • Architecture Setup: Define scenes with images and navigation buttons in index.js.vr constructor (e.g., scenes array with scene_image, step, navigations).
  • State Management: Initialize current_scene in constructor state.
  • Rendering: Use <Pano> for scene images and <Mesh> with <VrButton> for navigations; map navigation data for dynamic buttons.
  • Scene Initialization: Set initial scene in componentWillMount.
  • Navigation and Animation: Navigation: Handle clicks on <Mesh> via onInput event to switch scenes by updating current_scene state. Animation: Add animated button with requestAnimationFrame to adjust size/radius; reset on scene change. Rotation Controls: Subscribe to onInput for <Pano> to rotate buttons using arrow keys. Messaging: Implement VR/Main thread communication via postMessage for scene changes and loading states.
  • Navigation: Handle clicks on <Mesh> via onInput event to switch scenes by updating current_scene state.
  • Animation: Add animated button with requestAnimationFrame to adjust size/radius; reset on scene change.
  • Rotation Controls: Subscribe to onInput for <Pano> to rotate buttons using arrow keys.
  • Messaging: Implement VR/Main thread communication via postMessage for scene changes and loading states.
  • Interactivity (client.js): Store VR and camera instances for control. Implement zoom with onmousewheel and position changes with ondblclick using Three.js for 3D coordinates. Define get3DPoint in cameraHelper.js to convert screen to world coordinates.
  • Store VR and camera instances for control.
  • Implement zoom with onmousewheel and position changes with ondblclick using Three.js for 3D coordinates.
  • Define get3DPoint in cameraHelper.js to convert screen to world coordinates.
  • Loading Indicator: Add CSS loader in index.html (spinning wheel) and toggle visibility in client.js based on sceneLoadStart/sceneLoadEnd messages.
  • Add CSS loader in index.html (spinning wheel) and toggle visibility in client.js based on sceneLoadStart/sceneLoadEnd messages.
  • Challenges of Hiring VR Developers: Specialized Skill Set: VR development requires knowledge of React VR, WebVR, and Three.js, which are niche skills. Finding Experienced Talent: Limited pool of developers with hands-on VR app experience. Cost Considerations: Hiring specialized VR developers or agencies can be expensive due to the complexity of the technology. Keeping Up with Evolving Tech: WebVR and related APIs are experimental and rapidly changing, requiring developers to stay updated.
  • Specialized Skill Set: VR development requires knowledge of React VR, WebVR, and Three.js, which are niche skills.
  • Finding Experienced Talent: Limited pool of developers with hands-on VR app experience.
  • Cost Considerations: Hiring specialized VR developers or agencies can be expensive due to the complexity of the technology.
  • Keeping Up with Evolving Tech: WebVR and related APIs are experimental and rapidly changing, requiring developers to stay updated.
  • Solutions for Hiring: Leverage Agencies: Partner with firms like InApps, a leading app development company in Vietnam, which offers expertise in VR and other technologies. Review Portfolios: Ensure candidates have VR project experience (e.g., via GitHub or demos). Test Skills: Use coding challenges focused on WebVR, React VR, or Three.js. Consider Outsourcing Models: Use dedicated teams or hybrid models for cost-effective, scalable solutions. Invest in Training: Upskill existing developers with React Native experience to learn VR frameworks.
  • Leverage Agencies: Partner with firms like InApps, a leading app development company in Vietnam, which offers expertise in VR and other technologies.
  • Review Portfolios: Ensure candidates have VR project experience (e.g., via GitHub or demos).
  • Test Skills: Use coding challenges focused on WebVR, React VR, or Three.js.
  • Consider Outsourcing Models: Use dedicated teams or hybrid models for cost-effective, scalable solutions.
  • Invest in Training: Upskill existing developers with React Native experience to learn VR frameworks.

Technical Requirements

Before getting started with React VR, You required a proper setup for the dependencies that will be used to build and manage a React VR app. These are Node.js and the React VR CLI.

Hourly Rate For Freelance Web Developer - Update

You need to install Node.js, ensure that the latest version is used. If not, do the following:

  • MacOS: Install Node.js using Homebrew
  • Windows: Install it from the nodejs.org
  • Linux: Use sudo apt-get install nodejs command

Then you have to install the React VR CLI using npm:

<code>npm install -g react-vr-cli.</code>

Getting Started

Navigate to the directory where you wish to create a new project and run the react-vr init MyFirstReactVR command.

Change the directory name to something like MyFirstReactVR and run npm start .

Click and try to drag your cursor around. Also, in browsers that support WebVR, you’ll be able to explore this VR environment with a headset in full virtual reality mode.

How to develop VR apps

Now let’s make a VR tour with a few scenes and navigations in them. First of all, you need to prepare the architecture. In this example, we will make buttons within each scene for navigations and declare this in the constructor of a React component named index.js.vr:

<code>constructor(props) { super(props); scenes: [{ scene_image: 'initial.jpg', step: 1, navigations: [{ step: 2, translate: [0.73, -0.15, 0.66], rotation: [0, 36, 0] }] }, { scene_image: 'step1.jpg', step: 2, navigations: [{ step: 3, translate: [-0.43, -0.01, 0.9], rotation: [0, 140, 0] }] }, { scene_image: 'step2.jpg', step: 3, navigations: [{ step: 4, translate: [-0.4, 0.05, -0.9], rotation: [0, 0, 0] }] }, { scene_image: 'step3.jpg', step: 4, navigations: [{ step: 5, translate: [-0.55, -0.03, -0.8], rotation: [0, 32, 0] }] }, { scene_image: 'step4.jpg', step: 5, navigations: [{ step: 1, translate: [0.2, -0.03, -1], rotation: [0, 20, 0] }] }] }</code>

Also, declare current_scene in the state in the constructor:

<code>constructor(props) { this.state = { ... current_scene: {} ... }</code>

For rendering, change the render() method, as seen below:

<code>render() { return ( < View > < Pano source = { asset(this.state.current_scene['scene_image']) } style = { { transform: [{ translate: [0, 0, 0] }] } } /> { this.state.current_scene['navigations'].map(function(item, i) { return <Mesh key = { i } style = { { layoutOrigin: [0.5, 0.5], transform: [{ translate: item['translate'] }, { rotateX: item['rotation'][0] }, { rotateY: item['rotation'][1] }, { rotateZ: item['rotation'][2] }] } } > < VrButton style = { { width: 0.15, height: 0.15, borderRadius: 50, backgroundColor: 'blue' } } > < /VrButton> < /Mesh> }) } < /View> ) }</code>

The last step to make this work is to set the current_scene state to the first element of the scenes array componentWillMount function:

<code>componentWillMount() { this.setState({ current_scene: this.state.scenes[0] }); }</code>

The result should be like this on screen:

Now add a simple animation for the button and implement the logic to navigate between scenes. First of all, for navigation, you need to subscribe to the onInput event for our Mesh element, bind this function to this in constructor, and implement it:

<code>... constructor(props) { ... this.onNavigationClick = this.onNavigationClick.bind(this); ... } ... onNavigationClick(item, e) { if (e.nativeEvent.inputEvent.eventType === "mousedown" && e.nativeEvent.inputEvent.button === 0) { var new_scene = this.state.scenes.find(i => i['step'] === item.step); this.setState({ current_scene: new_scene }); } } ... render() { var that = this; ... < Mesh key = { i } ... onInput = { e => that.onNavigationClick(item, e) } .... > ... }</code>

Then added a simple animation try it out. For this, you have added one more button inside the existing one in the render method and changed the size of it. Use native JS requestAnimationFrame function:

<code>const DEFAULT_ANIMATION_BUTTON_RADIUS = 50; const DEFAULT_ANIMATION_BUTTON_SIZE = 0.05; constructor(props) { ... this.state = { ... animationWidth: DEFAULT_ANIMATION_BUTTON_SIZE, animationRadius: DEFAULT_ANIMATION_BUTTON_RADIUS ... } ... this.animatePointer = this.animatePointer.bind(this); } ... componentWillUnmount() { if (this.frameHandle) { cancelAnimationFrame(this.frameHandle); this.frameHandle = null; } } componentDidMount() { this.animatePointer(); } animatePointer() { var delta = this.state.animationWidth + 0.002; var radius = this.state.animationRadius + 10; if (delta >= 0.13) { delta = DEFAULT_ANIMATION_BUTTON_SIZE; radius = DEFAULT_ANIMATION_BUTTON_RADIUS; } this.setState({ animationWidth: delta, animationRadius: radius }) this.frameHandle = requestAnimationFrame(this.animatePointer); } ... render() { ... < VrButton style = { { width: 0.15, height: 0.15, borderRadius: 50, justifyContent: 'center', alignItems: 'center', borderStyle: 'solid', borderColor: '#FFFFFF80', borderWidth: 0.01 } } > < VrButton style = { { width: that.state.animationWidth, height: that.state.animationWidth, borderRadius: that.state.animationRadius, backgroundColor: '#FFFFFFD9' } } > < /VrButton> < /VrButton> ... }</code>

Now let’s implement manipulations with the animated button and its rotation. It will rotate the button on an X-Y-Z axis. To do so, you need to subscribe to the onInput event for the Pano component and change the rotation via arrow-up, arrow-right, and arrow-down buttons.

Best JavaScript projects for beginners - Update 2022

The last thing is to implement messaging of the VR thread and Main thread to exchange data. Below is the subscription code on receiving messages and posting a message when a scene changes or an image starts/ends loading.

<code>componentWillMount() { window.addEventListener('message', this.onMainWindowMessage); ... } onMainWindowMessage(e) { switch (e.data.type) { case 'newCoordinates': var scene_navigation = this.state.current_scene.navigations[0]; this.state.current_scene.navigations[0]['translate'] = [e.data.coordinates.x, e.data.coordinates.y, e.data.coordinates.z] this.forceUpdate(); break; default: return; } } onNavigationClick(item, e) { ... postMessage({ type: "sceneChanged" }) this.state.animationWidth = DEFAULT_ANIMATION_BUTTON_SIZE; this.state.animationRadius = DEFAULT_ANIMATION_BUTTON_RADIUS; this.animatePointer(); ... } sceneOnLoad() { postMessage({ type: "sceneLoadStart" }) } sceneOnLoadEnd() { postMessage({ type: "sceneLoadEnd" }) } render() { ... < Pano... onLoad = { this.sceneOnLoad } onLoadEnd = { this.sceneOnLoadEnd } ... / > }</code>

In client.js, implement a zoom with the mouse wheel and a position change with a double-click. you need to store the VR instance and VRcamera instance to implement the logic above.

<code>function init(bundle, parent, options) { const vr = new VRInstance(bundle, 'TMExample', parent, { // Add custom options here ...options, }); vr.render = function() { // Any custom behavior you want to perform on each frame goes here }; // Begin the animation loop vr.start(); window.playerCamera = vr.player._camera; window.vr = vr; return vr;</code>

Then subscribe to ondblclick and onmousewheel and implement the zoom and change position logic.

<code>function onRendererDoubleClick() { var x = 2 * (event.x / window.innerWidth) - 1; var y = 1 - 2 * (event.y / window.innerHeight); var coordinates = get3DPoint(window.playerCamera, x, y); vr.rootView.context.worker.postMessage({ type: "newCoordinates", coordinates: coordinates }); } function onRendererMouseWheel() { if (event.deltaY > 0) { if (window.playerCamera.zoom > 1) { window.playerCamera.zoom -= 0.1; window.playerCamera.updateProjectionMatrix(); } } else { if (window.playerCamera.zoom < 3) { window.playerCamera.zoom += 0.1; window.playerCamera.updateProjectionMatrix(); } } }</code>

get3DPoint is your custom function to transform screen coordinates to world coordinates using Three.js, implemented in cameraHelper.js.

<code>import * as THREE from 'three'; export function get3DPoint(camera, x, y) { var mousePosition = new THREE.Vector3(x, y, 0.5); mousePosition.unproject(camera); var dir = mousePosition.sub(camera.position).normalize(); return dir; }</code>

Sometimes, loading scene images takes time. thus, you have implemented the loader to show this process. In index.html, add a loader and CSS based on this w3cschool example.

<code><style> body { margin: 0; } #loader { position: absolute; left: 50%; top: 50%; z-index: 1; width: 150px; height: 150px; margin: -75px 0 0 -75px; border: 16px solid #f3f3f3; border-radius: 50%; border-top: 16px solid #3498db; width: 120px; height: 120px; -webkit-animation: spin 2s linear infinite; animation: spin 2s linear infinite; } @-webkit-keyframes spin { 0% { -webkit-transform: rotate(0deg); } 100% { -webkit-transform: rotate(360deg); } } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } .animate-bottom { position: relative; -webkit-animation-name: animatebottom; -webkit-animation-duration: 1s; animation-name: animatebottom; animation-duration: 1s } @-webkit-keyframes animatebottom { from { bottom:-100px; opacity:0 } to { bottom:0px; opacity:1 } } @keyframes animatebottom { from{ bottom:-100px; opacity:0 } to{ bottom:0; opacity:1 } } #myDiv { display: none; text-align: center; } </style> <body> <div id='content' style="width:100%; height:100%"> <div id="loader"></div> </div> <script src="https://codersera.com/blog/how-to-make-react-vr-apps-2/./client.bundle?platform=vr"></script> <script> ReactVR.init('../index.vr.bundle?platform=vr&dev=true', document.getElementById('content')); </script> </body></code>

And don’t forget message in client.js from the VR thread to enable/disable animation:

<code>function init(bundle, parent, options) { ... vr.rootView.context.worker.addEventListener('message', onVRMessage); ... } function onVRMessage(e) { switch (e.data.type) { case 'sceneChanged': if (window.playerCamera.zoom != 1) { window.playerCamera.zoom = 1; window.playerCamera.updateProjectionMatrix(); } break; case 'sceneLoadStart': document.getElementById('loader').style.display = 'block'; break; case 'sceneLoadEnd': document.getElementById('loader').style.display = 'none'; break; default: return; } }</code>

Check your index.html or client.js.

InApps – Top App development company in Vietnam

When it comes to coding an app, you have three options: you can either hire an app development agency to build and design your product. You can create your own internal design and development team, or you can build the app yourself.

InApps is a leading application development company in Vietnam. We have extensive experience in developing different applications in all industries. Please view Our portfolio. As long as you have an idea, we will help you turn it into reality. Share your ideas with us now.

What is M-Commerce? Examples, Applications, Benefits

List of Keywords users find our article on Google

[sociallocker id=”2721″]

react vr

create vr app

react native vr

how to develop vr apps

react setstate

dna vr

nodejs org

reactvr

w3cschool

react vr game

react native share whatsapp

this setstate

react constructor

react vr tutorial

build a virtual reality application with react learning

vr bundle

border radius react native

componentwillmount

react native transform

setstate react

0.15 * 50

make vr app

react js vr

react native zoom

npm threejs

react-native-vision-camera

headset cartoon

react native vision camera

react virtual reality

react native virtual reality

constructor custom cursor

react-vr

.map is not a function react

react native position absolute

vr react native

this.setstate

infinite outsourcing solutions

react native camera

webkit postmessage

react native templates

var headset

react native border

react recruitment

javascript display none

three js react native

react native template design

drag react native

front end loader hire

index vr

loader react

saas loader

360 spin images for ecommerce

react native app development

react native mobile app development

react native app development company

how to make a vr app

webvr portfolio

react vr documentation

build a vr app

create vr apps

event check-in software for radius

cli elearning

how to create vr apps

offshore it translator

react style display none

how to develop vr application

onn headphones

react native vr app

zoom react native

react native 0.66

three.js mesh

react-native-branch

react-icons npm

virtual reality react native

oculus app labs

adobe xd component states

react native branch

offshore translate

react icons npm

react native animated event

react native stories

building vr apps

emotion react npm

react native center text

camerax sample

react-native border radius

npm normalize

style-loader npm

adobe xd map

react a-frame

react native content loader

position absolute in react native

vr apps

adobe xd map template

border react native

react native loader

schedule component react

three js mesh

zindex react native

virtual office ho chi minh

vr travel case

js vector3

nodejs get parent directory

react image rotate

react native align to bottom

react native border radius

adobe xd to react native

react native animated button

react native bind

react native drag

react native rotate view

react-native-touch-id

.map react

case logic camera

opacity react native

react-native-camera

three js group rotation

borderradius react native

constructor react

mousepose for windows

used index vr

ecommerce xd template

react rotate image

react setstate array

webkit zoom

3498db

react web worker

react-content-loader

let’s play vr

react array state

react native translate

react onmousewheel

requestanimationframe react native

bind this react

display:none javascript

hire webkit developers

js addeventlistener

react addlistener

react native design templates

react native range

react native sketch

react window infinite loader

threejs loaders

vector3 three js

#3498db

node js constructor

react double click

react get mouse position

react native animation loop

react native rotate animation

react native zindex

react-translate

transform.rotation

vietnam coordinates

wheel game crypto software development

react justify content

rotate arrow css

three js react

translate react native

z index in react native

display none javascript

react loader

case logic high zoom camera case

ondblclick

portfolio website using react

react native free template

react set state

react sketch app

react-phone-number-input

vr top of vietnam

adobe xd css export

how to add border in react native

in app messaging react native

loader in react js example

react rotation

this.state is null

z-index react native

margin top in react js

react disable zoom

react state array

react native game development

vr app development

react native mobile development

vr development

hire dedicated react native developers

react js mobile app development

hire react native development services

react native mobile app development company

react native application development services

react native mobile app development services

react native development services

[/sociallocker]

Rate this post

ShareLinkedInX

Want to apply these insights?

Our AI architects offer free 45-minute consultations to discuss your specific use case.

Book a Discovery Call