To construct your own gaze cursor, you will need the following key components:
- A designated object to act as the cursor for user feedback
- An array of objects that the cursor will interact with
- A loop to iterate through the array of interactive objects to determine if the cursor is targeting them
Below is a sample implementation to help you better understand the process.
Cursor Design
Utilizing a ring design allows for animation, which provides users with feedback before triggering an interaction.
const cursor = new THREE.Mesh(
new THREE.RingBufferGeometry(0.1, 0.15),
new THREE.MeshBasicMaterial({ color: "white" })
);
Interactive Elements
Maintain a list of objects that should be interactive and define the actions they should perform when interacted with.
const selectable = [];
const cube = new THREE.Mesh(
new THREE.BoxBufferGeometry(1, 1, 1),
new THREE.MeshNormalMaterial()
);
selectable.push({
object: cube,
action() {
console.log("Cube selected");
},
});
Interactivity Validation
Regularly check for interactions and execute the corresponding actions.
const raycaster = new THREE.Raycaster();
(function animate() {
for (let i = 0, length = selectable.length; i < length; i++) {
const camPosition = camera.position.clone();
const objectPosition = selectable[i].object.position.clone();
raycaster.set(camPosition, camera.getWorldDirection(objectPosition));
const intersects = raycaster.intersectObject(selectable[i].object);
const selected = intersects.length > 0;
// Change cursor color to indicate selection
cursor.material.color.set(selected ? "crimson" : "white");
// Execute object action only once
if (selected && !selectable[i].selected) {
selectable[i].action();
}
selectable[i].selected = selected;
}
})();
View the demonstration below to see this concept in practice:
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
canvas {
display: block;
}
<script type="module">
import * as THREE from "https://cdn.jsdelivr.net/npm/three@latest/build/three.module.js";
import { OrbitControls } from "https://cdn.jsdelivr.net/npm/three@latest/examples/jsm/controls/OrbitControls.js";
// Code for setting up the environment and implementing the gaze cursor
</script>