Augmented Reality with JavaScript
Our reality is termed as Augmented Reality when it is supplemented with computer-generated interactive objects or graphics. Virtual Reality, on the other hand, is constrained within the application to provide an immersive experience. When Oculus VR released its VR headset, Oculus Rift, it sure did flood YouTube with hilarious videos — I even remember tweeting about it
Although VR headset caused headaches, neck pain, and occasional property damage, it educated the community of possibilities with virtual reality. It also was a perfect segway into selling the vision for Augmented Reality. In the recent past, Google spearheaded AR solutions with Google Glasses and after a fair share of criticism and privacy concerns, it lay the glasses to rest and resurrected the product again in 2017 as ‘Glass Enterprise Edition’. Furthermore, Microsoft has jumped in on the AR action as well with Microsoft HoloLens. Clearly, AR is here to stay at least to cater the enterprise crowd. As AR content and use cases become generic and relatable to the general population, it will gain traction and adaptation. With that, introducing to you an AR JS library — AR.js
AR.js is a blazing fast, open source library which uses WebGL and WebRTC. AR.js leverages existing open source JS libraries such as three.js, A-Frame, babylon.js, and ARToolkit.js which is port from ARToolKit, the native library.
AR.js providers wrappers for A-Frame and babylon.js –
- A-Frame — aframe-ar
- babylon.js — babylon-ar
Our primary focus will be on A-Frame and aframe-ar wrapper library. But before that, what is A-Frame, babylon and three?
A-Frame is a three.js framework which provides a declarative, composable and reusable entity-component structure.
Bablylon.js is a 3D engine based on webGL and Javascript.
Three.js is a JavaScript library for 3D models.
The wrapper libraries from Jerome Etienne inject the 3D models generated from A-frame, Babylon and Three into our reality, thus producing Augmented Reality. Alright, it’s time to code. In a previous post Mapbox GL JS, we developed an application ISS Finder which tracked the International Space Station. What if the 2D map can be transformed into a 3D model and be shown as augmented reality? Sounds like a perfect visual for a sci-fi movie. We already have the tools, so lets built it!
Clone a copy of the implementation to follow along.
Include A-Frame and aframe-ar.
<script src="vendor/aframe.js"></script>
<script src="vendor/aframe-ar.js"></script>
Building off from ISS finder project, the first step is to convert the 2D output into 3D models using A-Frame. A-Frames declarative approach makes that a breeze.
First, include a scene.
A scene is represented by the <a-scene> element. The scene is the global root object, and all entities are contained within the scene. Read more.
Add ‘arjs’ as an attribute so that AR.js picks up the scene.
<a-scene embedded arjs="trackingMethod:best;">
//Scene contents
</a-scene>
Create an anchor entity to host all entities.
A-Frame represents an entity via the <a-entity> element. Entities are placeholder objects to which we plug in components to provide appearance, behavior, and functionality. Read more.
<a-anchor hit-testing.enabled="true">
<!--Include Entities-->
</a-anchor>
Now that we have the base template, the fun begins. The approach is to create a sphere entity and set its src attribute to the map image retrieved from the canvas rendered by Mapbox GL JS.
<a-sphere id="sphere" position="1 0.5 0">
</a-sphere>
When Mapbox GL JS map loads –
map.on('load', function () {
let canvas = document.querySelector("#map canvas"),
image = canvas.toDataURL("image/png"),
sphere = document.getElementById("sphere");
sphere.setAttribute("src", image);
});
Fire up the index.html and point a HIRO marker at your camera — voilà — Augmented Reality.
Add in a spin to the sphere with <a-animation>
<a-animation attribute="rotation"
dur="10000"
fill="forwards"
to="0 360 0"
repeat="indefinite">
</a-animation>
To meet parity with the 2D version of ISS finder, details pane has to be included. In the A-Frame world, it maps to a text entity.
<a-entity id="detailsEntity" position="-1 1.5 0"
geometry="primitive: plane; width: auto; height: auto"
material="color: steelblue"
text="value:">
</a-entity>
If the alignment of the sphere or text pane does not align well with your satisfaction, play around with the position property. You may also use A-Frames Visual Inspector for visual assessments.
Demo
This post was inspired by Allan Walker’s implementation. His article was so engaging that I had to put a spin on it.
References:
Augmented Reality for JavaScript Developers
Microsoft HoloLens: what it’s really like
https://aframe.io/docs/0.7.0/introduction/#getting-started
https://blog.x.company/a-new-chapter-for-glass-c7875d40bf24
https://github.com/jeromeetienne/AR.js
Originally published at javascriptstore.com on December 20, 2017.