freshtechbro/claudedesignskills11 files

Aframe Webxr

Declarative web framework for building browser-based 3D, VR, and AR experiences using HTML and entity-component architecture. Use this skill when creating WebXR applications, VR experiences, AR experiences, 360-degree media viewers, or immersive web content with minimal JavaScript. Triggers on tasks involving A-Frame, WebXR, VR development, AR development, entity-component-system, declarative 3D, or HTML-based 3D scenes. Built on Three.js with accessible HTML-first approach.

Specification
Skill ID
freshtechbro/claudedesignskills/aframe-webxr
Publisher
freshtechbro
Repository
claudedesignskills
Installs
0
Files
11
Synced
Sep 23, 2026
How to use it

Open any RiverX project, open the Skills panel in the chat, and search for this identifier. The files are fetched from the source repository at install time.

freshtechbro/claudedesignskills/aframe-webxrInstalls these files
  • SKILL.md
  • assets/examples/README.md
  • assets/starter_aframe/README.md
  • assets/starter_aframe/index.html
  • assets/starter_aframe/main.js
  • assets/starter_aframe/style.css
  • references/api_reference.md
  • references/components_library.md
  • references/webxr_guide.md
  • scripts/component_builder.py
  • scripts/scene_generator.py

What this skill tells the agent

A-Frame WebXR Skill

When to Use This Skill

  • Build VR/AR experiences with minimal JavaScript
  • Create cross-platform WebXR applications (desktop, mobile, headset)
  • Prototype 3D scenes quickly with HTML primitives
  • Implement VR controller interactions
  • Add 3D content to web pages declaratively
  • Build 360° image/video experiences
  • Develop AR experiences with hit testing

Core Concepts

1. Entity-Component-System (ECS)

A-Frame uses an entity-component-system architecture where:

  • Entities are containers (like <div> in HTML)
  • Components add functionality/appearance to entities
  • Systems provide global functionality
<!-- Entity with components -->
<a-entity
  geometry="primitive: box; width: 2"
  material="color: red; metalness: 0.5"
  position="0 1.5 -3"
  rotation="0 45 0">
</a-entity>

Primitives are shortcuts for common entity + component combinations:

<!-- Primitive (shorthand) -->
<a-box color="red" position="0 1.5 -3" rotation="0 45 0" width="2"></a-box>

<!-- Equivalent entity-component form -->
<a-entity
  geometry="primitive: box; width: 2"
  material="color: red"
  position="0 1.5 -3"
  rotation="0 45 0">
</a-entity>

2. Scene Setup

Every A-Frame app starts with <a-scene>:

<!DOCTYPE html>
<html>
  <head>
    <script src="https://aframe.io/releases/1.7.1/aframe.min.js"></script>
  </head>
  <body>
    <a-scene>
      <!-- Entities go here -->
      <a-box position="-1 0.5 -3" 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>

The scene automatically injects:

  • Default camera (position: 0 1.6 0)
  • Look controls (mouse drag)
  • WASD controls (keyboard movement)

3. Camera Systems

Default Camera (auto-injected if none specified):

<a-entity camera="active: true" look-controls wasd-controls position="0 1.6 0"></a-entity>

Custom Camera:

<a-camera position="0 2 5" look-controls wasd-controls="acceleration: 50"></a-camera>

Camera Rig (for independent movement and rotation):

<a-entity id="rig" position="0 0 0">
  <!-- Camera for head tracking -->
  <a-camera look-controls></a-camera>

  <!-- Movement applied to rig, not camera -->
</a-entity>

VR Camera Rig with Controllers:

<a-entity id="rig" position="0 0 0">
  <!-- Camera at eye level -->
  <a-camera position="0 1.6 0"></a-camera>

  <!-- Left hand controller -->
  <a-entity
    hand-controls="hand: left"
    laser-controls="hand: left">
  </a-entity>

  <!-- Right hand controller -->
  <a-entity
    hand-controls="hand: right"
    laser-controls="hand: right">
  </a-entity>
</a-entity>

4. Lighting

Ambient Light (global illumination):

<a-entity light="type: ambient; color: #BBB; intensity: 0.5"></a-entity>

Directional Light (like sunlight):

<a-entity light="type: directional; color: #FFF; intensity: 0.8" position="1 2 1"></a-entity>

Point Light (radiates in all directions):

<a-entity light="type: point; color: #F00; intensity: 2; distance: 50" position="0 3 0"></a-entity>

Spot Light (cone-shaped beam):

<a-entity light="type: spot; angle: 45; intensity: 1.5" position="0 5 0" rotation="-90 0 0"></a-entity>

5. Materials and Textures

Standard Material:

<a-sphere
  material="color: #FF0000; metalness: 0.5; roughness: 0.3"
  position="0 1 -3">
</a-sphere>

