AR For The Web: An 8th Wall Tutorial
Tags: augmentedreality, ar, webdev, html
Published: 2019-09-11 18:58:20

# AR For the Web
Hi everyone, I'm a dev that's very interested in XR technology, and I think it would be great if users didn't need an expensive phone or a fancy headset to experience XR for themselves.
In this set of tutorials, I'll be walking you through how to create your own Augmented reality app using 8th Wall and A-Frame, that you can run right in your phone browser! I'll try to take it slow, so even if you have little experience you should still be able to follow along!

## Pre-Requisites
- We'll need NPM to install the packages we need in order to run our app. https://www.npmjs.com/get-npm
- A text editor, my personal preference is VSCode https://code.visualstudio.com/
- A web dev account on 8th Wall ( Important to choose web dev not unity for this tutorial ) https://www.8thwall.com/
 
## Let's Start : Setting Up
Before we dive in I'll make a note to say that this tutorial will mostly follow the 8th wall quick start docs, so if you need another perspective head there. The following tutorials will dive deeper.  
First let's navigate to our 8th wall console (https://console.8thwall.com/web/), and create a new project. Our console should look like so: ![Web console with one project](https://i.imgur.com/oZxJ00U.png)
Next we need to authorize our phone as a developer device. To do this just click device authorization in the top right of the developer console, and scan the QR code.  
Now we'll download some scripts that will allow us to run our future AR app locally. We can clone or download the following repo for the scripts: {% github 8thwall/web %} In this tutorial we'll just get the zip since we don't need all of the files.
Let's grab the serve folder from the zip, and set up an empty folder that we will serve our application from.
Inside our empty folder let's create a new HMTL file called index.html  

