A-Frame

A web framework for building virtual reality experiences.
Examples
Find more examples on the homepage, A Week of A-Frame, and WebVR Directory.
Features
:eyeglasses: Virtual Reality Made Simple: A-Frame handles the 3D and WebVR
boilerplate required to get running across platforms including mobile, desktop,
Vive, and Rift just by dropping in <a-scene>
.
:heart: Declarative HTML: HTML is easy to read and copy-and-paste. Since
A-Frame can be used from HTML, A-Frame is accessible to everyone: web
developers, VR enthusiasts, educators, artists, makers, kids.
:electric_plug: Entity-Component Architecture: A-Frame is a powerful
framework on top of three.js, providing a declarative, composable, reusable
entity-component structure for three.js. While A-Frame can be used from HTML,
developers have unlimited access to JavaScript, DOM APIs, three.js, WebVR, and
WebGL.
:zap: Performance: A-Frame is a thin framework on top of three.js.
Although A-Frame uses the DOM, A-Frame does not touch the browser layout
engine. Performance is a top priority, being battle-tested on highly
interactive WebVR experiences.
:globe_with_meridians: Cross-Platform: Build VR applications for Vive,
Rift, Daydream, GearVR, and Cardboard. Don't have a headset or controllers? No
problem! A-Frame still works on standard desktop and smartphones.
:mag: Visual Inspector: A-Frame provides a built-in visual 3D inspector
with a workflow similar to a browser's developer tools and interface similar to
Unity. Open up any A-Frame scene and hit <ctrl> + <alt> + i
.
:runner: Features: Hit the ground running with A-Frame's built-in
components such as geometries, materials, lights, animations, models,
raycasters, shadows, positional audio, tracked controllers. Get even further
with community components such as particle systems, physics, multiuser, oceans,
mountains, speech recognition, or teleportation!
Usage
Example
Build VR scenes in the browser with just a few lines of HTML! To start playing
and publishing now, remix the starter example on
:

<html>
<head>
<script src="https://aframe.io/releases/0.9.0/aframe.min.js"></script>
</head>
<body>
<a-scene>
<a-box position="-1 0.5 -3" rotation="0 45 0" color="#4CC3D9"></a-box>
<a-sphere position="0 1.25 -5" radius="1.25" color="#EF2D5E"></a-sphere>
<a-cylinder position="1 0.75 -3" radius="0.5" height="1.5" color="#FFC65D"></a-cylinder>
<a-plane position="0 0 -4" rotation="-90 0 0" width="4" height="4" color="#7BC8A4"></a-plane>
<a-sky color="#ECECEC"></a-sky>
</a-scene>
</body>
</html>
With A-Frame's entity-component
architecture, we can drop in community
components from the ecosystem (e.g., ocean, physics) and plug them into our
objects straight from HTML:

