Utilizing THREE.JS: Implementing a click event using raycasting and a perspective camera

Looking to implement a unique menu for a web page using three.js, where each tab is represented by an object (a 2D rectangle) and clicking on the rectangle will navigate to a specific page of the website. I've been researching how to achieve this functionality using a raycaster activated upon a right-click event, and then utilizing the intersected objects array to determine which object was clicked.

I've tried several tutorials online but have not been successful in getting a functional raycaster and eventListener for the right-click. The raycast function I'm using is directly from the official three.js documentation.

Below is my code (script.js). Can you spot any errors or provide any suggestions for improvement? Thank you in advance for your assistance!


var camera, scene, rendu;
var geometrie, materiau, mesh;
var controle;
var couleur, plan, onglet1, onglet2, onglet3, onglet4, onglet5, onglet6;
var r, t;
var rayon, souris;

init();

function init() {
    // Code omitted for brevity
}

// Remaining code truncated for brevity

And here is my html code (index.html)


<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>test</title>

    <style>
        body{margin: 0px;}
        canvas{width: 100%; height: 100%;}
    </style>
</head>


<body>
    <script src="js/build/three.js"></script>
    <script src="js/build/three.min.js"></script>
    <script src="js/OrbitControls.js"></script>
    <script src="js/GLTFLoader.js"></script>
    <script src="js/script.js"></script>
</body>
</html>

Answer ā„–1

Once you've initialized the variable souris as a type of Vector2, proceed by casting the ray and verifying if it intersects with any objects prior to making any alterations.

To prevent modifying the color of all objects in the scene that share the same material, assign a new material specifically to the first intersected object.

function performRaycast( event ) {
    //1. Define the mouse position relative to the screen's center
    souris = new THREE.Vector2();
    souris.x = ( event.clientX / window.innerWidth ) * 2 - 1;
    souris.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
    //2. Create a ray originating from the camera based on mouse coordinates
    rayon.setFromCamera( souris, camera );
    //3. Calculate intersections
    var intersections = rayon.intersectObjects( scene.children );

    if (intersections.length) {
        intersections[0].object.material = 
            new THREE.MeshBasicMaterial({ 
                color: 0xff0000, 
                side: THREE.DoubleSide 
            });

        if (intersections[0].object.url) { window.open(intersections[0].object.url, '_blank'); }
    }
}

Furthermore, importing both three.js & three.min.js is unnecessary, so remove one of them from your project.

This should help resolve the issue at hand...

Answer ā„–2

It seems like you're encountering an issue because you haven't initialized your variable souris as a THREE.Vector2(). Here's a simplified version of your code:

var souris;
souris.x = xxx;
souris.y = yyy;

var rayon = new THREE.Raycaster();
rayon.setFromCamera( souris, camera );

Raycaster.setFromCamera requires the use of a Vector2 as its first argument, so make sure to create a Vector2 object!

To resolve this issue, ensure that you declare souris = THREE.Vector2() before setting its values:

var souris = THREE.Vector2();
souris.x = xxx;
souris.y = yyy;

var rayon = new THREE.Raycaster();
rayon.setFromCamera( souris, camera );

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

How can one address the issue of undefined data within table cells?

I have encountered an issue while reading and displaying an XML file on a webpage using a JavaScript script. The problem arises when the page loads, and the information inside the cells of the table shows as "UNDEFINED". The intended display should include ...

Result array, employed as an input for auto-suggest functionality

