A-Frame VR for Browsers

Whilst listening to the Software Engineering Daily Postcast this week I heard a really good episode entitled "Modern Front End: React, GraphQL, VR, WebAssembly with Adam Conrad" (well worth a listen if interested). Amongst a host of other things talked about the rise of front end VR Javascript frameworks (particularly React 360 and A-Frame). I was particularly tempted by the description given of VR JS as being a "little like the web in the 90s" - in that it's a creative space without well defined rules, a bit like the web was in the days of Geocities before everyone grew up and decided on clear rules and style guides to give the well manicured pages we have today.

As anyone who has seen a website I've built will testify, I don't do "well manicured" (although I don't have scrolling text, 'under construction' animated gifs or anything like that!). So I thought it might be fun to do some hacking like I used to do when I was a teenager, and this blog describes what what I found in my first 24 hours playing in this new Wild West of the Web (or WWW if that TLA isn't already taken).

Step 1: Choose a framework

I selected A-Frame (partly on a whim, and partly as I don't know any React so I thought documentation might make fewer assumptions about base knowledge). Looking at the A-Frame Examples page it looks like there's a fair bit you can do with it.

Step 2: Hello World

There is nothing to install (it's Java Script after all) so I opened VS Code and tried to make a new page.

I followed the Building a Basic Scene template and got up and running fairly fast. A couple of slight niggles

  1. There doesn't appear to be a completed html page to check your work against in case you've missed anything. Also a lot of the examples use v0.5.0 and even when examples show a newer version the 'try this' seems (upon inspection through Chrome) to be using the older version (this made debugging harder when I hit a version issue - see below).
  2. Images don't work if they're not hosted on a webserver (the page makes this plain) but as I was merely loading file:///something.html into Chrome.

Step 3: Building something real

I decided to re-build my ageing (and as mentioned above - not particularly nice looking) home page as a go at doing something "real". The page is essentially 'something' to have at my vanity domain so it doesn't have nothing if anyone visits it. It has a few links to my online presence (photos, CV, Twitter etc). So it's very simple.

I took apart my basic scene and fairly rapidly managed to get more cubes to fill the landscape and give myself something to work with. The only real problems came in getting the links to work. There is an a-link primitive but it puts a rather ugly circular portal in the scene rather than what I wanted, and most of the examples given do things within the same page (e.g. animations spinning a cube) - so I needed to add some JavaScript to capture the click event for whichever component was clicked on like this:

AFRAME.registerComponent('link-click', {
schema: {
target: { type: 'string' },
on: { type: 'string' }

init: function () {
var data = this.data;
var el = this.el;

el.addEventListener(data.on, function () {
console.log("Clicked:" + data.target);
window.location.href = data.target;


Then for each entity we add this attribute to the a-entity tag (replacing the text as needed):
link-click="on: click; target: SOME-TARGET-URL"

This worked and I even added floating text below the images to make it clearer, a little like this
<a-text font="kelsonsans" value="CV" width="2" wrap-count="10" position="-3 0.5 -5" rotation="0 0 0" align="center"></a-text>

Step 4: Flying in Cardboard

One of the nice things about working with A-Frame is that it includes support for VR headsets as standard with a button to click (if running on a mobile device) to enter split screen mode on a VR device. I'm cheap, so I've got a Google Cardboard style holder for my mobile phone rather than a pro VR headset but it's enough to give it a go. It works well except:
  1. Using A-Frame v0.5.0 (as the examples do) means on Android/Chrome the image jumps around like crazy - it seems to be hyper sensitive to the motion sensors on the phone. It worked fine on iOS Safari but I had to upgrade to A-Frame 0.8.2 to fix this on Android. Seems the libraries are ahead of the examples.
  2. The split screen is too far apart to allow me to get the images to focus on Chrome - I tried to find settings for this or re-calebrate (the phone works fine for the Android cardboard app) so in the end I installed Firefox for Android and it worked fine! 

Step 5: Visual Inspector

A-Frame offers a GUI called Visual Inspector which I tried to install but when I cloned the git repo and tried to do an NPM install it gave a screen full of red errors - I'll look at this when I have some time but sadly in my first day on the job this has defeated me.


Overall I've been really impressed by my one day creating a very simple 3D world in A-Frame and hopefully it won't be my last experience (in fact I have another idea already in mind).

If you're interested to see my new landing page, it's at: http://jameslees.net and my old 2D website (in case you want to see the horror of it) is at http://jameslees.net/index-old.html.

Or for a static image it looks a bit like this: