I have a friend who’s birthday was coming up, so I wanted to do something special for her. As she is a TechGeek just like me, so I couldn’t just get her a simple birthday present like a teddy bear or chocolates. So, I started looking for unique ways to wish her a happy birthday on the Web.

I ended up watching a video where a guy was proposing to a girl using VR. So, I decided — that was it! That was how I was gonna do it. Not the proposal part though.

While I was contributing to Mozilla, I’d created few small VR projects using A-FrameMozilla’s web-framework for building virtual reality experiences. And believe me, even if you don’t know much about VR or AR, you can easily create a VR scene using A-Frame. The only prerequisite is HTML, which you can learn easily here. For a better understanding, though, I recommend that you go through A-Frame School, which is a great collection of tutorials intended for beginners.

So I’d decided that I was gonna use A-Frame, but I wanted more than just a simple VR scene displaying “Happy Birthday.” In the end, I chose to create an AR scene. I found a great project called AR.js. If you wanna get started with AR.js, here is a great article for beginners.

Building a basic AR web app

AR Scene, created using AR.js

To watch the AR scene, you have to:

  • Open this HIRO marker image in your desktop browser.
  • Open this AR web app in your phone browser, and point it to your screen.

When you scan a marker (here, a HIRO marker), it’ll display an AR scene on your phone, just like the image above. I used a plain HIRO marker, but you can create your own marker as well.

So, after adding all these libraries, my code looked like this:

Basic AR web app [ Demo ]

Please note that while accessing any AR web app, if you get any prompt asking permission to access the webcam, please allow it. Otherwise the app won’t work.

Add 3D models and fonts

So, now we have simple AR web app working on our device. But what’s a birthday without cake?! Fortunately, A-Frame supports three types of 3D models: glTF, OBJ, and COLLADA. Learn more about 3D models in A-Frame here.

I downloaded some 3D model files of cake from Google Poly. You can import any asset files in A-Frame using the <a-assets> tag. You can also import separate fonts, in case you want to use a different font.

I was pretty convinced that A-Frame couldn’t be more awesome. But, wait…

Add audio

Birthdays are also not complete without the birthday song, right? And A-Frame supports Audio files as well. You can use the <audio> tag to import your files, under the <a-assets> tag.

Import asset files

Add particles

What’s the thing that comes to your mind when you hear about a birthday — after cake, of course? A party, right? So, let’s add confetti to our AR scene, using A-Frame’s Particle System Component.

Add libraries for confetti and 3D text

Let’s put it all together

3D Models

This code will display the 3D model of the cake. But as you can see, I’ve added a few values in the rotation and scale fields. So, let’s discuss that. According to A-frame’s GitHub page:

  • Rotation: the rotation component defines the orientation of an entity in degrees. It takes the pitch (x), yaw (y), and roll (z) as three space-delimited numbers indicating degrees of rotation.
  • Scale: the scale component defines a shrinking, stretching, or skewing transformation of an entity. It takes three scaling factors for the X, Y, and Z axes.
  • MTL: stands for Material Library File (.mtl) Material library files contain one or more material definitions, each of which includes the color, texture, and reflection map of individual materials. These are applied to the surfaces and vertices of objects. Material files are stored in ASCII format and have the .mtl extension.
  • OBJ: a file format that was created as a simple way to import and export geometry from different 3D applications. This is a common file type used by many 3D design solutions.
  • Suggestion: If you don’t see your model, try scaling it down. OBJ models generally have extremely large scales in comparison to A-Frame’s scale.

If you’re wondering how I knew the exact values for rotation, well I didn’t. I used an amazing tool created by the Mozilla team called A-Frame Inspector, built for this purpose only.

To learn more about <a-obj-model>, visit this link.

Display 3D model of Cake


Well, this code may look overwhelming at first sight, but believe me, it’s not. We discussed Rotation earlier, but let’s talk about other fields as well:

  • Position: places entities at certain spots in 3D space. The Position takes a coordinate value as three space-delimited numbers.
  • Preset: preset configuration. Possible values are: default, dust, snow, rain. Here we chose default in order to display starts.
  • Color: describes a particle’s color. This property is a “value-over-lifetime” property, meaning an array of values can be given to describe specific value changes over a particle’s lifetime.
  • Acceleration Value: describes this emitter’s base acceleration.
  • Particle Count: the total number of particles this emitter will hold.
  • Direction: the direction of the emitter. If the value is 1, the emitter will start at beginning of particle's lifecycle. If the value is -1, the emitter will start at end of particle's lifecycle and work it's way backward.
  • Rotation Axis: Describes this emitter’s axis of rotation. Possible values are x, y and z.

To know more about A-Frame’s Particle Component System, visit this link.


Text and Audio

Well, you use can use <a-text> as well, but I decided to go with Text Geometry Component for more options. It’s used to generate text as a single geometry.

  • Material : The text geometry component defines just the geometry. We can apply any three.js material to the geometry.
<a-entity text="value: HELLO" material="color: red; src: #texture"></a-entity>

For more details, visit three.js’s documentation.

  • Text Geometry: string and font value. (you should edit the text in this part, otherwise you’ll end up wishing happy birthday to my friend ??)
  • Sound: defines the entity as a source of sound or audio.
  • Autoplay: describes whether to automatically play the sound once set.
  • Loop: describes whether to loop the sound once the sound finishes playing.
  • On: an event for the entity to listen to before playing sound.


Yes, you made it ? ? ?. You’ve created your first AR application. If you did everything correctly, you should now see something like the image below:

Finally, Happy Birthday Krupa!

If you like my work, please follow me on Medium @Pratik Parmar or add me on LinkedIn. Feel free to reach out to me on Twitter: Pratik Parmar or comment down below, in case you need any help.

Apart from Open-source contributions at Mozilla, I’m a Microsoft Student Partner and community member at GDG Baroda. I would like to thank Mozilla and the MozillaIN community for providing me a chance and the resources to learn about VR/AR and Open Source.

This is me, Pratik Parmar signing off till the next tech adventure. Over and Out…

[ Edit: Thank you Vikranth Kanumuru for drawing my attention that URL of source code was broken. It’s been updated now, please go ahead and try now. Keep coding, keep rocking ]