Once I set up my new project using three.js
, I followed the instructions in the three.js
documentation to add a Raycaster
and connect it to a cube. The goal was to make the cube follow the cursor's position, but unfortunately, the cube ended up moving too far sideways.
Below is the code snippet:
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
import {MeshBasicMaterial} from "three";
const canvas = document.querySelector('#c')
const renderer = new THREE.WebGLRenderer({antialias: true, canvas})
const camera = new THREE.PerspectiveCamera(75, 2, 0.1, 1000)
const controls = new OrbitControls(camera, renderer.domElement)
controls.addEventListener('change', camera)
camera.position.z = 3.5;
camera.position.x = 3.5;
camera.position.y = 5;
camera.lookAt(-0.5,-0.5,-0.5)
controls.target = new THREE.Vector3(-0.5, -0.5, -0.5)
const scene = new THREE.Scene()
scene.background = new THREE.Color(0x36393e)
const loader = new THREE.TextureLoader()
let rollOverMaterial, rollOverMesh, line;
let planes = [];
const raycaster = new THREE.Raycaster();
const pointer = new THREE.Vector3()
init()
render()
function init() {
const gridHelper = new THREE.GridHelper(16, 16, 0xffffff)
scene.add(gridHelper)
gridHelper.position.y = -0.5
gridHelper.position.x = -0.5
gridHelper.position.z = -0.5
const rollOverGeo = new THREE.BoxGeometry( 1, 0.999, 1 );
rollOverMaterial = new THREE.MeshBasicMaterial( { color: 0x0077be, opacity: 0.5, transparent: true } );
rollOverMesh = new THREE.Mesh( rollOverGeo, rollOverMaterial );
const edges = new THREE.EdgesGeometry(rollOverGeo)
line = new THREE.LineSegments(edges, new THREE.LineBasicMaterial({color: 0x6b6b6b}))
scene.add( rollOverMesh, line );
const planeGeometry = new THREE.PlaneGeometry(16, 16)
planeGeometry.rotateX( - Math.PI / 2 );
const plane = new THREE.Mesh( planeGeometry, new THREE.MeshBasicMaterial( { visible: false } ) );
scene.add( plane );
plane.position.x = -0.5
plane.position.y = -1.5
plane.position.z = -0.5
planes.push(plane)
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
document.addEventListener( 'pointermove', onMouseMove );
window.addEventListener( 'resize', onWindowResize );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
render();
}
function onMouseMove( event ) {
pointer.x = ( event.clientX / renderer.domElement.clientWidth ) * 2 - 1;
pointer.y = - ( event.clientY / renderer.domElement.clientHeight ) * 2 + 1;
pointer.z = 1;
let mouse = [event.clientX, event.clientY];
raycaster.setFromCamera(pointer, camera);
let intersects = raycaster.intersectObjects(planes, true);
if ( intersects.length > 0 ) {
const intersect = intersects[ 0 ];
rollOverMesh.position.copy( intersect.point ).add( intersect.face.normal );
rollOverMesh.position.y += 0.5
line.position.copy( intersect.point ).add( intersect.face.normal );
line.position.y += 0.5
render();
}
}
function render() {
renderer.render(scene, camera)
requestAnimationFrame(render)
}
I attempted to replace event.clientX
with event.pageX
hoping for better results, but unfortunately, it didn't work as expected. As a beginner in JavaScript and three.js
, I apologize if this seems like a simple mistake!