{"__v":0,"_id":"58f7a4c9cbd001190056cc5a","category":{"version":"58f7a4c8cbd001190056cbf8","project":"578c4badbd223d2000cc1441","_id":"58f7a4c8cbd001190056cbf9","__v":0,"sync":{"url":"","isSync":false},"reference":false,"createdAt":"2016-10-25T23:36:45.975Z","from_sync":false,"order":0,"slug":"basics","title":"Basics"},"parentDoc":null,"project":"578c4badbd223d2000cc1441","user":"576c22a3808cf02b00d37419","version":{"__v":1,"_id":"58f7a4c8cbd001190056cbf8","project":"578c4badbd223d2000cc1441","createdAt":"2017-04-19T17:56:24.172Z","releaseDate":"2017-04-19T17:56:24.172Z","categories":["58f7a4c8cbd001190056cbf9","58f7a4c8cbd001190056cbfa","58f7a4c8cbd001190056cbfb","58f7a4c8cbd001190056cbfc","58f7a4c8cbd001190056cbfd","58f7a4c8cbd001190056cbfe"],"is_deprecated":false,"is_hidden":false,"is_beta":false,"is_stable":true,"codename":"","version_clean":"1.1.0","version":"1.1.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":3,"body":"Once you have gotten to HelloWorld via [Quick Start](doc:quick-start) or [Installing Viro](doc:starting-a-new-viro-project-1), this tutorial will serve as a step by step guide to developing a simple 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]\nOpen the **Hello World** app ``` react-viro init ViroSample```.  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]\nThis scene **HelloWorldScene** is pushed into view using Viro's [scene navigation controller](doc:scene-navigation), ```<ViroSceneNavigator>```. This is done in the entry point to the app,  **index.ios.js**.\n\nViro 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, for Viro apps you'll 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**:\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\n* Render can only return a nested set of JSX statements, which is why 'return' is the first line in this example.\n    \n* After the return statement, we declare the top level component: ```<ViroScene>```. Every scene must have a ```<ViroScene>``` as its top-most element. All other components are children of ```<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 `index.android.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>``` from react-viro so our import statements now look like: \n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"import {\\n  ViroScene,\\n  ViroText,\\n  Viro360Image,\\n  ViroBox,\\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. Let's declare ours to be:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"<ViroBox position={[0, -1, -2]} width={.5} height={.5} length={.2} scale={[1,1,1]} materials={[\\\"grid\\\"]} />\\n\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\n**Positioning the Box**\nIn the above ```<ViroBox>``` declaration we state we want our box to be at ```position``` x=0, y=-1 and z=-2. This will place the box under the \"Hello World\" text. We give it a ```width``` and``` height``` and ```length``` of 0.5 units. \n\nThe final property ```materials``` lets us specify how the object looks. Materials define the visual appearance of the object: its color, how it responds to light, and so on. In this example we specify that we are using the material named ```grid```.\n\n**Defining a Material**\nTo use a material called grid, we need to define it. But first we need to import ```ViroMaterials```, as shown below.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"import {\\n  ViroScene,\\n  ViroText,\\n  Viro360Image,\\n  ViroBox,\\n  ViroMaterials,\\n} from 'react-viro';\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\nAfter we have imported ViroMaterials, we can define ViroMaterials by using the ```createMaterials``` method in the [Materials](doc:materials) class. We do this by adding the following code after our scene: \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]\nYou can see above, that our grid material is located in our res folder and is called grid_bg.jpg.  (Right click on the grid image below and save it to your res folder as **grid_bg.jpg**.)\n\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 add [React state variables](https://facebook.github.io/react-native/docs/state.html). Below we explain how to accomplish this: \n\n**Add a New State Variable**\nFirst we modify ```getInitialState()``` method 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]\nNow we bind our newly created state variable to our ```<ViroText>``` which now looks 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**Add an Event**\nNow lets add an ```onHover``` handler to the ```<ViroBox>```.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"<ViroBox position={[0, -1, -2]} width={.5} height={.5} length={.5} scale={[1,1,1]} materials={[\\\"grid\\\"]} onHover={this._onBoxHover}/>\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\nWe'll define the ```onHover``` handler ```_onBoxHover``` as a new method:\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]} width={.5} height={.5} length={.5} scale={[1,1,1]} 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 grey 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\nOpen a new file and name it HelloBeachScene.js (make sure it is located in the same directory as your HelloWorldScene.js file).  Copy and paste the code below into your HelloBeachScene file and save it.  \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 (HelloWorldScene.js).\n\nNow that we have created our second scene, we need to connect the two scenes together.  Go back to your HelloWorldScene.js file.  \n\nWe will navigate to HelloBeachScene.js by clicking on the ```<ViroBox>```.  To do this we add an ```onClick``` event to the ```<ViroBox>```. \n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"<ViroBox position={[0, -1, -2]} width={.5} height={.5} length={.5} scale={[1,1,1]} materials={[\\\"grid\\\"]} onHover={this._onBoxHover} onClick={this._showHelloBeachScene}/>\\n\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\nWe'll define the ```onClick``` handler ```_showHelloBeachScene``` as a new method:\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]} width={.5} height={.5} length={.5} scale={[1,1,1]} 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.  Load the HelloWorldScene.js file.  Tap on the ```<ViroBox>``` and the scene should change to the 360 beach photo. Tap anywhere on the 360 beach photo to return to the HelloWorldScene.  \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 the Viro platform 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 Viro 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 Viro 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 Viro VR experience.","excerpt":"","slug":"tutorial","type":"basic","title":"Tutorial"}
Once you have gotten to HelloWorld via [Quick Start](doc:quick-start) or [Installing Viro](doc:starting-a-new-viro-project-1), this tutorial will serve as a step by step guide to developing a simple 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] Open the **Hello World** app ``` react-viro init ViroSample```. You should see the following: [block:image] { "images": [ { "image": [ "https://files.readme.io/f457060-HelloWorld.PNG", "HelloWorld.PNG", 800, 450, "#366867" ], "sizing": "smart" } ] } [/block] This scene **HelloWorldScene** is pushed into view using Viro's [scene navigation controller](doc:scene-navigation), ```<ViroSceneNavigator>```. This is done in the entry point to the app, **index.ios.js**. Viro 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, for Viro apps you'll 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**: [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] * Render can only return a nested set of JSX statements, which is why 'return' is the first line in this example. * After the return statement, we declare the top level component: ```<ViroScene>```. Every scene must have a ```<ViroScene>``` as its top-most element. All other components are children of ```<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 `index.android.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>``` from react-viro so our import statements now look like: [block:code] { "codes": [ { "code": "import {\n ViroScene,\n ViroText,\n Viro360Image,\n ViroBox,\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. Let's declare ours to be: [block:code] { "codes": [ { "code": "<ViroBox position={[0, -1, -2]} width={.5} height={.5} length={.2} scale={[1,1,1]} materials={[\"grid\"]} />\n", "language": "javascript" } ] } [/block] **Positioning the Box** In the above ```<ViroBox>``` declaration we state we want our box to be at ```position``` x=0, y=-1 and z=-2. This will place the box under the "Hello World" text. We give it a ```width``` and``` height``` and ```length``` of 0.5 units. The final property ```materials``` lets us specify how the object looks. Materials define the visual appearance of the object: its color, how it responds to light, and so on. In this example we specify that we are using the material named ```grid```. **Defining a Material** To use a material called grid, we need to define it. But first we need to import ```ViroMaterials```, as shown below. [block:code] { "codes": [ { "code": "import {\n ViroScene,\n ViroText,\n Viro360Image,\n ViroBox,\n ViroMaterials,\n} from 'react-viro';", "language": "javascript" } ] } [/block] After we have imported ViroMaterials, we can define ViroMaterials by using the ```createMaterials``` method in the [Materials](doc:materials) class. We do this by adding the following code after our scene: [block:code] { "codes": [ { "code": "ViroMaterials.createMaterials({\n grid: {\n diffuseTexture: require('./res/grid_bg.jpg'),\n },\n});", "language": "javascript" } ] } [/block] You can see above, that our grid material is located in our res folder and is called grid_bg.jpg. (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 add [React state variables](https://facebook.github.io/react-native/docs/state.html). Below we explain how to accomplish this: **Add a New State Variable** First we modify ```getInitialState()``` method 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] Now we bind our newly created state variable to our ```<ViroText>``` which now looks 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] **Add an Event** Now lets add an ```onHover``` handler to the ```<ViroBox>```. [block:code] { "codes": [ { "code": "<ViroBox position={[0, -1, -2]} width={.5} height={.5} length={.5} scale={[1,1,1]} materials={[\"grid\"]} onHover={this._onBoxHover}/>", "language": "javascript" } ] } [/block] We'll define the ```onHover``` handler ```_onBoxHover``` as a new method: [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]} width={.5} height={.5} length={.5} scale={[1,1,1]} 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 grey 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. Open a new file and name it HelloBeachScene.js (make sure it is located in the same directory as your HelloWorldScene.js file). Copy and paste the code below into your HelloBeachScene file and save it. [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 (HelloWorldScene.js). Now that we have created our second scene, we need to connect the two scenes together. Go back to your HelloWorldScene.js file. We will navigate to HelloBeachScene.js by clicking on the ```<ViroBox>```. To do this we add an ```onClick``` event to the ```<ViroBox>```. [block:code] { "codes": [ { "code": "<ViroBox position={[0, -1, -2]} width={.5} height={.5} length={.5} scale={[1,1,1]} materials={[\"grid\"]} onHover={this._onBoxHover} onClick={this._showHelloBeachScene}/>\n", "language": "javascript" } ] } [/block] We'll define the ```onClick``` handler ```_showHelloBeachScene``` as a new method: [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]} width={.5} height={.5} length={.5} scale={[1,1,1]} 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. Load the HelloWorldScene.js file. Tap on the ```<ViroBox>``` and the scene should change to the 360 beach photo. Tap anywhere on the 360 beach photo to return to the HelloWorldScene. 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 the Viro platform 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 Viro 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 Viro 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 Viro VR experience.