Using OrBI

OrBI is a component in the entity-component-system (ECS) architecture used in A-Frame (refer to A-FRAME Docs). It means that OrBI have to be attached to an entity to be added to the scene. The way you do it in A-Frame is through HMTL:

<a-entity orbi></a-entity>

You can then set the properties to OrBI:

<a-entity orbi="orbits: 1 1.5; theta: 45; phi: 0;"></a-entity>

As default, OrBI uses spherical coordinates to positionate the interface, i.e., the position is defined with a radial distance from the camera and two angles.The property orbits defines the possible distances, theta defines the horizontal angle, and phi defines the vertical angle.

It is also possible to positionate OrBI using cartesian coordinates, but then movement buttons are disabled automatically.

<a-entity orbi="worldPosition: -1 1.6 -1; rotation: 0 45 0;"></a-entity>

For creating buttons, we need to use javascript. The way we do it is creating an auxiliary component and adding to our entity.

<html>
<head>
    [...]
    <script src="path/to/aframe.min.js"></script>
    <script src="path/to/orbi.js"></script>

    <script>
        AFRAME.registerComponent('my-component', {
            init: function () {
                const orbi = this.el.components['orbi'];

                orbi.addButton('myButton', '#myTexture', function () {
                    orbi.showMessage('Button pressed');
                });

                orbi.addButton('myButton2', '#myTexture2', function () {
                    orbi.showMessage('Button 2 pressed', 'bottom');
                });
            },
        });
    </script>
</head>

<body>
    <a-scene>
        <a-assets>
            <img id="#myTexture" src="path/to/textute/img1.png">
            <img id="#myTexture2" src="path/to/textute/img2.png">
        </a-assets>

        <a-entity orbi="dimension: 2 1; theta: 45" my-component></a-entity>
    </a-scene>
</body>
</html>

Notice the dimension property, it defines how the buttons will be displayed, in the case, 2 lines an 1 row.

If you plan to move the camera while using OrBI, wrap your camera entity with a entity with the id rig and move the rig instead of the camera itself.

<a-scene>
    <a-entity id="rig" position="0 0 0">
        <a-entity id="camera" camera position="0 1.6 0"">
        </a-entity>
    </a-entity>

    <a-entity orbi="dimension: 2 1; theta: 45" my-component></a-entity>
</a-scene>

Properties:

Property Description Default Value
dimension Dimension of the interface { x: 1, y: 1 }
orbits Distances from the camera 1
theta Horizontal rotation in degrees 90
phi Vertical rotation in degrees 0
movementBar Whether to display move bar or not, doesn't work with worldPosition true
worldPosition Cartesian way for positioning the interface, it overrides the default orbital way { x: null, y: null, z: null }
rotation Defines the rotation in x, y and z when using worldPosition { x:0, y:0, z:0 }
centralize Whether to align buttons to the center, if false they are aligned to the top-left true
buttonSize Width and height of the buttons { x: 0.3, y: 0.2 }
border Thickness and color of button border, if nothing is set, no border is added { thickness: 0, color: null }
gap Distance beteween the buttons in the x and y axis { x: 0, y: 0}
transparency Whether the textures have transparency false
messagePos Default position of message (top or bottom) top
messageColor Text color of the message box white
messageBG Background color of the message box #232323
cursorColor Defines the color of the aim cursor white
cursorPosition Defines the positon of the aim cursor, usually it doesn't need to change { x: 0, y: 0, z: -1 }
font Font URL. Check here valid fonts A-Frame default (Roboto)
negate Negate font true
sideTextSize Size for the lateral panel { x: 0.75, y: 1 }
sideTextRotation Lateral panel rotation 0
visible Visibilty of the interface true
raycaster Defines near and far properties of the raycaster { near: 0, far: orbits[0] }

Functions:

Function Description
addButton(buttonName, idOfTexture, callback) Adds a button to the interface
showMessage(message, position) Shows message, position parameter is optional
showSideText(text) Shows a permanent multiline message to the right of the interface
hideSideText() Hides side text
updatePosition({radius, theta, phi, worldPosition}) Should be called if the camera position changes or if you want to change one parameter. All parameters are optional.
hide() Hide the interface
show() Make interface visible