{"_id":"5a06037134873d0010b3920a","category":{"_id":"5a06037134873d0010b391ff","version":"5a06037134873d0010b391fe","project":"578c4badbd223d2000cc1441","__v":0,"sync":{"url":"","isSync":false},"reference":false,"createdAt":"2016-10-25T23:36:45.975Z","from_sync":false,"order":0,"slug":"basics","title":"Getting Started"},"parentDoc":null,"user":"576c22a3808cf02b00d37419","project":"578c4badbd223d2000cc1441","version":{"_id":"5a06037134873d0010b391fe","project":"578c4badbd223d2000cc1441","__v":1,"createdAt":"2017-11-10T19:52:17.163Z","releaseDate":"2017-11-10T19:52:17.163Z","categories":["5a06037134873d0010b391ff","5a06037134873d0010b39200","5a06037134873d0010b39201","5a06037134873d0010b39202","5a06037134873d0010b39203","5a06037134873d0010b39204"],"is_deprecated":false,"is_hidden":false,"is_beta":false,"is_stable":true,"codename":"","version_clean":"2.1.0","version":"2.1.0"},"__v":0,"updates":[],"next":{"pages":[],"description":""},"createdAt":"2016-10-25T17:27:27.283Z","link_external":false,"link_url":"","githubsync":"","sync_unique":"","hidden":false,"api":{"settings":"","results":{"codes":[]},"auth":"required","params":[],"url":""},"isReference":false,"order":5,"body":"This tutorial requires the completion of the [Quick Start](doc:quick-start).\n\nThis tutorial is a step by step guide for developing a simple AR app. Our goal by the end of this tutorial is to:\n\n1. Understand HelloWorldScene.js\n2. Change the photosphere from a beach to a park\n2. Add a new component to our HelloWorldScene\n3. Add an event to our HelloWorldScene\n4. Add a second scene to our app\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Understanding HelloWorldScene.js\"\n}\n[/block]\nUpon start the **Hello World** VR app. You should see the following:\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/f457060-HelloWorld.PNG\",\n        \"HelloWorld.PNG\",\n        800,\n        450,\n        \"#366867\"\n      ],\n      \"sizing\": \"smart\"\n    }\n  ]\n}\n[/block]\nThe scene you are presented with is `HelloWorldScene.js` which is set as the `initialScene` on the [ViroSceneNavigator](doc:viroscenenavigator) component in the `App.js`, which serves as the entry point into your app.\n\nViroReact is built on top of React Native and uses React Native constructs to make it easy to create native VR applications. In addition to understanding Javascript, you will also need to understand some basic React concepts, like [JSX](https://facebook.github.io/react/docs/jsx-in-depth.html), [components](https://facebook.github.io/react/docs/react-component.html), [state](https://facebook.github.io/react-native/docs/state.html), and [props](https://facebook.github.io/react-native/docs/props.html). \n\nBelow is the code for `HelloWorldScene.js`:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"'use strict';\\n\\nimport React, { Component } from 'react';\\n\\nimport {StyleSheet} from 'react-native';\\n\\nimport {\\n  ViroScene,\\n  ViroText,\\n  Viro360Image,\\n} from 'react-viro';\\n\\nvar HelloWorldScene = React.createClass({\\n  getInitialState() {\\n    return {\\n\\n    };\\n  },\\n  render: function() {\\n    return (\\n     <ViroScene>\\n       <Viro360Image source={require('./res/guadalupe_360.jpg')} />\\n       <ViroText text=\\\"Hello World!\\\" width={2} height={2} position={[0, 0, -2]} style={styles.helloWorldTextStyle} />\\n     </ViroScene>\\n    );\\n  },\\n});\\n\\nvar styles = StyleSheet.create({\\n  helloWorldTextStyle: {\\n    fontFamily: 'Arial',\\n    fontSize: 60,\\n    color: '#ffffff',\\n    textAlignVertical: 'center',\\n    textAlign: 'center',  \\n  },\\n});\\n\\nmodule.exports = HelloWorldScene;\",\n      \"language\": \"javascript\",\n      \"name\": null\n    }\n  ]\n}\n[/block]\nThis file represents the first and only [scene](doc:scenes) in the app. A scene in VR is analogous to a web page on the web or a ViewController on mobile: it is a full 'screen' that is rendered to the user. The difference in VR is that there are no bounds; the content surrounds you in 360 degrees. Let's go through the file in detail:\n\n## Importing Components\nThe code begins by importing React, ```StyleSheet``` from React Native and react-viro components that the app will use. In this app we use ```ViroScene```,```ViroText```, and  ```Viro360Image```.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"'use strict';\\n\\nimport React, { Component } from 'react';\\n\\nimport {StyleSheet} from 'react-native';\\n\\nimport {\\n  ViroScene,\\n  ViroText,\\n  Viro360Image,\\n} from 'react-viro';\\n  \\n...\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\n## render() method\nBelow the import code, we declare the HelloWorldScene using React.createClass. This creates a react component that adheres to the [react component lifecycle](https://facebook.github.io/react/docs/react-component.html#the-component-lifecycle).\n\n```getInitialState()``` is the first method defined. It defines the initial state for variables in our class. Currently we don't have any initial state.\n\n```render()``` is an important member of each react class, and in our case, determines how each scene is displayed. It's defined using [JSX](https://facebook.github.io/react/docs/jsx-in-depth.html) which is similar to HTML syntactically. In the section below we go through this method in detail.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"...\\n\\nvar HelloWorldScene = React.createClass({\\n  getInitialState() {\\n    return {\\n\\n    };\\n  },\\n  render: function() {\\n    return (\\n     <ViroScene>\\n       <Viro360Image source={require('./res/guadalupe_360.jpg')} />\\n       <ViroText text=\\\"Hello World!\\\" width={2} height={2} position={[0, 0, -2]} \\t\\t\\t\\tstyle={styles.helloWorldTextStyle} />\\n     </ViroScene>\\n    );\\n  },\\n});\\n\\n...\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\n* In the return statement, we declare the top level VR component: `ViroScene`. All other components are children of the `ViroScene`.\n    \n* `Viro360Image` is the next component: it is known as a background component, in that is rendered *behind* all other objects in the scene. `Viro360Image` renders a 360 degree photo that surrounds the user.\n    \n* `ViroText` is declared next. It displays the text \"Hello World\" at x,y,z position of (0,0,-2) with the font, font size and color specified by the style property. In our coordinate system, the viewer faces in the negative-Z direction, so providing a Z coordinate of -2 places the object in front of the viewer.\n    \n## Declaring Styles\nAfter the render method, we declare styles that can be used in our application. Styles generally represent layout properties for components. In our app, we declare a style named ```helloWorldTextStyle``` that describes the font type, color, size and alignment for our `ViroText` component.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"var styles = StyleSheet.create({\\n  helloWorldTextStyle: {\\n    fontFamily: 'Arial',\\n    fontSize: 60,\\n    color: '#ffffff',\\n    textAlignVertical: 'center',\\n    textAlign: 'center',  \\n  },\\n});\\n\\nmodule.exports = HelloWorldScene;\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\nNow that we described how our scene works, let's see how we can expand upon it. \n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Changing Photospheres\"\n}\n[/block]\nSetting a background is important in VR: it gives the user context and immersion. 360 photos and 360 videos are popular backgrounds in VR. Let's change our HelloWorldScene from a beach to a park.\n\nTo help you get started, we provide a library of [Free Assets](doc:assets). Go to the Free Assets page and scroll down to the Park asset. Save this file as 360_park.jpg in your res folder. In your HelloWorldScene.js file update the `Viro360Image` component as shown below.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"<Viro360Image source={require('./res/360_park.jpg')} />\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\nSave your file and reload the app.  To reload your file, simply shake your phone and a debug menu will appear, as shown below. Tap on \"Reload\" and your changes will appear.\n[block:callout]\n{\n  \"type\": \"info\",\n  \"title\": \"Reloading on Android Devices\",\n  \"body\": \"Android devices running Nougat OS w/ Daydream must reload using ADB with the command: `adb shell input text rr`\\n\\nAndroid devices running Nougat OS w/ Cardboard must set `debug={true}` on SceneNavigator \\nwithin your `App.js` file for the debug menu to appear.\\n\\nMore details on [Reloading](doc:develop-with-viro#section-reloading-features)\"\n}\n[/block]\n\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/51ccf4d-viro_debug_hud.jpg\",\n        \"viro_debug_hud.jpg\",\n        800,\n        450,\n        \"#c4c4c5\"\n      ]\n    }\n  ]\n}\n[/block]\nOnce you reload, you should now see the scene below:\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/04334cb-HelloPark.PNG\",\n        \"HelloPark.PNG\",\n        800,\n        450,\n        \"#36320e\"\n      ]\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Adding Components to a Scene\"\n}\n[/block]\nLet's take our current HelloWorld scene and add a 3D Box above the \"Hello World\" text. We can do this by using the `ViroBox` component. To add a box to our scene we do the following:\n\nFirst we import `ViroBox` and `ViroMaterials` from `react-viro` so our import statements now look like: \n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"import {\\n  ...\\n  ViroBox,\\n  ViroMaterials,\\n} from 'react-viro';\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\nNext we need to add the box to our scene. The [`ViroBox` API Reference](doc:virobox) lets us know what properties we can set to customize our box.\n\nCopy the following code and add it below the `ViroText` component:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"<ViroBox position={[0, -1, -2]} scale={[.5,.5,.2]} materials={[\\\"grid\\\"]} />\\n\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\n**Customizing the ViroBox**\n\nIn the above code, we set the `position` of the `ViroBox` to [0, -.1, -2] so that it sets beneath the \"Hello World\" text.\n\nWe then scale the `ViroBox` by [.5, .5, .2] to make it smaller as its default `width`, `height`, and `length` is 1 (meters).\n\nFinally, the `materials` property define the visual appearance of the object, such as its color, lighting model, etc. In this example, we set a material named `grid` on the `ViroBox`.\n\n**Defining a Material**\nBefore we can use a material like the aforementioned `grid`, we need to define it. Since we have already import `ViroMaterials`, we can simply add the following code beneath the styles declaration.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"ViroMaterials.createMaterials({\\n  grid: {\\n    diffuseTexture: require('./res/grid_bg.jpg'),\\n  },\\n});\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\nAs you can see, we defined a `grid` material containing `diffuseTexture` which points to the file `grid_bg.jpg` in the `res` directory.\n\nTwo things to note here:\n- The `require()` function is a special function provided in React that converts a filepath into a value that the platform can use to fetch the resource.\n- The argument to `require()` is a filepath and is relative to the location of the file (in this case both the `res/` directory and the `HelloWorldScene.js` are in the same `ViroSample/js/` directory.\n\nNow, right click on the grid image below and save it to your res folder as `grid_bg.jpg`.\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/c8a22bc-grid_bg.jpg\",\n        \"grid_bg.jpg\",\n        256,\n        256,\n        \"#b4cccd\"\n      ]\n    }\n  ]\n}\n[/block]\nYour HelloWorldScene.js should now look like this:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"'use strict';\\n\\nimport React, { Component } from 'react';\\n\\nimport {StyleSheet} from 'react-native';\\n\\nimport {\\n  ViroScene,\\n  ViroText,\\n  Viro360Image,\\n  ViroBox,\\n  ViroMaterials,\\n} from 'react-viro';\\n\\nvar HelloWorldScene = React.createClass({\\n  getInitialState() {\\n    return {\\n\\n    };\\n  },\\n  render: function() {\\n    return (\\n     <ViroScene>\\n       <Viro360Image source={require('./res/360_park.jpg')} />\\n       <ViroText text=\\\"Hello World!\\\" width={2} height={2} position={[0, 0, -2]} style={styles.helloWorldTextStyle} />\\n       <ViroBox position={[0, -1, -2]} width={.5} height={.5} length={.2} scale={[1,1,1]} materials={[\\\"grid\\\"]} />\\n     </ViroScene>\\n    );\\n  },\\n});\\n\\nvar styles = StyleSheet.create({\\n  helloWorldTextStyle: {\\n    fontFamily: 'Arial',\\n    fontSize: 60,\\n    color: '#ffffff',\\n    textAlignVertical: 'center',\\n    textAlign: 'center',\\n  },\\n});\\n\\nViroMaterials.createMaterials({\\n  grid: {\\n    diffuseTexture: require('./res/grid_bg.jpg'),\\n  },\\n});\\n\\nmodule.exports = HelloWorldScene;\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\nSave your HelloWorldScene.js file and reload the app.  You should now see a pink and grey cube under the Hello World text\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/6e702ac-HelloBox.PNG\",\n        \"HelloBox.PNG\",\n        800,\n        450,\n        \"#37310e\"\n      ]\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Adding Events and State\"\n}\n[/block]\nNow let's add an event when the user hovers on the box. Also, we'll add an action to the hover event that changes the text displayed in the `ViroText` component. To accomplish this, we'll need to use [state](https://facebook.github.io/react-native/docs/state.html).\n\n**Adding new State**\nFirst we modify the ```getInitialState()``` function to add a new state variable. (We'll explain what we do with this variable in the next step.) Now our ```getInitialState()``` method looks like this: \n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"getInitialState() {\\n    return {\\n      text:\\\"Hello World!\\\",\\n    };\\n  },\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\nNext, we use the `text` value we stored in state by updating the `ViroText` component to look like the following:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"<ViroText text={this.state.text} width={2} height={2} position={[0, 0, -2]} style={styles.helloWorldTextStyle} />\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\n**Adding an Event**\nNow we'll add an `onHover` handler to the `ViroBox`, so that when the user hovers over the box, the text will update in response:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"<ViroBox position={[0, -1, -2]} scale={[.5,.5,.2]} materials={[\\\"grid\\\"]} onHover={this._onBoxHover}/>\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\nNext, add a ```_onBoxHover``` function to the `React.createClass()` function after the `render()` function:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"_onBoxHover(isHovering) {\\n    let text = isHovering ? \\\"Hello Box!\\\" : \\\"Hello World!\\\";\\n    this.setState({\\n      text\\n    });\\n},\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\nThe above method is invoked when the user hovers on or off the box. When the user hovers on the box ```isHovering``` is set to true and we update the state variable to reflect the new text value. Since React is a declarative framework and the state.text variable is bound to the `ViroText` component, the text will change automatically as the user hovers on and off the box.\n\nLet's look at our final code with our new changes:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"'use strict';\\n\\nimport React, { Component } from 'react';\\n\\nimport {StyleSheet} from 'react-native';\\n\\nimport {\\n  ViroScene,\\n  ViroText,\\n  Viro360Image,\\n  ViroBox,\\n  ViroMaterials,\\n} from 'react-viro';\\n\\nvar HelloWorldScene = React.createClass({\\n  getInitialState() {\\n    return {\\n      text:\\\"Hello World!\\\",\\n    };\\n  },\\n  render: function() {\\n    return (\\n     <ViroScene>\\n       <Viro360Image source={require('./res/360_park.jpg')} />\\n       <ViroText text={this.state.text} width={2} height={2} position={[0, 0, -2]} style={styles.helloWorldTextStyle} />\\n       <ViroBox position={[0, -1, -2]} scale={[.5,.5,.2]} materials={[\\\"grid\\\"]} onHover={this._onBoxHover}/>\\n     </ViroScene>\\n    );\\n  },\\n\\n  _onBoxHover(isHovering) {\\n    let text = isHovering ? \\\"Hello Box!\\\" : \\\"Hello World!\\\";\\n    this.setState({\\n      text\\n    });\\n  },\\n\\n});\\n\\nvar styles = StyleSheet.create({\\n  helloWorldTextStyle: {\\n    fontFamily: 'Arial',\\n    fontSize: 60,\\n    color: '#ffffff',\\n    textAlignVertical: 'center',\\n    textAlign: 'center',\\n  },\\n});\\n\\nViroMaterials.createMaterials({\\n  grid: {\\n    diffuseTexture: require('./res/grid_bg.jpg'),\\n  },\\n});\\n\\nmodule.exports = HelloWorldScene;\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\nSave your `HelloWorldScene.js` file and reload the app.  When you hover over the pink and gray box with the reticle, you should see the text change to \"Hello Box\": \n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/c3e3506-HelloBoth.PNG\",\n        \"HelloBoth.PNG\",\n        800,\n        450,\n        \"#3b3211\"\n      ]\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"title\": \"Adding Another Scene\"\n}\n[/block]\nLet's add a second scene to our HelloWorld app.  \n\nCopy and paste the following code below into a new file under `ViroSample/js/` and save it as `HelloBeachScene.js`.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"'use strict';\\n\\nimport React, { Component } from 'react';\\n\\nimport {StyleSheet} from 'react-native';\\n\\nimport {\\n  ViroScene,\\n  Viro360Image,\\n} from 'react-viro';\\n\\nvar HelloBeachScene = React.createClass({\\n  getInitialState() {\\n    return {\\n    };\\n  },\\n  render: function() {\\n    return (\\n     <ViroScene onClick={this._showHelloWorldScene}>\\n       <Viro360Image source={require('./res/guadalupe_360.jpg')} />\\n     </ViroScene>\\n    );\\n  },\\n\\n  _showHelloWorldScene() {\\n    this.props.sceneNavigator.pop();\\n  },\\n\\n});\\n\\nmodule.exports = HelloBeachScene;\\n\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\nThe top half of the file should look familiar as it is nearly identical to our original HelloWorldScene which showed a 360 beach photo. Let's dive into the changes:\n\n- We renamed the our scene from HelloWorldScene to HelloBeachScene in line 12 and line 31. \n- We added an ```onClick``` event to the `ViroScene` component (line 19).  By tapping on the 360 beach photo, we will return to the previous scene (HelloWorldScene).\n- We defined the ```onClick``` handler ```_showHelloWorldScene``` as a new method (lines 25-27). \n\nThe above method is invoked when the user clicks on anywhere on the scene. When the user clicks on anywhere on the scene the `ViroSceneNavigator` pops back to the previous scene in the stack (the `HelloWorldScene.js`).\n\nNow that we have created our second scene, we need to connect the two scenes together.\n\n\nFrom our original scene,  `HelloWorldScene.js`, we will navigate to the scene in `HelloBeachScene.js` by clicking on the `ViroBox`.  To do this we add an `onClick` event listener to the `ViroBox`. \n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"<ViroBox position={[0, -1, -2]} scale={[.5,.5,.2]} materials={[\\\"grid\\\"]} onHover={this._onBoxHover} onClick={this._showHelloBeachScene}/>\\n\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\nAdd the following ```_showHelloBeachScene``` function within the `React.createClass()` under `_onBoxHover`:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"_showHelloBeachScene() {\\n    this.props.sceneNavigator.push({scene:require(\\\"./HelloBeachScene.js\\\")});\\n  },\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\nThe above method is invoked when the user clicks on the box. When the user clicks on the box the scene navigator pushes the new scene (HelloBeachScene.js) into the renderer.\n\nLet's look at our final code for HelloWorldScene.js with our new changes:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"'use strict';\\n\\nimport React, { Component } from 'react';\\n\\nimport {StyleSheet} from 'react-native';\\n\\nimport {\\n  ViroScene,\\n  ViroText,\\n  Viro360Image,\\n  ViroBox,\\n  ViroMaterials,\\n} from 'react-viro';\\n\\nvar HelloWorldScene = React.createClass({\\n  getInitialState() {\\n    return {\\n      text:\\\"Hello World!\\\",\\n    };\\n  },\\n  render: function() {\\n    return (\\n     <ViroScene>\\n       <Viro360Image source={require('./res/360_park.jpg')} />\\n       <ViroText text={this.state.text} width={2} height={2} position={[0, 0, -2]} style={styles.helloWorldTextStyle} />\\n       <ViroBox position={[0, -1, -2]} scale={[.5,.5,.2]} materials={[\\\"grid\\\"]} onHover={this._onBoxHover} onClick={this._showHelloBeachScene}/>\\n     </ViroScene>\\n    );\\n  },\\n\\n  _onBoxHover(isHovering) {\\n    let text = isHovering ? \\\"Hello Box!\\\" : \\\"Hello World!\\\";\\n    this.setState({\\n      text\\n    });\\n  },\\n\\n  _showHelloBeachScene() {\\n    this.props.sceneNavigator.push({scene:require(\\\"./HelloBeachScene.js\\\")});\\n  },\\n\\n});\\n\\nvar styles = StyleSheet.create({\\n  helloWorldTextStyle: {\\n    fontFamily: 'Arial',\\n    fontSize: 60,\\n    color: '#ffffff',\\n    textAlignVertical: 'center',\\n    textAlign: 'center',\\n  },\\n});\\n\\nViroMaterials.createMaterials({\\n  grid: {\\n    diffuseTexture: require('./res/grid_bg.jpg'),\\n  },\\n});\\n\\nmodule.exports = HelloWorldScene;\\n\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\nAt this point we can navigate to a new scene by clicking on the box in `HelloWorldScene.js`. Reload our completed scene and when you tap on the `ViroBox`, the scene should change to the `HelloBeachScene.js`. Tapping anywhere in the the `HelloBeachScene.js` should then take you back to the `HelloWorldScene.js`.\n\nCongratulations, you now have a multi-scene VR experience!!!\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/023b67a-hello_box_b.gif\",\n        \"hello_box_b.gif\",\n        480,\n        270,\n        \"#413418\"\n      ]\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"title\": \"Next Steps\"\n}\n[/block]\n## Continue Modifying the Scene\nYou should now have a basic overview for how ViroReact works. Check out our [Code Samples](doc:code-samples) for other example apps, or continuing adding functionality on your own to the HelloWorldScene. For example:\n\n* Add an animation by making the cube rotate. Look at our [Animation Guide](doc:animation) for info on how to accomplish this.\n* Try adding illumination to the scene by adding a ```<ViroOmniLight>``` and giving the box a ```lightingModel```. Check out the [Lighting and Materials](doc:3d-scene-lighting) guide for details.\n* Create a grid of videos on the next scene to display to the user. Each one playing as you hover on it. Look at our [Flexbox UI Guide](doc:flexbox-ui-layouts) and [Video Guide](doc:video) on how to build the UI for this and display the video.\n\n## Set up [Android Studio](doc:installing-viro-android) or [Xcode](doc:starting-a-new-viro-project-1) \n\nFor most cases, using the solely the testbed to develop your ViroReact application is enough, but there may come a time where you want to build your own standalone application to test other VR platforms, submit to an app store or to integrate ViroReact with an existing native application . In those cases you will need to set up and use either Xcode or Android Studio to configure and build your own native iOS/Android application containing your ViroReact VR experience.","excerpt":"","slug":"tutorial","type":"basic","title":"Tutorial VR"}
This tutorial requires the completion of the [Quick Start](doc:quick-start). This tutorial is a step by step guide for developing a simple AR app. Our goal by the end of this tutorial is to: 1. Understand HelloWorldScene.js 2. Change the photosphere from a beach to a park 2. Add a new component to our HelloWorldScene 3. Add an event to our HelloWorldScene 4. Add a second scene to our app [block:api-header] { "type": "basic", "title": "Understanding HelloWorldScene.js" } [/block] Upon start the **Hello World** VR app. You should see the following: [block:image] { "images": [ { "image": [ "https://files.readme.io/f457060-HelloWorld.PNG", "HelloWorld.PNG", 800, 450, "#366867" ], "sizing": "smart" } ] } [/block] The scene you are presented with is `HelloWorldScene.js` which is set as the `initialScene` on the [ViroSceneNavigator](doc:viroscenenavigator) component in the `App.js`, which serves as the entry point into your app. ViroReact is built on top of React Native and uses React Native constructs to make it easy to create native VR applications. In addition to understanding Javascript, you will also need to understand some basic React concepts, like [JSX](https://facebook.github.io/react/docs/jsx-in-depth.html), [components](https://facebook.github.io/react/docs/react-component.html), [state](https://facebook.github.io/react-native/docs/state.html), and [props](https://facebook.github.io/react-native/docs/props.html). Below is the code for `HelloWorldScene.js`: [block:code] { "codes": [ { "code": "'use strict';\n\nimport React, { Component } from 'react';\n\nimport {StyleSheet} from 'react-native';\n\nimport {\n ViroScene,\n ViroText,\n Viro360Image,\n} from 'react-viro';\n\nvar HelloWorldScene = React.createClass({\n getInitialState() {\n return {\n\n };\n },\n render: function() {\n return (\n <ViroScene>\n <Viro360Image source={require('./res/guadalupe_360.jpg')} />\n <ViroText text=\"Hello World!\" width={2} height={2} position={[0, 0, -2]} style={styles.helloWorldTextStyle} />\n </ViroScene>\n );\n },\n});\n\nvar styles = StyleSheet.create({\n helloWorldTextStyle: {\n fontFamily: 'Arial',\n fontSize: 60,\n color: '#ffffff',\n textAlignVertical: 'center',\n textAlign: 'center', \n },\n});\n\nmodule.exports = HelloWorldScene;", "language": "javascript", "name": null } ] } [/block] This file represents the first and only [scene](doc:scenes) in the app. A scene in VR is analogous to a web page on the web or a ViewController on mobile: it is a full 'screen' that is rendered to the user. The difference in VR is that there are no bounds; the content surrounds you in 360 degrees. Let's go through the file in detail: ## Importing Components The code begins by importing React, ```StyleSheet``` from React Native and react-viro components that the app will use. In this app we use ```ViroScene```,```ViroText```, and ```Viro360Image```. [block:code] { "codes": [ { "code": "'use strict';\n\nimport React, { Component } from 'react';\n\nimport {StyleSheet} from 'react-native';\n\nimport {\n ViroScene,\n ViroText,\n Viro360Image,\n} from 'react-viro';\n \n...", "language": "javascript" } ] } [/block] ## render() method Below the import code, we declare the HelloWorldScene using React.createClass. This creates a react component that adheres to the [react component lifecycle](https://facebook.github.io/react/docs/react-component.html#the-component-lifecycle). ```getInitialState()``` is the first method defined. It defines the initial state for variables in our class. Currently we don't have any initial state. ```render()``` is an important member of each react class, and in our case, determines how each scene is displayed. It's defined using [JSX](https://facebook.github.io/react/docs/jsx-in-depth.html) which is similar to HTML syntactically. In the section below we go through this method in detail. [block:code] { "codes": [ { "code": "...\n\nvar HelloWorldScene = React.createClass({\n getInitialState() {\n return {\n\n };\n },\n render: function() {\n return (\n <ViroScene>\n <Viro360Image source={require('./res/guadalupe_360.jpg')} />\n <ViroText text=\"Hello World!\" width={2} height={2} position={[0, 0, -2]} \t\t\t\tstyle={styles.helloWorldTextStyle} />\n </ViroScene>\n );\n },\n});\n\n...", "language": "javascript" } ] } [/block] * In the return statement, we declare the top level VR component: `ViroScene`. All other components are children of the `ViroScene`. * `Viro360Image` is the next component: it is known as a background component, in that is rendered *behind* all other objects in the scene. `Viro360Image` renders a 360 degree photo that surrounds the user. * `ViroText` is declared next. It displays the text "Hello World" at x,y,z position of (0,0,-2) with the font, font size and color specified by the style property. In our coordinate system, the viewer faces in the negative-Z direction, so providing a Z coordinate of -2 places the object in front of the viewer. ## Declaring Styles After the render method, we declare styles that can be used in our application. Styles generally represent layout properties for components. In our app, we declare a style named ```helloWorldTextStyle``` that describes the font type, color, size and alignment for our `ViroText` component. [block:code] { "codes": [ { "code": "var styles = StyleSheet.create({\n helloWorldTextStyle: {\n fontFamily: 'Arial',\n fontSize: 60,\n color: '#ffffff',\n textAlignVertical: 'center',\n textAlign: 'center', \n },\n});\n\nmodule.exports = HelloWorldScene;", "language": "javascript" } ] } [/block] Now that we described how our scene works, let's see how we can expand upon it. [block:api-header] { "type": "basic", "title": "Changing Photospheres" } [/block] Setting a background is important in VR: it gives the user context and immersion. 360 photos and 360 videos are popular backgrounds in VR. Let's change our HelloWorldScene from a beach to a park. To help you get started, we provide a library of [Free Assets](doc:assets). Go to the Free Assets page and scroll down to the Park asset. Save this file as 360_park.jpg in your res folder. In your HelloWorldScene.js file update the `Viro360Image` component as shown below. [block:code] { "codes": [ { "code": "<Viro360Image source={require('./res/360_park.jpg')} />", "language": "javascript" } ] } [/block] Save your file and reload the app. To reload your file, simply shake your phone and a debug menu will appear, as shown below. Tap on "Reload" and your changes will appear. [block:callout] { "type": "info", "title": "Reloading on Android Devices", "body": "Android devices running Nougat OS w/ Daydream must reload using ADB with the command: `adb shell input text rr`\n\nAndroid devices running Nougat OS w/ Cardboard must set `debug={true}` on SceneNavigator \nwithin your `App.js` file for the debug menu to appear.\n\nMore details on [Reloading](doc:develop-with-viro#section-reloading-features)" } [/block] [block:image] { "images": [ { "image": [ "https://files.readme.io/51ccf4d-viro_debug_hud.jpg", "viro_debug_hud.jpg", 800, 450, "#c4c4c5" ] } ] } [/block] Once you reload, you should now see the scene below: [block:image] { "images": [ { "image": [ "https://files.readme.io/04334cb-HelloPark.PNG", "HelloPark.PNG", 800, 450, "#36320e" ] } ] } [/block] [block:api-header] { "type": "basic", "title": "Adding Components to a Scene" } [/block] Let's take our current HelloWorld scene and add a 3D Box above the "Hello World" text. We can do this by using the `ViroBox` component. To add a box to our scene we do the following: First we import `ViroBox` and `ViroMaterials` from `react-viro` so our import statements now look like: [block:code] { "codes": [ { "code": "import {\n ...\n ViroBox,\n ViroMaterials,\n} from 'react-viro';", "language": "javascript" } ] } [/block] Next we need to add the box to our scene. The [`ViroBox` API Reference](doc:virobox) lets us know what properties we can set to customize our box. Copy the following code and add it below the `ViroText` component: [block:code] { "codes": [ { "code": "<ViroBox position={[0, -1, -2]} scale={[.5,.5,.2]} materials={[\"grid\"]} />\n", "language": "javascript" } ] } [/block] **Customizing the ViroBox** In the above code, we set the `position` of the `ViroBox` to [0, -.1, -2] so that it sets beneath the "Hello World" text. We then scale the `ViroBox` by [.5, .5, .2] to make it smaller as its default `width`, `height`, and `length` is 1 (meters). Finally, the `materials` property define the visual appearance of the object, such as its color, lighting model, etc. In this example, we set a material named `grid` on the `ViroBox`. **Defining a Material** Before we can use a material like the aforementioned `grid`, we need to define it. Since we have already import `ViroMaterials`, we can simply add the following code beneath the styles declaration. [block:code] { "codes": [ { "code": "ViroMaterials.createMaterials({\n grid: {\n diffuseTexture: require('./res/grid_bg.jpg'),\n },\n});", "language": "javascript" } ] } [/block] As you can see, we defined a `grid` material containing `diffuseTexture` which points to the file `grid_bg.jpg` in the `res` directory. Two things to note here: - The `require()` function is a special function provided in React that converts a filepath into a value that the platform can use to fetch the resource. - The argument to `require()` is a filepath and is relative to the location of the file (in this case both the `res/` directory and the `HelloWorldScene.js` are in the same `ViroSample/js/` directory. Now, right click on the grid image below and save it to your res folder as `grid_bg.jpg`. [block:image] { "images": [ { "image": [ "https://files.readme.io/c8a22bc-grid_bg.jpg", "grid_bg.jpg", 256, 256, "#b4cccd" ] } ] } [/block] Your HelloWorldScene.js should now look like this: [block:code] { "codes": [ { "code": "'use strict';\n\nimport React, { Component } from 'react';\n\nimport {StyleSheet} from 'react-native';\n\nimport {\n ViroScene,\n ViroText,\n Viro360Image,\n ViroBox,\n ViroMaterials,\n} from 'react-viro';\n\nvar HelloWorldScene = React.createClass({\n getInitialState() {\n return {\n\n };\n },\n render: function() {\n return (\n <ViroScene>\n <Viro360Image source={require('./res/360_park.jpg')} />\n <ViroText text=\"Hello World!\" width={2} height={2} position={[0, 0, -2]} style={styles.helloWorldTextStyle} />\n <ViroBox position={[0, -1, -2]} width={.5} height={.5} length={.2} scale={[1,1,1]} materials={[\"grid\"]} />\n </ViroScene>\n );\n },\n});\n\nvar styles = StyleSheet.create({\n helloWorldTextStyle: {\n fontFamily: 'Arial',\n fontSize: 60,\n color: '#ffffff',\n textAlignVertical: 'center',\n textAlign: 'center',\n },\n});\n\nViroMaterials.createMaterials({\n grid: {\n diffuseTexture: require('./res/grid_bg.jpg'),\n },\n});\n\nmodule.exports = HelloWorldScene;", "language": "javascript" } ] } [/block] Save your HelloWorldScene.js file and reload the app. You should now see a pink and grey cube under the Hello World text [block:image] { "images": [ { "image": [ "https://files.readme.io/6e702ac-HelloBox.PNG", "HelloBox.PNG", 800, 450, "#37310e" ] } ] } [/block] [block:api-header] { "type": "basic", "title": "Adding Events and State" } [/block] Now let's add an event when the user hovers on the box. Also, we'll add an action to the hover event that changes the text displayed in the `ViroText` component. To accomplish this, we'll need to use [state](https://facebook.github.io/react-native/docs/state.html). **Adding new State** First we modify the ```getInitialState()``` function to add a new state variable. (We'll explain what we do with this variable in the next step.) Now our ```getInitialState()``` method looks like this: [block:code] { "codes": [ { "code": "getInitialState() {\n return {\n text:\"Hello World!\",\n };\n },", "language": "javascript" } ] } [/block] Next, we use the `text` value we stored in state by updating the `ViroText` component to look like the following: [block:code] { "codes": [ { "code": "<ViroText text={this.state.text} width={2} height={2} position={[0, 0, -2]} style={styles.helloWorldTextStyle} />", "language": "javascript" } ] } [/block] **Adding an Event** Now we'll add an `onHover` handler to the `ViroBox`, so that when the user hovers over the box, the text will update in response: [block:code] { "codes": [ { "code": "<ViroBox position={[0, -1, -2]} scale={[.5,.5,.2]} materials={[\"grid\"]} onHover={this._onBoxHover}/>", "language": "javascript" } ] } [/block] Next, add a ```_onBoxHover``` function to the `React.createClass()` function after the `render()` function: [block:code] { "codes": [ { "code": "_onBoxHover(isHovering) {\n let text = isHovering ? \"Hello Box!\" : \"Hello World!\";\n this.setState({\n text\n });\n},", "language": "javascript" } ] } [/block] The above method is invoked when the user hovers on or off the box. When the user hovers on the box ```isHovering``` is set to true and we update the state variable to reflect the new text value. Since React is a declarative framework and the state.text variable is bound to the `ViroText` component, the text will change automatically as the user hovers on and off the box. Let's look at our final code with our new changes: [block:code] { "codes": [ { "code": "'use strict';\n\nimport React, { Component } from 'react';\n\nimport {StyleSheet} from 'react-native';\n\nimport {\n ViroScene,\n ViroText,\n Viro360Image,\n ViroBox,\n ViroMaterials,\n} from 'react-viro';\n\nvar HelloWorldScene = React.createClass({\n getInitialState() {\n return {\n text:\"Hello World!\",\n };\n },\n render: function() {\n return (\n <ViroScene>\n <Viro360Image source={require('./res/360_park.jpg')} />\n <ViroText text={this.state.text} width={2} height={2} position={[0, 0, -2]} style={styles.helloWorldTextStyle} />\n <ViroBox position={[0, -1, -2]} scale={[.5,.5,.2]} materials={[\"grid\"]} onHover={this._onBoxHover}/>\n </ViroScene>\n );\n },\n\n _onBoxHover(isHovering) {\n let text = isHovering ? \"Hello Box!\" : \"Hello World!\";\n this.setState({\n text\n });\n },\n\n});\n\nvar styles = StyleSheet.create({\n helloWorldTextStyle: {\n fontFamily: 'Arial',\n fontSize: 60,\n color: '#ffffff',\n textAlignVertical: 'center',\n textAlign: 'center',\n },\n});\n\nViroMaterials.createMaterials({\n grid: {\n diffuseTexture: require('./res/grid_bg.jpg'),\n },\n});\n\nmodule.exports = HelloWorldScene;", "language": "javascript" } ] } [/block] Save your `HelloWorldScene.js` file and reload the app. When you hover over the pink and gray box with the reticle, you should see the text change to "Hello Box": [block:image] { "images": [ { "image": [ "https://files.readme.io/c3e3506-HelloBoth.PNG", "HelloBoth.PNG", 800, 450, "#3b3211" ] } ] } [/block] [block:api-header] { "title": "Adding Another Scene" } [/block] Let's add a second scene to our HelloWorld app. Copy and paste the following code below into a new file under `ViroSample/js/` and save it as `HelloBeachScene.js`. [block:code] { "codes": [ { "code": "'use strict';\n\nimport React, { Component } from 'react';\n\nimport {StyleSheet} from 'react-native';\n\nimport {\n ViroScene,\n Viro360Image,\n} from 'react-viro';\n\nvar HelloBeachScene = React.createClass({\n getInitialState() {\n return {\n };\n },\n render: function() {\n return (\n <ViroScene onClick={this._showHelloWorldScene}>\n <Viro360Image source={require('./res/guadalupe_360.jpg')} />\n </ViroScene>\n );\n },\n\n _showHelloWorldScene() {\n this.props.sceneNavigator.pop();\n },\n\n});\n\nmodule.exports = HelloBeachScene;\n", "language": "javascript" } ] } [/block] The top half of the file should look familiar as it is nearly identical to our original HelloWorldScene which showed a 360 beach photo. Let's dive into the changes: - We renamed the our scene from HelloWorldScene to HelloBeachScene in line 12 and line 31. - We added an ```onClick``` event to the `ViroScene` component (line 19). By tapping on the 360 beach photo, we will return to the previous scene (HelloWorldScene). - We defined the ```onClick``` handler ```_showHelloWorldScene``` as a new method (lines 25-27). The above method is invoked when the user clicks on anywhere on the scene. When the user clicks on anywhere on the scene the `ViroSceneNavigator` pops back to the previous scene in the stack (the `HelloWorldScene.js`). Now that we have created our second scene, we need to connect the two scenes together. From our original scene, `HelloWorldScene.js`, we will navigate to the scene in `HelloBeachScene.js` by clicking on the `ViroBox`. To do this we add an `onClick` event listener to the `ViroBox`. [block:code] { "codes": [ { "code": "<ViroBox position={[0, -1, -2]} scale={[.5,.5,.2]} materials={[\"grid\"]} onHover={this._onBoxHover} onClick={this._showHelloBeachScene}/>\n", "language": "javascript" } ] } [/block] Add the following ```_showHelloBeachScene``` function within the `React.createClass()` under `_onBoxHover`: [block:code] { "codes": [ { "code": "_showHelloBeachScene() {\n this.props.sceneNavigator.push({scene:require(\"./HelloBeachScene.js\")});\n },", "language": "javascript" } ] } [/block] The above method is invoked when the user clicks on the box. When the user clicks on the box the scene navigator pushes the new scene (HelloBeachScene.js) into the renderer. Let's look at our final code for HelloWorldScene.js with our new changes: [block:code] { "codes": [ { "code": "'use strict';\n\nimport React, { Component } from 'react';\n\nimport {StyleSheet} from 'react-native';\n\nimport {\n ViroScene,\n ViroText,\n Viro360Image,\n ViroBox,\n ViroMaterials,\n} from 'react-viro';\n\nvar HelloWorldScene = React.createClass({\n getInitialState() {\n return {\n text:\"Hello World!\",\n };\n },\n render: function() {\n return (\n <ViroScene>\n <Viro360Image source={require('./res/360_park.jpg')} />\n <ViroText text={this.state.text} width={2} height={2} position={[0, 0, -2]} style={styles.helloWorldTextStyle} />\n <ViroBox position={[0, -1, -2]} scale={[.5,.5,.2]} materials={[\"grid\"]} onHover={this._onBoxHover} onClick={this._showHelloBeachScene}/>\n </ViroScene>\n );\n },\n\n _onBoxHover(isHovering) {\n let text = isHovering ? \"Hello Box!\" : \"Hello World!\";\n this.setState({\n text\n });\n },\n\n _showHelloBeachScene() {\n this.props.sceneNavigator.push({scene:require(\"./HelloBeachScene.js\")});\n },\n\n});\n\nvar styles = StyleSheet.create({\n helloWorldTextStyle: {\n fontFamily: 'Arial',\n fontSize: 60,\n color: '#ffffff',\n textAlignVertical: 'center',\n textAlign: 'center',\n },\n});\n\nViroMaterials.createMaterials({\n grid: {\n diffuseTexture: require('./res/grid_bg.jpg'),\n },\n});\n\nmodule.exports = HelloWorldScene;\n", "language": "javascript" } ] } [/block] At this point we can navigate to a new scene by clicking on the box in `HelloWorldScene.js`. Reload our completed scene and when you tap on the `ViroBox`, the scene should change to the `HelloBeachScene.js`. Tapping anywhere in the the `HelloBeachScene.js` should then take you back to the `HelloWorldScene.js`. Congratulations, you now have a multi-scene VR experience!!! [block:image] { "images": [ { "image": [ "https://files.readme.io/023b67a-hello_box_b.gif", "hello_box_b.gif", 480, 270, "#413418" ] } ] } [/block] [block:api-header] { "title": "Next Steps" } [/block] ## Continue Modifying the Scene You should now have a basic overview for how ViroReact works. Check out our [Code Samples](doc:code-samples) for other example apps, or continuing adding functionality on your own to the HelloWorldScene. For example: * Add an animation by making the cube rotate. Look at our [Animation Guide](doc:animation) for info on how to accomplish this. * Try adding illumination to the scene by adding a ```<ViroOmniLight>``` and giving the box a ```lightingModel```. Check out the [Lighting and Materials](doc:3d-scene-lighting) guide for details. * Create a grid of videos on the next scene to display to the user. Each one playing as you hover on it. Look at our [Flexbox UI Guide](doc:flexbox-ui-layouts) and [Video Guide](doc:video) on how to build the UI for this and display the video. ## Set up [Android Studio](doc:installing-viro-android) or [Xcode](doc:starting-a-new-viro-project-1) For most cases, using the solely the testbed to develop your ViroReact application is enough, but there may come a time where you want to build your own standalone application to test other VR platforms, submit to an app store or to integrate ViroReact with an existing native application . In those cases you will need to set up and use either Xcode or Android Studio to configure and build your own native iOS/Android application containing your ViroReact VR experience.