aframe-cursor-teleport-component
v1.5.0
Published
Simple teleport navigation for non-XR devices.
Downloads
107
Readme
aframe-cursor-teleport-component
A simple A-Frame component for navigating scenes on non-VR devices. When combined with A-Frame's cursor and look-controls components, this allows users to freely explore A-Frame scenes using device orientation and touch on mobile or using the mouse on desktop.
For A-Frame.
API
| Property | Description | Default Value |
| --- | --- | --- |
| cameraRig | Selector of the camera rig to teleport | |
| cameraHead | Selector of the scene's active camera ||
| collisionEntities | Selector of the meshes used to check the collisions. If no value provided a plane at Y=0 is used. | |
| defaultPlaneSize | Size of the default plane created for collision when collisionEntities
is not specified | 100 |
| ignoreEntities | Selector of meshes that may obstruct the teleport raycaster, like UI or other clickable elements.
| landingNormal | Normal vector to detect collisions with the collisionEntities
| (0, 1, 0) |
| landingMaxAngle | Angle threshold (in degrees) used together with landingNormal
to detect if the mesh is so steep to jump to it. | 45
Events
The cursor-teleport
component will emit two events:
navigation-start
: Entity beginning travel to a destination.navigation-end
: Entity has reached destination.
Installation
Browser
Install and use by directly including the browser files:
<head>
<title>My A-Frame Scene</title>
<script src="https://aframe.io/releases/1.5.0/aframe.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/c-frame/[email protected]/dist/aframe-cursor-teleport-component.min.js"></script>
</head>
<body>
<a-scene>
<!-- see usage below -->
</a-scene>
</body>
npm
Install via npm:
npm install aframe-cursor-teleport-component
Then require and use.
require('aframe');
require('aframe-cursor-teleport-component');
Usage
Basic Setup
<a-scene cursor="rayOrigin: mouse">
<a-entity id="cameraRig" cursor-teleport="cameraRig: #cameraRig; cameraHead: #head">
<a-entity id="head" position="0 1.52 0" camera look-controls="reverseMouseDrag: true">
</a-entity>
</a-entity>
</a-scene>
Collision Entities
To add collision objects, simply identify them with a selector:
<a-scene cursor="rayOrigin: mouse">
<!-- camera rig -->
<a-entity id="cameraRig" cursor-teleport="cameraRig: #cameraRig; cameraHead: #head; collisionEntities: .collision">
<a-entity id="head" position="0 1.52 0" camera look-controls="reverseMouseDrag: true"></a-entity>
</a-entity>
<!-- collidable entity -->
<a-entity class="collision" position="0 -.05 0" geometry="primitive: box; width: 8; height: .1; depth: 8"></a-entity>
</a-scene>
Ignored Entities
If your scene has interactive entities that should not initiate a teleport when clicked, you can add them to the ignoredEntities array using a selector:
<a-scene cursor="rayOrigin: mouse" raycaster="objects: .clickable" >
<!-- camera rig -->
<a-entity id="cameraRig" cursor-teleport="cameraRig: #cameraRig; cameraHead: #head; collisionEntities: .collision; ignoreEntities: .clickable">
<a-entity id="head" position="0 1.52 0" camera look-controls="reverseMouseDrag: true"></a-entity>
</a-entity>
<!-- collidable entity -->
<a-entity class="collision" position="0 -.05 0" geometry="primitive: box; width: 8; height: .1; depth: 8"></a-entity>
<!-- UI element -->
<a-entity class="clickable" color-change geometry="primitive: octahedron" scale=".2 .2 .2" position="-.8 1 -1.5"></a-entity>
</a-scene>
Use with aframe-blink-controls
This component works with aframe-blink-controls allowing for easy-to-use navigation across virtually all devices:
<a-scene cursor="rayOrigin: mouse" raycaster="objects: .clickable">
<!-- camera rig -->
<a-entity id="cameraRig" cursor-teleport="cameraRig: #cameraRig; cameraHead: #head; collisionEntities: .collision; ignoreEntities: .clickable">
<a-entity id="head" position="0 1.52 0" camera look-controls="reverseMouseDrag: true"></a-entity>
<a-entity laser-controls="hand: left" raycaster="objects: .clickable; far: 100" line="color: red; opacity: 0.75" blink-controls="cameraRig: #cameraRig; teleportOrigin: #head;"></a-entity>
<a-entity laser-controls="hand: right" raycaster="objects: .clickable" line="color: red; opacity: 0.75" blink-controls="cameraRig: #cameraRig; teleportOrigin: #head;"></a-entity>
</a-entity>
<!-- collidable entity -->
<a-entity class="collision" position="0 -.05 0" geometry="primitive: box; width: 8; height: .1; depth: 8"></a-entity>
<!-- UI element -->
<a-entity class="clickable" color-change geometry="primitive: octahedron" scale=".2 .2 .2" position="-.8 1 -1.5"></a-entity>
</a-scene>
Use with simple-navmesh-constraint
You should disable the simple-navmesh-constraint
component during the navigation transition.
You can do that like this:
<script>
AFRAME.registerComponent("character-controller", {
events: {
"navigation-start": function () {
if (this.el.hasAttribute("simple-navmesh-constraint")) {
this.el.setAttribute("simple-navmesh-constraint", "enabled", false);
}
},
"navigation-end": function () {
if (this.el.hasAttribute("simple-navmesh-constraint")) {
this.el.setAttribute("simple-navmesh-constraint", "enabled", true);
}
},
},
});
</script>
Then add character-controller
component to your cameraRig entity. You also probably want to add .navmesh-hole
to the cursor-teleport
's ignoreEntities
:
<a-entity id="cameraRig" character-controller cursor-teleport="cameraRig: #cameraRig; cameraHead: #head; collisionEntities: .collision; ignoreEntities: .clickable,.navmesh-hole">
<a-entity id="head" position="0 1.52 0" camera look-controls="reverseMouseDrag: true"></a-entity>
</a-entity>
teleportTo API
You can use the same teleport animation programmatically to teleport to a destination knowing the position and quaternion (optional):
const cameraRig = document.getElementById('cameraRig');
const cursorTeleport = cameraRig.components['cursor-teleport'];
cursorTeleport.teleportTo(destination.object3D.position, destination.object3D.quaternion);
Look at the source code of the basic example, the black button triggers the teleportation to the black arrow on the second platform.