A Frame Components

Components Available for A-Frame.

The following components are available here under the MIT license.

Component Description Link
onclick For specifying a click handler for an entity or mixin. https://www.lokeldigital.com/shared-code/a-frame/onclick.js
rotate Assigns rotational speed for each axis in degrees / sec https://www.lokeldigital.com/shared-code/a-frame/rotate.js

Hold On What is A-Frame?

A-Frame is a neat JavaScript library that provides an Entity Component System layer over ThreeJS.

A-Frame makes using ECS in HTML really quite easy and simplfiies WebGL site creation dramatically. Many add-on components can be found in GitHub or via NPM.

Entity Component System

Overview

A-Frame implements a very neat ECS that builds on HTML to define entities in the scene and uses custom attributes for components and the value of the attribute holds the property values. Systems sit in the background and do the work for the component, if they are written.

A-Frame’s documentation for their ECS:

Limitations

My pet peeves with A-Frame are:

  • Systems aren’t necessary because you can put all the logic in the component and this is actually easier to implement than supporting the ECS architecture. Feels like they are hedging their bets a little.
  • Registering a component and system with A-Frame doesn’t automatically invoke the management of the component via the system. The author needs to make the system manage the components it handles on it’s own. Worse, the component needs to cooperate and that’s why I say that A-Frame make EC easier than full ECS. See here for A-Frame’s description of this.

Onclick Component

The onclick component makes it easy to register a click handler for any entity. Like most components, it can be easier to use it in mixins to build up the 3D equivalent of styles in your A-Frame scene.

Two examples are:

<html>
  <head>
    <script src="https://aframe.io/releases/1.0.4/aframe.min.js"></script>
    <script src="https://www.lokeldigital.com/shared-code/a-frame/onclick.js"></script>

    <script>
      function whenClicked(color) {
        let el = this
        el.setAttribute('material', `color: ${color}`)
      }

      function redWhenClicked() {
        this.setAttribute('material', "color: red")
      }
    </script>
  </head>
  <body>
    <a-scene>
      <a-assets>
        <!-- Interactive Styling -->
        <a-mixin id="redWhenClicked" onclick="redWhenClicked"></a-mixin>
        <a-mixin id="greenWhenClicked" onclick="whenClicked('green')"></a-mixin>

        <!-- Shapes -->
        <a-mixin id="box" geometry="primitive: box; width: 2; height: 2; depth: 2" />
        <a-mixin id="ball" geometry="primitive: sphere; radius: 1"/>

        <!-- colors -->
        <a-mixin id="init-blue" material="color: blue"></a-mixin>
        <a-mixin id="init-pink" material="color: pink"></a-mixin>
      </a-assets>

      <a-entity mixin="init-blue ball redWhenClicked" position="-2 1 -3"></a-entity>
      <a-entity mixin="init-pink box greenWhenClicked" position="0 1 -4"></a-entity>
      <a-entity mixin="init-pink box greenWhenClicked" position=".5 3 -4.5"></a-entity>
      <a-entity mixin="init-blue ball" onclick="whenClicked('black')" position="2 1 -3"></a-entity>

      <a-entity cursor="ray-origin: mouse" raycaster="objects: [geometry]"></a-entity>
    </a-scene>
  </body>
</html>

Rotate Component

The rotate component lets you specify rotational speed in degrees / second for each of the axes: X, Y and Z. See the example below. The boxes are made to look as if they float, adrift in space, by using small rotational speeds in two axes. The green box is set in a rig (parent entity) that rotates around the Z axis and is offset from the centre.

<html>
  <head>
    <script src="https://aframe.io/releases/1.0.4/aframe.min.js"></script>
    <script src="https://www.lokeldigital.com/shared-code/a-frame/rotate.js"></script>
    <script src="https://unpkg.com/aframe-environment-component@1.1.0/dist/aframe-environment-component.min.js"></script>
  </head>
  <body>
    <a-scene>
      <a-box position="-1 2 -4" rotate="5 20 0" color="yellow"></a-box>
      <a-box position="4 2 -2" rotate="15 2 0" color="red"></a-box>
      <a-entity position="0 2.5 0" rotate="0 0 30">
        <a-box position="0 2 -2" rotate="15 0 3" color="green"></a-box>
      </a-entity>

      <a-camera position="0 2 4" look-controls></a-camera>

      <a-entity environment="preset:egypt"></a-entity>
    </a-scene>
  </body>
</html>