Textured Material:

<a-assets>
  <img id="woodTexture" src="wood.jpg">
</a-assets>

<a-box material="src: #woodTexture" position="0 1 -3"></a-box>

Flat Shading (no lighting):

<a-plane material="shader: flat; color: #4CC3D9"></a-plane>

6. Animations

Property Animation:

<a-box
  position="0 1 -3"
  animation="property: rotation; to: 0 360 0; loop: true; dur: 5000">
</a-box>

Multiple Animations (use animation__* naming):

<a-sphere
  position="0 1 -3"
  animation__position="property: position; to: 0 3 -3; dir: alternate; loop: true; dur: 2000"
  animation__rotation="property: rotation; to: 360 360 0; loop: true; dur: 4000"
  animation__scale="property: scale; to: 1.5 1.5 1.5; dir: alternate; loop: true; dur: 1000">
</a-sphere>

Event-Based Animation:

<a-box
  color="blue"
  animation__mouseenter="property: scale; to: 1.2 1.2 1.2; startEvents: mouseenter"
  animation__mouseleave="property: scale; to: 1 1 1; startEvents: mouseleave"
  animation__click="property: rotation; from: 0 0 0; to: 0 360 0; startEvents: click">
</a-box>

7. Assets Management

Preload assets for better performance:

<a-scene>
  <a-assets>
    <!-- Images -->
    <img id="texture1" src="texture.jpg">
    <img id="skyTexture" src="sky.jpg">

    <!-- Videos -->
    <video id="video360" src="360video.mp4" autoplay loop></video>

    <!-- Audio -->
    <audio id="bgMusic" src="music.mp3" preload="auto"></audio>

    <!-- Models -->
    <a-asset-item id="tree" src="tree.gltf"></a-asset-item>

    <!-- Mixins (reusable component sets) -->
    <a-mixin id="redMaterial" material="color: red; metalness: 0.7"></a-mixin>
  </a-assets>

  <!-- Use assets -->
  <a-entity gltf-model="#tree" position="2 0 -5"></a-entity>
  <a-sphere mixin="redMaterial" position="0 1 -3"></a-sphere>
  <a-sky src="#skyTexture"></a-sky>
</a-scene>

8. Custom Components

Register custom components to encapsulate logic:

AFRAME.registerComponent('rotate-on-click', {
  // Component schema (configuration)
  schema: {
    speed: {type: 'number', default: 1}
  },

  // Lifecycle: called once when component attached
  init: function() {
    this.el.addEventListener('click', () => {
      this.rotating = !this.rotating;
    });
  },

  // Lifecycle: called every frame
  tick: function(time, timeDelta) {
    if (this.rotating) {
      var rotation = this.el.getAttribute('rotation');
      rotation.y += this.data.speed;
      this.el.setAttribute('rotation', rotation);
    }
  }
});
<a-box rotate-on-click="speed: 2" position="0 1 -3"></a-box>

Common Patterns

Pattern 1: VR Controller Interactions

Problem: Enable object grabbing and manipulation in VR

Solution: Use hand-controls and custom grab component

<a-scene>
  <!-- VR Camera Rig -->
  <a-entity id="rig">
    <a-camera position="0 1.6 0"></a-camera>

    <a-entity
      id="leftHand"
      hand-controls="hand: left"
      laser-controls="hand: left">
    </a-entity>

    <a-entity
      id="rightHand"
      hand-controls="hand: right"
      laser-controls="hand: right">
    </a-entity>
  </a-entity>

  <!-- Grabbable objects -->
  <a-box class="grabbable" position="-1 1.5 -3" color="#4CC3D9"></a-box>
  <a-sphere class="grabbable" position="1 1.5 -3" color="#EF2D5E"></a-sphere>
</a-scene>

<script>
AFRAME.registerComponent('grabbable', {
  init: function() {
    var el = this.el;

    el.addEventListener('triggerdown', function(evt) {
      console.log('Grabbed by', evt.detail.hand);
      el.setAttribute('color', 'green');
    });

    el.addEventListener('triggerup', function(evt) {
      el.setAttribute('color', 'blue');
    });

    el.addEventListener('gripdown', function(evt) {
      // Attach object to controller
      var controllerEl = evt.detail.controller;
      controllerEl.object3D.attach(el.object3D);
    });

    el.addEventListener('gripup', function(evt) {
      // Detach from controller
      var sceneEl = el.sceneEl.object3D;
      sceneEl.attach(el.object3D);
    });
  }
});

// Apply grabbable component
document.querySelectorAll('.grabbable').forEach(el => {
  el.setAttribute('grabbable', '');
});
</script>

More from freshtechbro

Use this skill in a project

Open any RiverX project, search the Skills panel for freshtechbro/claudedesignskills/aframe-webxr, and install it in one click.

Use this skill