<html>
<head>
<script src="https://aframe.io/releases/0.9.0/aframe.min.js"></script>
<script src="https://unpkg.com/aframe-particle-system-component@1.0.x/dist/aframe-particle-system-component.min.js"></script>
<script src="https://unpkg.com/aframe-extras.ocean@%5E3.5.x/dist/aframe-extras.ocean.min.js"></script>
<script src="https://unpkg.com/aframe-gradient-sky@1.0.4/dist/gradientsky.min.js"></script>
</head>
<body>
<a-scene>
<a-entity id="rain" particle-system="preset: rain; color: #24CAFF; particleCount: 5000"></a-entity>
<a-entity id="sphere" geometry="primitive: sphere"
material="color: #EFEFEF; shader: flat"
position="0 0.15 -5"
light="type: point; intensity: 5"
animation="property: position; easing: easeInOutQuad; dir: alternate; dur: 1000; to: 0 -0.10 -5; loop: true"></a-entity>
<a-entity id="ocean" ocean="density: 20; width: 50; depth: 50; speed: 4"
material="color: #9CE3F9; opacity: 0.75; metalness: 0; roughness: 1"
rotation="-90 0 0"></a-entity>
<a-entity id="sky" geometry="primitive: sphere; radius: 5000"
material="shader: gradient; topColor: 235 235 245; bottomColor: 185 185 210"
scale="-1 1 1"></a-entity>
<a-entity id="light" light="type: ambient; color: #888"></a-entity>
</a-scene>
</body>
</html>
Builds
To use the latest stable build of A-Frame, include aframe.min.js
:
<head>
<script src="https://aframe.io/releases/0.9.0/aframe.min.js"></script>
</head>
To check out the stable and master builds, see the dist/
folder.
npm
npm install --save aframe
require('aframe')
Local Development
git clone https://github.com/aframevr/aframe.git
cd aframe && npm install
npm start
And open in your browser http://localhost:9000.
Generating Builds
npm run dist
Questions
For questions and support, ask on StackOverflow.
Stay in Touch
And get in touch with the maintainers!
Contributing
Get involved! Check out the Contributing Guide for how to get started.
License
This program is free software and is distributed under an MIT License.
0.9.0
Performance improvements, WebXR support, Inspector updates!
We continued to battle test A-Frame to produce native-like VR experiences and
continue to add large performance gains. We have also introduced initial WebXR
support! Although the spec is heavily in flux and yet to have feature parity
with WebVR 1.1, we had A-Frame get a head start to help test it out and smooth
out the changes.
Major Changes
- Bump to three.js r101 on a branch with a few extra patches for WebXR support (f9f314).
- WebXR support (#3875).
- Remove
<a-animation>
in favor of new animation component (#3678).
- Remove
collada-model
component (#3866).
- Add
renderer.colorManagement
property (disabled by default) to accurately match colors against modeling tools, but may changes in scene colors when flipped on. renderer.gammaFactor
will be set to 2.2. Call scene.renderer.systems.applyColorCorrection
on THREE.Color
s and THREE.Texture
s to normalize changes (#3757).
- Have raycasters only intersect against objects defined via
.setObject3D
. raycaster.objects
should be specified (e.g., objects: [data-raycastable] or objects: .raycastable
) because raycasting is expensive. raycaster.recursive
property removed (#3980) but will default to be recursive only under objects defined via .setObject3D
(#3652).
- Add
renderer
component (#3757).
antialias
attribute moved to renderer.antialias
.
- Raycaster events such as
raycaster-intersected
no longer directly contain intersection data. Use .getIntersection
function supplied in event detail or el.components.raycaster.getIntersection(el)
to retrieve intersection data. Done to reduce garbage (a87e3b).
- Disable link portal appearance by default (
link.visualAspectEnabled
), link component defaults to purely to listening to an event to trigger navigation (#3743).
Fixes
- Frame-independent easing for
wasd-controls
to prevent judders during framedrops (#3830).
- Enable matrix auto updates for
tracked-controls
to fix children of camera and controllers not following parent (#3867).
- Fix removing mixins not removing components (#3982).
- Fix timing issues with mixins on still-initializing entities (#3859).
- setPoseTarget to underlying object3D to fix issues with entities as child of camera (#3820).
- Don't disable
matrixAutoUpdate
for tracked-controls outside VR (643fdc).
- Render spectator view after VR submit frame (#3577).
- Fix mouse cursor events not being re-enabled on resume (#3904).
- Allow components to write to camera Z rotation when look-controls enabled (9a78a)
- Clear raycaster intersections when toggling disabled (#3594).
- Postpone renderer until scene is appended to DOM (#3574).
- Fix canvas textures (b47f20).
- Fix faces and vertices numbers on stats panel (#3573).
- Fix magic window mode on Chrome (aaa3bf).
- Fix audio asset preloading (2a899c).
- Fix raycaster flatten to only include objects part of
el.object3DMap
versus arbitrary children (8809e7).
- Fix canvas getting squished on orientation change on mobile (64ed3d).
- Update position, rotation, scale components when calling
.setAttribute
on them (#3738).
- Update canvas bounds for mouse cursor on renderer resize (a4cf08).
- Fix controller reconnecting on Oculus Go and GearVR (dc8662).
- Fix playing sound on event with
sound.on
(#3844).
- Fix Chrome WebView (#3852).
- Fix raycaster not grabbing all entities when
raycaster.objects
is not set. But you should always set it (#3840).
- Fix WebVR polyfill buffer scale override (#3863).
- Fix text when used with other geometry types (#3909).
- Fix
daydream-controls
trigger not working with cursor by default (#3916).
- Fix accessing Inspector in pointer lock mode (#3947).
- Fix mouse cursor not emitting click when fuse is set (#4000).
- Fix screenshots (#3998).
- Fix camera offset getting applied when entering 2D fullscreen (#3902).
Enhancements
- Add
oculus-go-controls
, thanks Oculus! (cbbe75)
- Add
vive-focus-controls
(#3876).
- Add
loading-screen
component (#3760).
- Add
?inspector={selector}
and Entity.inspect()
to automatically launch Inspector and focus on entity (#3894).
- Add
renderer.highRefreshRate
to enable 72hz mode on Oculus Browser (#3967).
- Add
tracked-controls.autoHide
property to configure whether controllers automatically hide when connected or disconnected (#3912).
- Enable multiple raycasters on an entity (fc18cd).
- Support custom enter VR buttons through vr-mode-ui (#3606).
- Add
material.blending
property (#3543).
- Add
light.shadowRadius
property (21b38).
- Add ability to cap canvas size to pixel value (92b2f9).
- Reduce npm bundle (53f58f).
- Allow double underscores in component IDs (e.g.,
animation__foo__bar
) (030023).
- Add
renderer.logarithmicDepthBuffer
option (d210a2).
- Add
look-controls.reverseTouchDrag
property (#3761).
- Switch to jsdelivr with rawgit going away.
- Support preprocessing of sound in
sound.playSound()
(2b2819).
- Consolidate fullscreen styles under single CSS class (
html.a-fullscreen
) (#3828).
- Emit
displayconnected
event when headset connected (#3918).
- Enable antialias by default on Oculus Go (#3942).
- Update to webvr-polyfill v0.10.10 (#3993).
Performance
- Large refactor of core component update path, reducing memory allocation and using object pooling (#3772).
- Skip
buildData
if updating component directly. 2x speed boost on .setAttribute
(#3835).
- Remove spamming
navigator.getGamepad
calls in tracked-controls (#3816).
- Optimize coordinates / vector utilities (#3908).
- Remove object allocation in
.setAttribute(component, propertyName, value)
(#3812).
- Simplify text shader hacks and make text alpha look prettier (#3557).
- Remove garbage and bubbling from tracked-controls (#3589).
- Remove redundant matrix world update in raycaster (ae7eba).
- Replace Oculus OBJ model with a glTF one (#3539).
- Optimize coordinate parse (bf66ba).
- Simply wasd-controls tick (#3763).
- Optimize text component (#3768).
- Remove memory allocations in material code (#3789).
- Remove garbage in sound component (2b2819).
- Improve grabbing class cursor performance in 2D look-controls (#3790).
- Remove unused and redundant mixin observers (#3831).
- Add warning to developers to specify
raycaster.objects
(#3839).
- Cache asset property type regex (#3854).
Inspector
Kevin spent some time getting the Inspector into ship shape.
Major Changes
- Introducing the [A-Frame Watcher] to sync updates of entities with IDs from Inspector to HTML files.
- Remove HTML exporter.
- Remove old A-Frame Registry code.
- Remove broken Uploadcare uploader.
- Remove motion capture tools.
Enhancements
- Orthographic cameras.
- Improve raycasting to picking entities.
- Syntax highlighting of entities.
- Highlight and describe entities on viewport bar when hovering.
- Added
?inspector={selector}
to automatically launch Inspector and focus on entity.
- Show bounding box of selected entities.
- Show with icon what entities contain text in scenegraph.
- Sort component properties alphabetically.
- Display class names on entity panel.
- Only show camera and light helpers when respective entity is selected.
- Improve position when focusing on entity.
- Polish components panel.
- Center editor controls to the scene camera position.
- Support arrow keys for number widgets.
- .glb export.
- Add
o
shortcut to toggle transform widget.
- Add
esc
shortcut to unselect entity.
- Refactor most everything (modularize, data flow, Stylus, Prettier).
- Tweak grid colors.
- Bigger checkboxes.
- Fix color picker in components panel.
- Fix display of mixins.
Performance
- Don't load 50 images when opening the Inspector.
- Optimize and fix helpers for position, rotation, scale.
- Speed up scene graph search.
- Remove global mutation observer.