Using Glitch, the School will give you step-by-step exercises to help you jump into WebVR! The School has sections going ← and → but also subsections going ↑ and ↓:
Navigate ↓
- Skim through the docs and FAQ
- Get help from peeps on Slack
- Ask questions on Stack Overflow
- If you are in a live workshop event, please raise your hand if you have a question!
Navigate →
The School uses Glitch as your learning and development environment for A-Frame.
- Glitch lets you code in the browser without having to set anything up
- Glitch lets you remix projects to use existing A-Frame projects as a starting point
- Glitch instantly publishes and hosts your site with a URL (e.g.,
https://aframe.glitch.me) - Glitch updates your A-Frame site live on every code change
- Glitch lets multiple people code on the same project
If you are interested in setting up a local development environment, skip ahead ↓
Glitch lets you remix or fork an existing project and use it as a base for your new project. Before starting, we recommend linking Glitch to a GitHub account. After you remix, Glitch will give you a random project and URL name, which you can change.
Remix the A-Frame Starter Glitch
Once you've remixed the A-Frame Starter Glitch, check out where you'll be editing your code. Poke around and see that you can even edit the backend server code, upload assets, create new files, or invite others to edit with you!
After you've poked around the editor, see the project live.
At any time, if you want to download your project or export to GitHub, see the Advanced Options menu. Downloading will give you a
.tgzfile which you can unzip. For A-Frame projects, you mostly care about what's in thepublic/folder, and ignore all the server-side code.
If you download a project, you might be interested in setting up a web development environment in the next section ↓. Else, head → to start with A-Frame!
You can set up a full web development environment on your local machine, rather than use Glitch's online web development environment.
- Get a text editor: VS Code is a good one to start with
- Set up a local server: Download and run Mongoose
Server or run
python -m http.serverin a terminal - Create a file
index.htmland copy A-Frame code from the Glitch samples - Run a local server in the same directory as the HTML file
- Open the local server's URL in your browser (e.g.,
http://localhost:8000) - Make changes to your HTML file and refresh your browser to see the changes
- Optional: check out ngrok to let any device on any network have access to your local server
VS Code is a good text editor to start if you don't have one. Other popular options are Notepad++, Sublime, Brackets, or vim.
You'll need a local HTTP server to serve your files to the browser.
Optionally, you can use ngrok to help develop your A-Frame project on a smartphone without having to do the local IP address dance.
- Download and unzip ngrok anywhere
- Run ngrok, providing it the port number of your local server (
./ngrok http 8080) - In the output, ngrok will give you a URL with a bunch of letters and numbers (e.g.,
https://abcdef123456.ngrok.io) - Open that URL on another device on any network (such as a smartphone or another computer)
Play with examples on your desktop or smartphone from the A-Frame Homepage, A-Frame Blog, or awesome-aframe. See webvr.rocks for information on setting up WebVR with a headset if you have one.
A-Frame provides easy-to-use HTML elements for starters called primitives. In the sections below, we'll modify basic meshes through HTML attributes (e.g., change colors, positions, rotations, scale) and get a feel for the workflow.
Position defines where objects are in 3D space (X, Y, Z) in meters. Change the
positionof the objects via thepositionHTML attribute values. Read about positions.
- Move the cylinder left by decreasing the
position's X value - Move the box up by *increasing * the
position's Y value - Move the sphere back by decreasing the
position's Z value - Extra Credit: Add
<a-ring>as a child of<a-sphere>and give it a position to see relative positions
Rotation defines orientation of objects in 3D space (about the X, Y, Z axes) in degrees. Use the right-hand rule to spatially visualize rotation. Read about rotations.
- Rotate the cylinder around the X axis so we see the bottom
- Rotate the box around the Y axis so the box is facing straight
- Extra Credit: Wrap the scene contents in
<a-entity>(like a<div>) and give it a rotation to see relative rotations
Add primitives the scene by adding HTML elements under
<a-scene>. Read about primitives.
- Add
<a-torus-knot>to the left - Add
<a-dodecahedron>to the right - Add
<a-text>aligned in the center
We'll be adding image textures to meshes to more appearance than a flat color. Find your own images online, and upload them through the assets section in Glitch or through the uploader on cdn.aframe.io. Wherever else you may upload, make sure it's being served with CORS and over HTTPS.
In the Glitch below ↓, some assets will already be provided in the assets section (pictured above).
Fill in the
srcHTML attributes with image URLs. Read about applying an image texture.
- Add an image texture to the ground,
<a-plane> - Add image textures to
<a-box>es - Add an image texture to
<a-sphere> - Add an image texture to
<a-cone> - Add an image texture to the background,
<a-sky>. Find 360° images from FLickr
Hit
<ctrl> + <alt> + ion any A-Frame scene to pop open a visual editor, just like your browser's Dev Tools! Try the Inspector on some of the homepage examples. Read about the Inspector.
Modify an entity by modifying its components on the right-hand panel. The Inspector knows about all A-Frame components, including community components. This example includes an external text-geometry component, which the Inspector can modify the values of live.
- Select one of the entities with text in the example
- Change the
text-geometrycomponent'svalueproperty
Use physics components from the Registry to add gravity and collisions. The Registry is a curated collection of A-Frame components. And the Inspector is hooked up to the Registry so we can add components from the Registry in the entity panel.
- Add the
static-bodycomponent to ground grid - Add the
dynamic-bodycomponent to the torus knot (the purple pretzel in the back) - Increase the Y-position of the torus knot to make it higher up
- Exit the Inspector
Behind the easy-to-use primitive elements, A-Frame is based on an entity-component architecture. Decompose the primitive elements in the Hello, WebVR example to
<a-entity>s with their fundamental components.
- Convert
<a-box>to<a-entity>with geometry component and material component. Configure the geometry component to beprimitive: box - Convert
<a-sphere>to<a-entity>with geometry component and material component. Configure the geometry component to beprimitive: sphere - Convert
<a-cylinder>to<a-entity>with geometry component and material component. Configure the geometry component to beprimitive: cylinder - Convert
<a-plane>to<a-entity>with geometry component and material component. Configure the geometry component to beprimitive: plane - Convert
<a-sky>to<a-entity>with geometry component and material component. Configure the geometry component to beprimitive: spherewith a largeradius: 3000, and configure the material component to beshader: flatso we don't do expensive lighting calculations when we just need a flat color
Use the entity-component pattern to add a sphere that also acts as a point light source. Mix together the geometry, material, and light components to compose this type of object.
- Look for
<a-entity id="lightSphere"> - Attach the geometry component configured to use
primitive: sphereto the entity - Attach the material component configured to use
color: #FFFandshader: flatto the entity - Attach the light component configured to use
type: pointto the entity - Extra Credit: Add the animation component from the Registry via a
<script>tag. Attach the animation configured to useproperty: positionanddir: alternateandloop: trueand provide a position value forto: <POSITION>
The Registry is a great place to grab cool components that the community has added to A-Frame. Sort of like third-party plugins. Find community components from the Registry, copy their JS links, include them via a
<script>tag, and use them straight from HTML.
- Include Particle
System. Attach
<a-entity>s withparticle-systemcomponents configured topreset: defaultandpreset: snow. Open the Inspector to play with the values! - Include Animation. Attach
animation to the sphere to throb its scale by configuring
animationcomponent withproperty: scale,loop: true, andto: 1.1 1.1 1.1 - Include Outline Effect. Drop in the
<script>and attach theoutlinecomponent to the scene
Use JavaScript and DOM APIs to programmatically modify the scene and its entities. A-Frame is not just HTML; A-Frame provides access to JavaScript, DOM APIs, and three.js underneath for full control. Read about Using JavaScript and DOM APIs with A-Frame.
To see JavaScript logs, we can open the browser's development console by right-clicking the page, clicking Inspect or Inspect Element, and then clicking the Console tab. When viewing solutions, we can see the results through the browser console.
Use
document.querySelector()anddocument.querySelectorAll()to get a reference to the scene and its entities. Read about querying for entities.
- Get a reference to the
<a-scene>element usingvar sceneEl = document.querySelector('a-scene'); - Get a reference to all
<a-entity>elements usingsceneEl.querySelectorAll('a-entity'); - Get a reference to the box entity using
sceneEl.querySelector('#box'); - Get a reference to the sphere and cylinder entities in one
.querySelectorAll()call by using multi-element selector . Get a reference to the sphere and cylinder entities in one.querySelectorAll()call by adding and selecting HTML classes
Use
Entity.setAttribute()to modify entities after retrieving them from the previous exercise. Read about modifying entities.
- Change the box entity's
rotationcomponent - Change the cylinder entity's
geometrycomponent'sheightproperty - Change the sphere entity's
materialcomponent'smetalnessproperty
Use
document.createElement()to create entities,.setAttribute()to configure them, and.appendChild()to add them to the scene. Read about creating entities.
- In a JavaScript
forloop, create and add 50<a-box>elements with random positions and scales (useMath.random())
Use
.addEventListener()to register a handler function that will be called when an event is emitted. Then manually emit that event to see that handler function execute. Later we can use event listeners to change the scene based on user input or other events. Read about events and event listeners with A-Frame.
- Register an event listener on the box to listen to the
fooevent. In the handler function, change the box's color - Emit the
fooevent withEntity.emit()and see the box change its color
Use the gaze-based
cursorcomponent to provide the ability to interact with entities (primarily for smartphones). Read about building a 360° image gallery.
This lesson has all the event listeners hooked up already. We just need to add
an entity with the cursor component which will provide those events based on
user input. Note these events are not provided by the browser, but through
A-Frame.
- Add
<a-camera>entity. Previously A-Frame was providing a default camera - Add
<a-cursor>entity as a child underneath the camera entity - Drag the camera around the click on the panels on desktop. On smartphones, stare at the panels to trigger clicks (i.e., gaze-based)
Use the
click,mouseenter,mouseleaveevents provided by the gaze-basedcursorcomponent to change the properties of an object.
The Glitch code will have the project structure set up. We can add JavaScript
code inside the handle-events component, marked by the code comments.
- Attach our
controller-event-handlerto the cubes. We can attach to all of them at once through the mixin - Add an event listener to change the box's color on
mouseenterevent - Add an event listener to restore the box's color on
mouseleaveevent
3D models are like the images of 3D and VR applications, although a bit heavier. A 3D model is created beforehand in a 3D modeling program such as Blender and consists of vertices, textures, materials. We recommend using glTF, a relatively new 3D file format standard tailored for the Web. glTF is like the JPG of 3D models.
- Add the
https://cdn.aframe.io/test-models/models/virtualcity/VC.gltfto the<a-asset-item id="cityModel">'ssrcattribute to preload the model - Add
#cityModelto the<a-gltf-model>'ssrcattribute to set and add the model
Models can come with animations. The model provided above has many animations of ships zooming across the city. In the previous Glitch, we've provided a simple
play-all-model-animationscomponent that we can attach to our model to play its animations. Continue working from your current Glitch.
- Include the
animation-mixercomponent via a<script>in the<head>after the A-Frame script. This component is currently in the Registry, and may one day be included with A-Frame.https://unpkg.com/aframe-extras.animation-mixer@3.4.0/dist/aframe-extras.animation-mixer.js - Attach the
animation-mixercomponent to the<a-gltf-model>by setting it via an HTML attributeanimation-mixer. By default, this will play all the animations of the model at once.
If you have a model of your own, it can be tricky to upload it to a CDN since it consists of multiple files that reference each other. So far the easiest way we've found is to dump them into a GitHub repo, publish the repo's master branch to GitHub Pages, and use
rawgit.comto serve them. Alternatively, set up Amazon S3. More to come.
Tracked hand controls provide immersion and interactivity with hand controllers. In the following Glitch, we've pre-recorded hand control movements and button presses with A-Frame Motion Capture. Now we just have to add the hands and handle the interaction events.
- Find
<a-entity id="left">and add the hand-controls component configured to the left hand (hand-controls="hand: left") - Find
<a-entity id="right">and add the hand-controls component configured to the right hand (hand-controls="hand: right") - View the result and see the hands moving with pre-recorded motions
There are many components to add interactivity to hand controls. controller-cursor, aabb-collider + grab, super-hands. For this lesson, we'll use controller-cursor that acts as a pointing laser for each hand. Continue from your previous Glitch.
- Add
controller-cursorcomponent to both hands - In the
controller-event-handlercomponent, change the color of the boxes when they are hovered over with themouseenterevent, and restore the color with themouseleaveevent
You've graduated from the A-Frame School and now have a virtual uncertified degree in WebVR.
Head to the documentation for more guides to become a master.