Category: WebVR

If you’re interested in building virtual reality experiences for the web, then one of the most approachable ways to go about it is to use a framework like A-Frame. A-Frame makes it really easy to get started with WebVR, it’s an active, well-managed project with a vibrant and growing community, and it’s very fun to use and play around with.

What is A-Frame?

A-Frame is a web framework designed to make WebVR content creation easier, faster, and more accessible. A-frame was started by Mozilla, and has been around since mid-2015. From the A-frame documentation:

A-Frame lets you build scenes with just HTML while having unlimited access to JavaScript, three.js, and all existing Web APIs. A-Frame uses an entity-component-system pattern that promotes composition and extensibility. It is free and open source with a welcoming community and a thriving ecosystem of tools and components.

If you’ve never used it at all, here’s a super-minimal “Hello World” example. It uses a declarative HTML-type syntax as seen below:

At the top there’s a link to the A-Frame script, then the <a-scene> element encompasses everything in the WebVR scene, the same way that the <body> element encompasses everything the uses sees in a web page.

Inside the scene there is an <a-box> element which makes–you guessed it–a box appear in the scene. The box has attributes that describe how it should appear, including its position within the scene, its rotation, and its color.

The <a-box> element is a built-in primitive provided by A-Frame. The rest of this post is going to focus on how to build your own reusable components that don’t already exist in A-Frame, how to build your own building blocks in a sense. If this is truly your first time using A-Frame I recommend that you play around with it a little bit to get a feel for it.

Build Your Own Components

Once you’re up to speed with building basic scenes using built-in components and primitives like boxes, spheres, cylinders, etc. you will reach a point where you might want to build your own custom components that you can use in your projects, and even share for others in the community to use.

For a simple example, here’s a “clock” component showing the current time. Next we’ll walk through how it’s built, step-by-step.

Register Your Component

The first thing you need to do is let A-Frame know about your component by registering it. You do this with AFRAME.registerComponent(), as seen below:

Register your component

JavaScript

1

2

3

4

5

AFRAME.registerComponent('clock',{

// component code goes here

});

AFRAME.registerComponent() takes two arguments, the first will be the name of your component, and the second is an object that represents your component itself, containing all of its properties and methods.

Component Lifecycle Methods

A-Frame provides a number of lifecycle methods for your component. These are built-in methods that will automatically get called at certain times, like when it is first initialized, or when its properties are changed. This is where you make your component “do stuff”. In this case we’ll be using the init() and tick() lifecycle methods.

Lifecycle methods

JavaScript

1

2

3

4

5

6

7

8

9

10

11

AFRAME.registerComponent('clock',{

init:function(){

// this code runs when the component is first initialized

},

tick:function(){

// this code gets run on each render loop

// so typically 30 to 60+ times per second

}

});

First, we’ll take a look at init().

Hello World

Here’s how you can create a text element and add it to the scene (add it to the DOM).

One great thing about A-Frame is, if you are a web developer and are used to working with the DOM, everything pretty much works the way you would expect. For example, creating an element, appending it to another element, and adding a text value, as seen below:

JavaScript

1

2

3

4

5

6

7

8

// create a new <a-text> element

this.clockEl=document.createElement('a-text');

// append it to the component's main element

this.el.appendChild(this.clockEl);

// now set the 'value' attribute

this.clockEl.setAttribute('value','Hello World!');

You can now add the Hello World text to the scene with <a-entity clock></a-entity>. Congratulations, you’ve now built your first component!

In the Codepen above I have also given the entity a position since otherwise it would be at the origin (0, 0, 0) position in the same place as the camera, which would make it hard to see.

Passing in properties

What’s the fun in having a reusable component if you’re only going to have one instance of it, or if all instances will be exactly the same? Let’s make it so that we can pass in some properties and customize each instance of the component.

To do that we will use the schema. The schema is an object that defines the properties for your component. In other words, the schema tells A-Frame what properties to expect to be passed in and what data types (or “property types”) those properties will be. It also lets you define default values in case any of those properties aren’t passed in.

a schema

JavaScript

1

2

3

4

5

6

7

schema:{

position:{type:'vec3',default:{x:-.75,y:1.75,z:-1.75}},

color:{type:'color',default:'#0f0'},

font:{type:'string',default:'monoid'}

}

This schema is saying that we can expect a position, a color, and a font to potentially be passed in, that the types of these properties will be vec3, color, and string respectively, and then setting a default value for each.

Once they are defined in the schema, we can access each of these properties via the component’s data object, allowing us to easily grab these values and set them for our component instance using setAttribute().

setAttribute

1

2

3

4

5

6

7

8

9

10

11

12

13

init:function(){

this.clockEl=document.createElement('a-text');

this.el.appendChild(this.clockEl);

//get the position that was passed in, and set it on this instance

this.clockEl.setAttribute('position',this.data.position);

//get the color that was passed in, and set it on this instance

this.clockEl.setAttribute('color',this.data.color);

//get the font that was passed in, and set it on this instance

this.clockEl.setAttribute('font',this.data.font);

this.clockEl.setAttribute('value','Hello World!');

}

Now when you add the component to the A-Frame scene, you will pass in the position, color, and font like so:<a-entity clock="font: sourcecodepro; color: #191; position: -1 1.5 -.75"></a-entity>

Make time for making time

We’re actually getting pretty close here, now that you know how to register your component, build your component by adding elements to the DOM, use the built-in lifecycle methods, and use schema to define and pass in properties.

Two things still need to be done in order to turn this Hello World example into a working clock component: we have to get the current time, and then update it regularly. First let’s add a getTime() method to our component that will get a JavaScript Date object and return it as a formatted time string.

getTime() method

JavaScript

1

2

3

4

5

6

getTime:function(){

vard=newDate();

returnd.toLocaleTimeString();

}

Then we want to use the tick()lifecycle method to call getTime periodically and update the text element accordingly with the current time (tick() will be called every render loop, many times per second).

tick()

JavaScript

1

2

3

4

5

tick:function(){

this.clockEl.setAttribute('value',this.getTime());

}

With those last two pieces in place, we’ve got a fully working and reusable a-frame clock component, which you can instantiate like so:

Share this:

Over the past year or so I’ve been branching out from traditional web development and have become more and more interested in working with newer forms of digital media like Virtual Reality (VR), Augmented Reality (AR), and 360° video + photos which I want to focus on here.Continue reading “360: Exploring New Forms of Media”