How to create a web-based VR experience with HTML-like tags?

Ankit Raj Gupta
6 min readFeb 29, 2020

--

Web technology is changing rapidly and we have arrived at a point where web-based virtual reality is a reality now :)

By design, A-frame is a very simple webVR framework. If you know HTML tags then you already know the A-Frame, because it uses HTML-like tags and attributes to create a VR experience.

This will be a short tutorial for beginners, covering all aspects of A-Frame library to give you an idea about its potential.

HTML-like tags

A-Frame calls them “primitives”. The code below will create a 1x1x1 box in a 3d world and place it 3 meters in front of the observer. It’s that simple.

<a-box color="orange" depth="1" height="1" width="1" position="0 0 -3" ></a-box>
A 1x1x1 3d box
A 3d box in A-Frame scene

Let’s get started

First, we need to create an HTML file, name it index.html and store it in any directory. Within your <head> section, include a link to the A-Frame.js library.

<script src="https://aframe.io/releases/1.0.3/aframe.min.js"></script>
index.html

Create a scene

Once we finish setting up our HTML file, it’s time to create a VR world. The<a-scene> element acts as a container for all the other a-frame primitive elements and settings.

<a-scene>
<!-- All your other elements -->
</a-scene>

Paint the sky

At this point, our creation has a plain white background, so let’s add a sky to it. As you can guess, A-frame also has <a-sky> for this very purpose.

<a-scene>
<a-sky color="#B5E8FF"></a-sky>
</a-scene>

Shapes & Camera

Now let’s add some shapes to our VR world, as A-frame has a couple of basic shapes in their library. In our scene, we’ll be using — <a-box>, <a-cone> , <a-sphere> , <a-plane> , <a-cylinder>

Out of the box, A-Frame provides some default shapes.
<a-scene>
<a-sphere color="#C73D6D" radius="0.5"></a-sphere>
<a-sky color="#B5E8FF"></a-sky>
</a-scene>

If you refresh your page you won’t be able to see anything change. Although the sphere is there, it’s at 0,0,0 axis exactly where the observer — or in A-Frame’s terminology — the camera is placed.

Now we have 2 options, either move these shapes away from the camera or move the camera’s position. Let’s move the camera. <a-camera> is the a-frame element that will help us here.

Let’s add a camera tag and position it 3 meters behind — Yes VR world uses meters as a unit, which sounds very unintuitive for designers. But when you think about it in a real-world context where a person is consuming your content on an Oculus Rift headset and using his arms for all kinds of interactions, it makes more sense to use some physical unit.

<a-scene>
<a-sphere color="#C73D6D" radius="0.5"></a-sphere>
<a-sky color="#B5E8FF"></a-sky>
<a-camera position="0 0 3"></a-camera>
</a-scene>
<a-sphere> element 3 meters away from the observer/camera

Now let’s add the remaining shapes to our scene.

A small note on positioning — In 3d world we have x(horizontal), y(vertical) and z(depth) axes. So in the above example position=”0 0 3" refers to x, y and z axes.

<a-scene>
<a-sphere color="#C73D6D" radius="0.5"></a-sphere>
<a-box width="1" height="1" depth="0.5" color="#58303E" position="1.1 0 0" ></a-box> <a-cone color="#4B89DD" radius-bottom="0.6" radius-top="0.1" position="-1 0 -0.2" ></a-cone> <a-cylinder color="#D34242" height="1" radius="0.2" position="-1.5 0 0.5" ></a-cylinder> <a-plane color="#FFFAF2" height="1.5" width="4" rotation="-90 0 0" position="0 -0.54 0" ></a-plane> <a-sky color="#B5E8FF"></a-sky>
<a-camera position="0 0 3"></a-camera>
</a-scene>
Here we have all our shapes.

Animation

A-Frame also gives you the option to animate these shapes by just passing animation properties as an attribute. Let’s rotate the box to 90 degrees on its x-axis in 1000ms duration.

...<a-box width="1" height="1" depth="0.5" color="#58303E" position="1.1 0 0" animation="property: rotation; to: 90 0 0; dur: 1500;"></a-box>...
A-Frame animation — rotating a box on its x-axis to 90 degrees

The A-Frame API documentation has a list of properties that you can animate. Here I’m sharing a few attributes that could make your animation a bit more interesting —

Properties

  1. delay: in milliseconds, how long to wait before starting the animation
  2. loop: how many times an animation should repeat. Pass true to make the animation loop infinite
  3. dir: which direction to go, possible values — “alternate”, “reverse”. Use alternate to create a seamless transition from and to.
  4. easing: To ease in and ease out. Check out all the options available for easing function.

To create multiple animations on a single object you need to give a name-space to the second animation attribute with double underscores (__). e.g. animation__2, animation__color etc. (remember that anything after __ is your own custom name, it could be anything).

...<a-sphere 
color="#C73D6D"
radius="0.5"
animation="property: position; to: 0 1.5 0; dur: 700; loop: true; easing: easeInSine; dir: alternate"
animation__color="property: color; to: #58303E; dur: 700; loop: true; easing: easeInSine; dir: alternate" >
</a-sphere>...
Here I’m animating the position and colour of the sphere.

Lights

A-Frame has a light component that you can add to your scene. Before you add any lights, please remember that when you add a light, A-Frame removes the default lights(an ambient and a directional light placed at the left side of the screen), which may leave your scene with a very dark environment. So whenever you add your own lights, make sure to compensate for the reduced light intensity.

To properly light up your scene, you need to understand the way light works in real-world situations. Most of the time we have an ambient light around us e.g. sunlight (through clouds) or a distant defused light source. Ambient light hardly casts any shadow, so if you just add an ambient light you will end up with flat-looking objects on your screen. To create a proper sense of depth, you need at least one directional light.

Directional (D) and Ambient light (A). Also, the colour of the light source can affect the overall appearance by changing the highlights and shadow colours.

Let’s add some light to our scene. For this task, we’ll be using <a-entity> element. It’s a placeholder element that has no appearance and can be used to plug in other components.

Add a warm ambient light

<a-entity light="type: ambient; color: #FFE9A0"></a-entity>

And an orange directional light to imitate sunset.

<a-entity light="color: #FFB783; intensity: 1" position="-10 1 1" ></a-entity>
Notice how the overall appearance has changed and the objects appear warmer on the screen.

Textures

Textures are a fun way to create some realistic-looking objects. For this example, I’ll be using the below image to create a wooden box.

Image by Pexels from Pixabay

In order to use an image file you first need to load it using <a-assets> element. After downloading the image, place it in your root directory (where your index.html file is located).

Load your assets just after the a-scene tag.

<a-scene>
<a-assets>
<img id="texture" src="wood-texture.jpg" />
</a-assets>
...

Once your assets are loaded you can use them by their ids in your src attribute (e.g. "#texture")

...<a-box
width="1"
height="0.5"
depth="0.5"
color="#A28886"
src="#texture"
position="1.1 1 0"
>
</a-box>
...
Wooden box

Here is the final piece on CodePen —

And here is the source code —

Conclusion

I think at this point, you would have enough of an understanding of A-Frame to create your own VR experience. A-Frame is a small yet powerful framework that can be used to create more complex VR content. You can create your own custom shapes as well as design your own 3d models and place them in your scene (A-Frame supports glTF and OBj files). Since it’s all DOM at the core, you can use JavaScript to add an event-driven aspect to your content.

Please let me know in the comment section if you want to know more about the A-Frame!

--

--

Ankit Raj Gupta

I design and code user experiences | UX Designer | Tech Enthusiast | Studying Interactive Media @ Sheridan College www.ankit.life