I am experiencing issues with my three.js Raycaster functionality. Does anyone know how to troubleshoot and resolve this problem

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!

Answer №1

After thorough analysis and troubleshooting, I have successfully resolved the issue at hand. My approach involved making several key adjustments to the existing code. Firstly, I eliminated instances where the render function was called multiple times within the onMouseMove and onWindowResize functions to address lag concerns. Next, I focused on the plane mesh and removed its offsets to prevent interference with the cubes when the mouse was moved. Additionally, I modified specific lines of code such as rollOverMesh.position.y += 0.5 and line.position.y += 0.5, altering the offset values to -1 for synchronization purposes. The pointer.z value was also set to 0, although its direct impact remains uncertain. Lastly, a line was added immediately after creating the rollOverGeo variable:

rollOverGeo.translate(-.2, 0, -.2)
, resulting in improved centering of the mouse over the cube.

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);
    rollOverGeo.translate(-.2, 0, -.2)
    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
    plane.position.y = 0
    plane.position.z = 0
    planes.push(plane)

    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();

    renderer.setSize(window.innerWidth, window.innerHeight);

    //document.addEventListener('pointermove', onMouseMove);
    document.onmousemove = 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 = 0;
    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 -= 1
        line.position.copy(intersect.point).add(intersect.face.normal);
        line.position.y -= 1

        //render();

    }

}
function render() {
    renderer.render(scene, camera)
    requestAnimationFrame(render)
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Filter information by the K column within Google Script Editor on Google Sheets

For this particular case, I have data coming from a Google Sheet (4Cat) that is being transferred to another sheet (ImportFeeder) where my Google Script is executed. After executing the script provided below, I am looking to implement a filter script at t ...

After the AJAX request, $this experienced a loss of focus

I am facing an issue with my CakePHP code snippet below: <tr class="tr_clone"> <td><?php echo $this->Form->input('items][',array('label'=>false,'options'=>$items,'class'=>'it ...

Retrieving a PHP script from within a DIV element

I am seeking assistance to successfully load a PHP file from a DIV call. Below is the code I have used: <html> <head> </head> <body> <script class="code" type="text/javascript"> $("#LoadPHP").load("fb_marketing ...

Uploading Files Using the Dropbox API Version 2

Before, I integrated the Dropbox API V1 into my web application to upload files to my personal Dropbox account. The app was configured to use only one specific dropbox account for file uploads. Previous Process: I registered an app on the dropbox develo ...

How to add additional text after a particular line within a string containing multiple lines using JavaScript

What is the best way to add a new string after line 2 in a multi-line JavaScript string? ...

Preventing SQL Injection by properly formatting SQL queries

In my Node.js application, I need to construct an SQL query that looks like the one shown below. SELECT * FROM my_table WHERE my_column IN ['name1','name2'] The user inputs an array, such as ['name1', 'name2'], whic ...

Contrasting actions observed when employing drag functionality with arrays of numbers versus arrays of objects

Being a newcomer to D3 and JavaScript, I'm hoping someone can help me clarify this simple point. I am creating a scatter graph with draggable points using code that closely resembles the solution provided in this Stack Overflow question. When I const ...

JavaScript 'await' throws error 'then is not defined'

Just starting out with async programming and I've noticed a common issue in similar threads - the problem of not returning anything. However, in my case, I am facing a different error message 'Cannot read property 'then' of undefined&ap ...

Is there a way to manipulate a DOM element using a component?

import { FlagIcon, ChartIcon, ShareIcon, ConnectIcon, HearIcon, AnalyticsIcon, AddIcon, RemoveIcon, } from "../../icons/Icons"; import "./Sidebar.scss"; import ReactDOM from "react-dom"; const Sidebar = () =&g ...

Ways to invoke a function within a React Material-UI component

Currently, I am in the process of setting up a chat system that allows users to add emojis. To achieve this feature, I have devised a function that produces a component containing both text and an image. Here is the function I have implemented: test: fu ...

Different options for determining network connectivity on a website

Seeking Network and Location Information on ASP.Net Core MVC Web Application After some investigation, I came across the Navigator API online. For acquiring location data, it functions flawlessly. navigator.geolocation.getCurrentPosition(function (posi ...

Having difficulty retrieving cookie from fetch() response

Many times, the issue of fetching cookies from a SO response has been raised on sites like: fetch: Getting cookies from fetch response or Unable to set cookie in browser using request and express modules in NodeJS However, none of the solutions provide ...

Calculate the total width of all images

I'm on a mission to calculate the total width of all images. Despite my attempts to store image widths in an array for easy summing, I seem to be facing some challenges. It feels like there's a straightforward solution waiting to be discovered - ...

Issue with Jquery animation

I'm facing a strange issue. I've created a jQuery function that animates the result bars of a poll. function displayResults() { $(".q_answers1 div").each(function(){ var percentage = $(this).next().text(); $(this).css({widt ...

Error: The "map" property cannot be read if it is undefined in a Django and React application

While I was following the react and django tutorial, I encountered an issue when I added some code for concern with. The error message 'Cannot read property 'map' of undefined' keeps getting thrown. The error location is pointed out ...

Display the LOADING indicator until the entire page has finished loading

Here is the JavaScript code that I am currently using: function generateRequest(){ var request; if(window.XMLHttpRequest){ // Works with Firefox, Safari, Opera request = new XMLHttpRequest(); } else if(window.ActiveXObject) ...

AngularJS - managing checkboxes and dropdownlists

When I talk about the topic of depending on checkboxes from a dropdown list, I mention that I populate my dropdown list with data from the controller: @RequestMapping(value = "/all", method = GET) public List<Warehouse> findAll(){ return warehous ...

Arranging and Filtering an Object Array Based on their Attributes

Here is an example of a JSON array called items: var items = [ { Id: "c1", config:{ url:"/c1", content: "c1 content", parentId: "p1", parentUrl: "/p1", parentContent: "p1 content", } }, { Id: "c2", ...

Axio GET request in VueJS does not return a response body when using Amazon API Gateway

UPDATE: While Postman and browsers are able to receive valid response bodies from an Amazon API Gateway endpoint, other web applications are not. This is a basic GET request with no headers, and no authentication is needed for the API endpoint. The data is ...

Interacting with dynamically loaded HTML content within a div is restricted

On my main HTML page, I have implemented a functionality that allows loading other HTML pages into a specific div using jQuery. The code snippet looks like this: $('.controlPanelTab').click(function() { $(this).addClass('active').s ...