JSFiddle - React, Tailwind, and code Playground
HTML
<!-- Import maps polyfill -->
<!-- Remove this when import maps will be widely supported -->
<script async src="https://unpkg.com/[email protected]/dist/es-module-shims.js"></script>
<script type="importmap">
{
"imports": {
"three": "https://unpkg.com/[email protected]/build/three.module.js",
"three/addons/": "https://unpkg.com/[email protected]/examples/jsm/"
}
}
</script>
JavaScript
import * as THREE from 'three';
import {
OrbitControls
} from 'three/addons/controls/OrbitControls.js';
// init
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 200;
const scene = new THREE.Scene();
// Create instanced mesh
const cubeGeometry = new THREE.BoxGeometry(1, 1, 1);
const cubeMaterial = new THREE.MeshBasicMaterial({
color: 0xffffff
});
const count = 1000;
const radius = 100;
const instancedMesh = new THREE.InstancedMesh(cubeGeometry, cubeMaterial, count);
scene.add(instancedMesh);
instancedMesh.instanceMatrix.setUsage(THREE.DynamicDrawUsage);
// Position cubes on the sphere surface
const dummy = new THREE.Object3D();
const idleColor = new THREE.Color(0xffffff);
const hoverColor = new THREE.Color(0xff0000)
for (let i = 0; i < count; i++) {
dummy.position.randomDirection().multiplyScalar(radius);
dummy.scale.setScalar(3)
dummy.updateMatrix();
instancedMesh.setMatrixAt(i, dummy.matrix);
instancedMesh.setColorAt(i, idleColor);
}
// Raycaster
const raycaster = new THREE.Raycaster();
const mouse = new THREE.Vector2();
let targetPosition = new THREE.Vector3();
// Event listener for mouse move
window.addEventListener('mousemove', onMouseMove);
window.addEventListener('click', onMouseClick);
function onMouseMove(event) {
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
}
function onMouseClick(event) {
raycaster.setFromCamera(mouse, camera);
const intersects = raycaster.intersectObject(instancedMesh);
const color = new THREE.Color(0xff0000); // Red color for the hit instance
console.log("test")
if (intersects.length > 0) {
console.log("restes")
const instanceId = intersects[0].instanceId;
if (instanceId !== undefined) {
instancedMesh.setColorAt(instanceId, color);
instancedMesh.instanceColor.needsUpdate = true;
// Get the position of the clicked cube
...