2 posts tagged


Introduction to React VR , Part 2

Shay Keinan

Read the first part

We’ll begin by installing the react-vr-cli.

npm install -g react-vr-cli

Next, we are going to initialize the project. This will install all of the dependancies that we need to run the project.

react-vr init WelcomeToVR

cd WelcomeToVR && npm start

Facebook already created a very basic ‘hello world’ project which they call welcome to VR. After installation you should see the following screen:

After the init we get the following file structure:


All the static assets are located in the static_assets folder. The entry point for any VR application is the index.vr.js file. In the VR folder there is always a file called client.js  which is  used for the application configuration and communicating with the Three.js scene.

Let’s take a look at index.vr.js. This is the entry point for our application. We have a basic React component that contains two children:  Pano for the panoramic image of the room and Text for the word “hello”. On the bottom we register the WelcomeToVr component just like in React.

import React from 'react';
import { AppRegistry, asset, Pano, Text, View } from 'react-vr';
class WelcomeToVR extends React.Component {
  render() {
    return (
        <Pano source={asset('chess-world.jpg')}/>
            fontSize: 0.8,
            textAlign: 'center',
            transform: [{translate: [0, 0, -3]}],
AppRegistry.registerComponent('WelcomeToVR', () => WelcomeToVR);

Let’s begin building our own application. The app that we are going to build together will represent our solar system planets.

This is what the application is going to look like. We can see a planet with some text, there is a menu on the right to change a planet, and some additional info about the planet on our left.

Final application demo

3D coordinates and Transformations

To know where to place objects and how to move around the scene we need to be familiar with the coordinate system.

The coordinate system is the same as OpenGL coordinates meaning that y positive is up, and we use the right hand rule for rotation.

We can apply transformations on any component, just like we do with CSS The syntax is a bit different than classic CSS but should be familiar to those who code in React Native. If I want to place an object anywhere other than [0,0,0] I use translate. If I want to change its size I use scale. And if I want to rotate it along a certain axis I use rotate.

Just like React Native, React VR provides a set of basic primitives used to construct user interface. This is a powerful feature of React VR: developers can use the same styling and layout system across web, React Native, and VR, which opens the doors to directly sharing layout styles across these platforms.

View is the most fundamental component for building a UI. It is a container that supports layout with flexbox, styling, and touch handling. View maps directly to the native view equivalent on whatever platform React Native is running on, whether that is a UIView, <div>, or android.view. View is designed to be nested inside other views and can have zero to many children of any type.

Text is a React component for displaying text. It supports nesting and styling.

Image is a react component for displaying different types of images. Keep in mind that you must manually specify the dimensions of your image in meters and it is not possible to predict the intended dimensions from the pixel width and height of the image.

Pano is an image projected onto a sphere that fully surrounds the viewer. It is a Sphere of 1000m with a center located at the local transform origin at [0,0,0]. You can create pano compatible images by using a special 360 camera or even with your phone. Cube map images are also supported in Pano, you can specify a source url as an array of 6 individual images.

So lets add a Pano component to our index.vr.js, we need to provide an asset to the source property.

Note that we are using a utility from react VR called asset. This allows us to load assets directly from the static_assets folder I showed you before. Also note that this is not just any jpeg but rather one that supports 3D.

render() {
  return (
      <Pano source={asset('stars.jpg')}/>

This is the result, our sphere is the cosmos. The image surrounds us.

Styling with Flex box

React VR makes use of a Flexbox style layout algorithm to automatically position components and their children. The library used is CSSLayout, the syntax is more or less identical to the web flexbox.

As you can imagine, using flexbox to layout content on a 2D plane is not optimal for a 3D experience. So it’s a common practice to layout the content on a cylindrical plane. This will give us a ‘2.5D’ feel.


In VR we interact with objects in a different way than the web. We don’t necessarily click on something, it may be enough that we look at an object for a significant amount of time to trigger an event.

Besides looking we can also press a controller to trigger a reaction.

To make our scene interactive we are going to use react’s VrButton — a helper component that manages the interaction state machine. By default, VrButton has no appearance and will only act as a wrapper to capture events, but it can be styled in the same ways as a View.

When pressing a button in our menu, the handleClick function will save the planet name in the currentPlanet variable.

menu() {
  return (
          Object.keys(planets).map((planet) => (
            <VrButton key={`button-${planet}`}
              onClick={() => this.handleClick(planet)}>
              <View style={styles.planetBtn}>
                <Text style={styles.planetBtnLabel}>{planet}</Text>

Let’s take a look at our menu again. Now when we press a button we are updating the currentPlanet variable in our state, and as a result the header component updates.

Loading models

There are many types of model formats available out there like obj, stl, or collada. They may come with a built-in animation, or with material and texture. At the moment, React VR supports the Wavefront OBJ file format only.

React VR provides a component for loading models, called Model. Let’s load Earth.

Here is our planet declaration. The lit property specifies if the model will be affected by lights. The model’s ability to define a style enables us to apply different transformations such as   scaling, rotating, or translating.

  source={{obj: asset(`models/Earth.obj`)}}

Here is the loaded model. By changing the current planet we’re causing a new model to load every time.


To make our scene more interesting we can add animation to objects and layouts. There are two ways to create animations in React VR : using the Animated library, or manually using requestAnimationFrame.

Below is an example of requestAnimationFrame . What I want to do here is rotate a planet. The rotate function in this example is called in a loop hopefully at least 60 frames per second. On each call we are advancing the rotation by a delta.

state = {
  rotation: 0
componentDidMount() { this.rotate(); }
// planet rotate animation
rotate() {
  const now = Date.now();
  const delta = now - this.lastUpdate;
  this.lastUpdate = now;
    rotation: this.state.rotation + delta / 150
  this.frameHandle = requestAnimationFrame(this.rotate);

This is the result, we can see the planet rotating. If we switch planets the new model will still rotate around itself.

Rotating animation

Lets see an example of how to use the Animated library for animations. When a button is pressed we want to make it look like it bounces a bit, and also when a planet appears we will give it a nice little bounce. In the Animated library this effect is called spring.

state = {
  bounceValue: new Animated.Value(1)

// bounce animation
bounce({initial, toValue, friction = 1.5}) {
    {toValue, friction}

Native modules

If React VR doesn’t support a feature that you need, you can build it yourself using native modules.

A lot of stuff that exists in Three.js has not yet been implemented in React VR, for example there are dozens of geometries in Three.js of which only sphere, box and cylinder exist in React VR.

This Tetrahedron geometry is supported in Three.js but not in React VR. So lets create a native module, let’s extend it for React.

Tetrahedron geometry

I need to do 2 things . First I create a module and in its constructor which I receive the Three.js scene. From this point the Three.js scene is open to me.

The rows within the add functions are all Three.js code. I define a tetrahedron geometry, a meshLambert material and a new mesh that I’m adding to the actual Three.js scene.

import { Module } from 'react-vr-web';
import * as THREE from 'three';
export default class AsteroidsModule extends Module {
  constructor(scene) {
    // The name of the module in NativeModules
    this.scene = scene;
  add() {
    const color = 0x7F492A;
    const geometry = new THREE.TetrahedronGeometry(10, 1);
    const material = new THREE.MeshLambertMaterial({ color });
    const mesh = new THREE.Mesh(geometry, material);

The second thing I have to do is go to my client.js file, and place my native module in the native modules array. I also make sure that my module is rendered.

import {VRInstance} from 'react-vr-web';
import AsteroidsModule from '../asteroidsModule';
import * as THREE from 'three';
function init(bundle, parent, options) {
  const scene = new THREE.Scene();
  const Asteroids = new AsteroidsModule(scene);
  const vr = new VRInstance(bundle, 'solarSystem', parent, {
    // Add custom options here
    nativeModules: [ Asteroids ],
  vr.render = function() {
  // Begin the animation loop
  return vr;

Here is my tetrahedron geometry in react VR. These tetrahedrons are going to be my asteroids.

 Tetrahedron geometry

Here is the final application: we are inside a Pano where we loaded an image of stars. We see the header with two texts inside. Below is a loaded model, the planet surrounded by asteroids that we created by using native modules.

On the right is a Menu, a click on the menu switches to a different planet with a bounce. The menu button also has a spring to it. On the left we have an info view. Both the menu and the info have a billboard property that is on and as a result those views always face us.

Final ‘Solar System’ application

You can find the entire project on GitHub. Feel free to use it.

React VR is relatively new, time will tell if the community is willing to adopt it. React VR is a quick and easy way to build a 3D application. I’ll be happy if you share your future applications and insights with me.

Thanks for your time!

React   ReactVR   ThreeJS   Virtual Reality

Introduction to React VR , Part 1

Shay Keinan

Virtual reality is being used in many industries. Besides games, virtual reality is being used in many fields like medicine, education, and movies. Because of its ability to completely immerse you in a scene the possibilities are endless.

Before diving into code I want to talk to you about virtual reality concepts, things that we, as developers, must know if we want to build a virtual reality application.

So what is virtual reality in a nutshell? Visual virtual reality is made up of 2 things: stereoscopic imaging and movement tracking.

Lets look at these 2 images. Are they identical?

They seem identical but if you look closely you can see a difference.

Stereoscopic images are based on how the human brain works: it takes two images that show the same content but from a slightly different point of view. The offset of these images corresponds to the distance between our eyes, this distance is called inter-pupillary distance, IPD for short. In this way we simulate the way we see the world naturally, and it gives us the perception of 3D depth.

Headset lenses are an integral part of the virtual reality experience. Why do we use headset lenses Because they position the images on the screen at the exact distance that they need to be to get the desired effect. VR lenses are thick so they cause a distortion. The square that you see on the left looks caved in through the lenses. The outcome looks something like what we see on the right.

To compensate for this, we give images that are rounded out. On the left you can see a compensated image before the lenses, and on the right is the final desired image.

To sum up stereoscopic imaging: by showing two slightly different images to each eye, using special lenses, we get the effect of depth.

Besides stereoscopic imaging the second thing we need to complete the illusion of virtual space is to track the movement of our body. All VR devices track head movement so we can look around. Some devices, the more expensive ones, track body movements, so we can move around. Of course the more tracking sensors that you have, the better the illusion of reality.

On April this year, Facebook announced the launch of React VR, a new JavaScript framework, based on Three.js and React Native.

React VR allows developers to build virtual reality experiences with the help of JavaScript. As the name implies, React VR uses the same concepts as Facebook’s existing React framework. Just like with React for standard web apps, VR developers can now use the same declarative model to write apps for their 360-degree experiences.

Just like in animation, VR apps need to be rendered at 60 frames per second, React Native has solved many of the issues that usually make this hard to do with a JavaScript application. It’s important to know that React VR is based on React Native and Three.js. Most of the components that we use are React Native components. The 3D rendering engine is the Three.js rendering engine.

Three.js is a cross-browser JavaScript library used to create and display animated 3D graphics.

In the next part, we are going to cover React’s VR basic components and start to write an application from scratch. If you can’t wait and want to move on the entire tutorial is available here:

React   ReactVR   ThreeJS   Virtual Reality