Augmented Reality: create an interactive business card using Mind AR and A-Frame JS.
Blog, Pitang.
Pitang Labs
Augmented Reality: create an interactive business card using Mind AR and A-Frame JS.
Development
The Technical Break on Augmented Reality is now live!
Below is the tutorial for creating the Business Card in text format:
What are Mind-AR and A-Frame?
A-Frame is a framework that allows the creation of virtual scenes using HTML, enabling the creation of augmented reality (AR) and virtual reality (VR) experiences, providing full access to the three.js API.
MindAR is an Open Source JavaScript augmented reality (AR) library for the web that supports image tracking and face tracking, utilizing the GPU (via WebGL) and web workers to boost performance.
Initial Setup
For this project, we will need an index.html that will contain the application's main code for building and displaying the virtual scene. In addition, some graphic assets will be required, such as the target and the virtual elements that will be part of the AR experience. Thus, we structure the directory as follows:
Creating the Target
We will create the business card that will serve as the trigger for displaying our application's interactive content. When creating yours, it is important to take into account aspects that ensure as many feature points as possible, which allow greater accuracy during real-time target detection and tracking. MindAR provides some tips so you can design or choose images for this purpose. We provide the following canvas template that we will use:
We will use the Image Targets Compiler to turn the Business Card into a target. This compilation will return a targets.mind file that stores the feature point data in a compact format. Save your business card image in PNG format and the compiled file in the targets folder.
In index.html, we will need to import three libraries that will enable the application implementation using MindAR together with A-Frame. To import via CDN, add to the head of your index.html: mindar-image.prod.js, mindar-image-aframe.prod.js, and aframe.min.js. So the initial code might look like this:
<title>My Business Card - Jane Doe</title> </head>
<body> </body> </html>
Creating the Scene
We will begin by creating the scene, the a-scene, which is the global object of our application. In it, we will specify some properties according to the MindAR documentation and also add all the elements that will compose the scenario.
mindar-image: to specify the path to the compiled target.
color-space and renderer: these are two optional properties that ensure higher quality when rendering graphic elements.
vr-mode-ui: will be included to disable the button that allows access to the virtual reality experience.
device-orientation-permission-ui: will be disabled to avoid displaying dialogs requesting access to certain device orientation events.
Adding Elements to the Scene
Inside a-scene, we will import our assets using the a-assets tag. In it, we can place images, 3D objects, audio, and videos. For each imported element, we must specify a unique ID, which is how this element will be referenced later, and the src attribute that will contain the path to the item, as shown in the examples below.
Since we will be inserting images into our application, we will need the img tag. Let's add our first content, which is the image of the business card you created.
In order to display our first content, we need the a-entity tag, which will enable the insertion of components that provide appearance, behavior, and functionalities.
As a tag attribute, we need to specify the path to the target that needs to be detected and tracked in real time. This is done through the mindar-image-target="targetIndex: 0" property. The targetIndex: 0 indicates the index of the compiled image.
Note: It is possible to compile more than one image together. In this case, the targets will be referenced considering the order in which the images were placed in the image targets compiler.
<a-entity mindar-image-target="targetIndex: 0" >
</a-entity>
Inside a-entity, we place the content we want to display. Since it is just an image, using the a-image tag, we specify the following attributes:
id: unique element identification
position: considering the x, y, and z coordinates, we can position the image at the center with the values 0, 0, 0.
height: height of the image
width: width of the image. Whenever we set 1, we are indicating that it should match the target's width in the physical environment.
src: identifier of the item that was loaded in the a-assets tag.
Let's run it using Live Server in your VS Code. After installing the extension, right-click on the index.html file, and select the option Open with Live Server, and the web page will be launched.
Adding Interactions
We can start placing the rest of the items in a-assets. To do this, download these icons and put them in the icons folder, and insert a photo of yourself, preferably with dimensions 980 x 980, in the profile folder. You can use our canvas template to place the image according to the design proposed for this application.
After importing the elements into a-assets, we will organize our code better by grouping the business card image and the photo inside an a-entity. In the code, we adjust the positioning, height, width, and scale of the images to match the created design.
Tip: If you want to visually adjust some parameters, you can use the A-Frame inspector tool using the shortcut <ctrl> + <alt> + i.
Next, let's insert an a-entity containing five a-image tags referring to the buttons for websites and social networks. Experimentally, we adjusted the positions of all the buttons and of the entity that groups them together, as shown in the code below.
Optionally, we added an animation via the animation property. The animation occurs by scaling up the size of the icons in an alternating direction. For more information and customizations, refer to the official documentation of A-Frame.
The scale increases and decreases slightly, but to clearly illustrate how the animation occurs, we adjusted one of the icons to a larger scale as shown in the GIF below.
Figure 5: Animation on the buttons
After adding the buttons to the scene, we need to allow interactions through clicking. To do this, we must insert the cursor and raycaster properties into the a-camera tag.
In raycaster, we specify that all objects with the .clickable class will be clickable. Therefore, for all icons, we must add the attribute class=”clickable”.
To enable interactivity, the raycaster casts a line from the location where the user clicks into the scene. Thus, if any interactive object—that is, one with the .clickable class—lies in the path of the line, the click event will be triggered.
Now we need to create the script that adds the behaviors resulting from clicking the buttons. To do this, let's import the index.js file into the head of index.html as follows:
The defer attribute will prevent the script from executing until the HTML page is ready.
In the JavaScript file, we need to "listen" for the click events for each button. To select the elements, we can use the document.querySelector() method, specifying the id corresponding to each object, according to the code below.
After selecting the elements, we can attach the click events using the addEventListener() method. In the method, we need to implement the function that will execute when this event is fired. In our application, each button will open a specific web page in a new window or tab. Set the URL for your accounts and web pages.
If we run the application, we can observe element jitter at times. This is considered a common issue in AR applications, due to factors such as noise coming from the camera.
To solve this problem, we can adjust the filterMinCF and filterBeta parameters. Technical information can be found in the official documentation of MindAR. But, generally speaking, by decreasing the filterMinCF value we reduce jitter, and by increasing the filterBeta value, we reduce latency/delay.
The default values for filterMinCF and filterBeta are 0.001 and 1000. Experimentally, we modified these values in the mindar-image attribute to reduce jitter without significantly increasing delay.
We can observe through the following GIF that jitter was substantially reduced, ensuring a better user experience.
In the end, your complete project might look similar to the code found in this repository.
Deployment
To complete our tutorial, we will deploy to the Vercel platform using the following steps:
Create a repository on your GitHub to place your code;
Sign up on Vercel, preferably using your GitHub account;
Create a new project on Vercel;
4. Import your GitHub account
5. You can grant access to all repositories or only to the one you just created;
6. After installing and selecting the repository, click the Import button;
7. If you want, change the project name, then select the deploy option and wait.
8. A new page will open, indicating that the deployment was successful.
9. Click on the blank window to open the site or press the Go to Dashboard button to view status, domains, etc.
10. On your business card, change jane.com/card to the URL generated by Vercel. Then, repeat the target compilation procedure with the new image and replace it in your project.
11. Finally, push to GitHub and wait, as Vercel will update the page with the new changes.