Here's what my folder structure looks like:  
![Folder Structure](https://i.imgur.com/Y3G93vv.png)

Inside this file we will import scripts to enable our A-Frame and 8th wall content. We will also set up our application key. Our index page should look like this:

```html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>My First Web-AR App!</title>

    <!-- This is 8th Wall's version of A-Frame -->
    <script src="//cdn.8thwall.com/web/aframe/8frame-0.8.2.min.js"></script>

    <!-- This allows us some nice 8th wall AR extras such as the tap to recenter and a loading spinner -->
    <script src="//cdn.8thwall.com/web/xrextras/xrextras.js"></script>

    <!-- We need to replace the XXXXXXXX here with our AppKey -->
    <script async src="//apps.8thwall.com/xrweb?appKey=XXXXXXXX"></script>

  </head>

  <body>

  </body>

</html>
```
We need to import our appkey, so let's head back to the web console. Our App key will be on the right inside our project panel. Just copy and paste this key to replace the Xs in our Index file.

## Creating Our Content

In order to include our AR content we will be using A-Frame. This three.js framework allows us to declaratively add 3d objects to our scene and interact with them using an entity component architecture. In my opinion working with A-Frame feels similar to working with Unity and allows quick prototyping and development. A-Frame is created by Mozilla, the docs can be found here: https://aframe.io/docs/0.9.0/introduction/.  
Let's start by adding our first **entity** to our application; the a-scene. We'll insert it into our body tag just like regular HTML. You might notice we have some attributes on this tag, these are custom 8th wall **components** which have mostly self-explanatory names.

```html
<body>

    <a-scene
        xrweb
        xrextras-tap-recenter
        xrextras-almost-there
        xrextras-loading
        xrextras-runtime-error>

    </a-scene>

</body>
```

Now we have our a-scene setup we can insert more **entities** to our application. Nested inside our a-scene let's add a camera and some lights so we can see what we are doing.

```html
<body>

    <a-scene
        xrweb
        xrextras-tap-recenter
        xrextras-almost-there
        xrextras-loading
        xrextras-runtime-error>

        <a-camera position="0 8 8"></a-camera>

        <a-entity
            light="type: directional;
                castShadow: true;
                intensity: 0.8;
                shadowCameraTop: 7;
                shadowMapHeight: 1024;
                shadowMapWidth: 1024;"
            position="1 4.3 2.5">
        </a-entity>

        <a-entity
            light="type: directional; castShadow: false; intensity: 0.5;"
            position="-0.8 3 1.85">
        </a-entity>

        <a-light type="ambient" intensity="0.2"></a-light>

    </a-scene>

</body>
```
First we added the `<a-camera>` to the scene, this is one of a number of primitive **entities** that A-Frame provides ( [more info here](https://aframe.io/docs/0.9.0/introduction/html-and-primitives.html#primitives) ). Our camera also has a position **component** that we can provide arguments to. While using A-Frame you will make use of many components, they provide a lot of functionality to our **entities** such as; position, scale, materials and more. Without our components our entities would be nothing!  
We then added some more **entities** to our scene, each with a light and position **component** and a number of arguments. Hopefully now you have the general gist of working A-Frame's **Entity** **Component** system, these are the building blocks with which we can build anything!  
Lastly we added an `<a-light>` another A-Frame primitive, I'm sure you can guess what this one does!  
Ok. Now let's add something to our scene that we can actually see, we'll start simple, with a box perhaps. Inserted underneath our light entity:
```html
<a-box 
    color="blue" 
    depth="2" 
    height="2" 
    width="3"
    position="0 0 2">
</a-box>

<a-entity
    geometry="primitive: box; width: 1; height: 1; depth: 1"
    material="color: yellow"
    position="-0.8 1.2 2"
    rotation="0 45 0"
    scale="0.5 0.5 0.5">
</a-entity>
```
So we added two boxes in two different ways!  
The first uses the primitive entity `<a-box>` and we've given it some components to change the look and notably the position. Position in A-Frame is controlled similarly to Unity's Vector3 struct. We can give it 3 arguments; the x,y,z coordinates of our object in 3D space.  
Next we opted for the basic entity option, and added a geometry component to show our box. We also added some other components here, such as scale and rotation. For a list of all built in components it's a good plan to check the [A-Frame docs!](https://aframe.io/docs/0.9.0/core/component.html)  
Our whole index file should look like this: 
```html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>My First Web-AR App!</title>

    <!-- This is 8th Wall's version of Aframe -->
    <script src="//cdn.8thwall.com/web/aframe/8frame-0.8.2.min.js"></script>

    <!-- This allows us some nice 8th wall AR extras such as the tap to recenter and a loading spinner -->
    <script src="//cdn.8thwall.com/web/xrextras/xrextras.js"></script>

    <!-- We need to replace the XXXXXXXX here with our AppKey -->
    <script async src="//apps.8thwall.com/xrweb?appKey=76ZXfqUXU4WjzcF3j3COyqxdgylAbcbSnHqyfHXo7IWmeJWSgkxOveZy93cPbQERsXsG5C"></script>

  </head>

  <body>

    <a-scene
      xrweb
      xrextras-tap-recenter
      xrextras-almost-there
      xrextras-loading
      xrextras-runtime-error>

        <a-camera position="0 8 8"></a-camera>

        <a-entity
        light="type: directional;
            castShadow: true;
            intensity: 0.8;
            shadowCameraTop: 7;
            shadowMapHeight: 1024;
            shadowMapWidth: 1024;"
        position="1 4.3 2.5">
        </a-entity>

        <a-entity
        light="type: directional; castShadow: false; intensity: 0.5;"
        position="-0.8 3 1.85">
        </a-entity>

        <a-light type="ambient" intensity="0.2"></a-light>

        <a-box 
        color="blue" 
        depth="2" 
        height="2" 
        width="3"
        position="0 0 2">
        </a-box>

        <a-entity
        geometry="primitive: box; width: 1; height: 1; depth: 1"
        material="color: yellow"
        position="-0.8 1.2 2"
        rotation="0 45 0"
        scale="0.5 0.5 0.5">
        </a-entity>

    </a-scene>

  </body>

</html>
```

## Running Our App
In order to run our app locally we'll use the serve script we downloaded earlier.  
- Open a terminal window and navigate to your project folder.
- navigate into the serve folder:
```
cd serve
```
- Install the required node modules:
```
npm install
```
- Go back to the project folder:
```
cd ..
```
- Run the serve script:
```
Windows : 
    serve\bin\serve.bat -d {MyProjectName}
MacOS :
    ./serve/bin/serve -d ./{MyProjectName}
```
- Scan the QR on your mobile, and proceed past the security warning (It's our app so it's fine). You'll also have to give camera permissions to the browser.

You should now be able to see your app up and running!

![AR Boxes!](https://i.imgur.com/uOl6GTo.png?1)

It might not look like much, but we've created our first AR Web App! And all great things must start somewhere!  

Once again I'd recommend taking a look at [the docs](https://aframe.io/docs/0.9.0/core/component.htm) to see what other kind of primitives we can use to make something cool in our scene using just the basics.

I hope you enjoyed this look at 8th Wall and A-Frame. If there is interest I'll continue with this series and cover importing custom models ( No more boxes! ) as well as using some animations and interactions.

The final code is available here:  
{% github mattbibby95/ARWebTut %}