Iā€™m currently working with an array where I am iterating over an object from an API endpoint that is in stdClass format: foreach($searchResults->hits as $arr){ foreach ($arr as $obj) { $fullType = $obj->_source->categories; print_r($fu ...

The Ajax request (b) fired off during the callback of an earlier Ajax request (a) finishes before (a) itself is fully

I encountered an issue with my code where an ajax call, referred to as callback (b), was expected to depend on the success of another ajax call, known as callback (a). Surprisingly, callback (b) completed successfully before its parent ajax call (a) finish ...

VueJS with Vuetify: Issue with draggable cards in a responsive grid

I am currently working on creating a gallery that allows users to rearrange images. To test this functionality, I am using an array of numbers. It is important that the gallery is responsive and displays as a single column on mobile devices. The issue I ...

How much worth does an unfilled text input box hold?

I've been working on integrating a search feature and I'm having an issue with the functionality. Below is the code snippets for both HTML and JS: HTML <form> <input type="text" ng-model="searchVar" class="searchbox"> <in ...

Incorporate JSON data from a file into a d3 visualization within a Node.js/Express

I am working on an express app and I have the requirement to load JSON data from the "public" folder into d3 (version 4). Here is my current folder structure: public |-myData.json view |-index.jade app.js The JSON data I want to load using d3: { { ...

To view the previous or next image, simply click on the links and watch as the new image fades in seamlessly while maintaining

Whenever I click on a prev/next link, a specific div loads different images that loop. The JavaScript successfully changes the image source when the prev or next button is clicked. It works flawlessly. However, I am facing an issue. I want each new image ...

Jest / eslint error: Function has no defined return type

I'm currently working with Jest in my codebase const fetchData = async () => { await API.fetchDataAsync(param); }; await expect(fetchData()).rejects.toThrowError(CustomError); However, I encountered an eslint error 92:28 error ...

What is the best way to save the response data into an array outside of the current function in Node.js?

How can I efficiently store all the result data into an array called pImages? I am able to retrieve the results, but I believe using an async function would be more suitable. However, I am unsure of how to implement it. Any assistance would be greatly appr ...

Every day, I challenge myself to build my skills in react by completing various tasks. Currently, I am facing a particular task that has me stumped. Is there anyone out there who could offer

Objective:- Input: Ask user to enter a number On change: Calculate the square of the number entered by the user Display each calculation as a list in the Document Object Model (DOM) in real-time If Backspace is pressed: Delete the last calculated resul ...

Exporting CSS file from css-loader in Webpack: A step-by-step guide

My application structure is set up like this: /src /app.js /styles.css /images /img.png The content of the app.js file is as follows: const styles = require('./styles.css'); console.log(styles) // => I want a URL to t ...

Having trouble retrieving data through AJAX requests

My goal is to verify the existence of a user email on "blur()" using AJAX to send textbox data to PHP. Even though I can see the posted data in Firebug, I keep encountering an error: Undefined index: data. Despite numerous attempts, I have been unable to r ...

What is the best way to extract the delta from audio.currentTime?

I'm looking to synchronize my Three.js skeletal animation with an audio track. Typically, for animating the model, I would use the following code: var clock = new THREE.Clock(); function animate(){ var delta = clock.getDelta(); THREE.Animati ...

Interested in gaining knowledge on how to define basic properties on the model within Angular.JS?

As I dive into the demos on the angular.js website, one aspect that caught my attention is the lack of explicit model/properties definition compared to other frameworks like durandal. For instance, how can we access the property "yourName" in a particular ...

Enhanced UI Pagination Component

I am puzzled by why my page is unable to recognize other pages when I click (for example, when on page 2, the same page keeps appearing) This snippet is from MealNew.js component: import React, {useEffect, useState } from "react"; import '. ...

The date-picker element cannot be selected by html2canvas

I'm encountering an issue with Html2canvas while trying to capture a screenshot of my page. Specifically, the date shown in the date-picker on the page is not appearing in the screenshot. Do you have any insights into why this might be happening and h ...

Center JQuery within the current screen

My implementation of Jquery dialog is as follows: <body> <div id="comments_dialog"> Insert a comment <form> <input type="text" id="search" name="q"> </form> </div> .... </body> dialog = $( "#com ...

Is there a way for me to conceal my table upon clicking on the sidebar? Additionally, when I click on a button to display a different table, can the currently visible table automatically close?

I have a unique table for each button. Initially, the tables are hidden using CSS visibility: 'hidden', and when I click a button, the corresponding table displays. However, the issue arises when I click the same button again as it fails to hide ...

What is the best way to combine two arrays into a single array using AngularJS?

Here is a code snippet: $scope.studentDetails=[]; $scope.studentDetails=[0][id:101,name:one] [1][id:102,name:two] [2][id:103,name:three] $scope.studentMarks=[]; $scope.studentMarks=[0][id:101,marks:78] ...

Adjust the preset timeout for mocha

In the scenario where we have a unit test file named my-spec.js and are utilizing mocha for running tests: mocha my-spec.js By default, the timeout period is set at 2000 ms. However, it can be modified for specific tests by adding a command line paramet ...