Is it possible to select multiple three.js objects by pressing CTRL and clicking on each one

I'm having issues with implementing multiple selection of three.js objects using CTRL-click. While single-select works perfectly, the behavior is problematic when trying to select multiple objects with CTRL-click. The selected array sometimes contains duplicate entries, and not every item in the array has the transformation applied consistently. It's quite confusing as the results are not what I expected. I suspect the problem lies within my logic statement inside the

if ( event.type === 'click' && event.ctrlKey )
block in the mouseEventHandler() function, but I can't seem to pinpoint the exact mistake.

Below is the relevant code snippet:

var ray = new THREE.Raycaster();
var mouse = new THREE.Vector2();
var INTERSECTED;  // Object closest to the camera
var SELECTED = [];    // Objects selected via dblclick

function onMouse( event ) {

    event.preventDefault();

    // Calculate mouse position in normalized device coordinates (-1 to +1) for both components
    mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
    mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;

    mouseEventHandler( event );

}

function mouseEventHandler( event /* , fn, revFn */ ){

    // Update the picking ray with the camera and mouse position
    ray.setFromCamera( mouse, entities.cameras.perspCamera );

    // Calculate objects intersecting the picking ray
    var intersects = ray.intersectObjects( scene.children );

    // If there's at least one intersected object...
    if ( intersects && intersects[0] && intersects[0].object ){

        // Check various scenarios based on the type of event
        // interaction with the intersected objects        

    }

}

// Additional functions for transforming graph elements based on mouse events

function transformGraphElementOnMouseOver( obj ){
    if ( obj.isGraphElement ) { obj.referent.transformOnMouseOver(); }  
}

function unTransformGraphElementOnMouseOut( obj ){
    if ( obj.isGraphElement ) { obj.referent.transformOnMouseOut(); }
}

function transformGraphElementOnSelect( obj ){
    if ( obj.isGraphElement ) { obj.referent.transformOnDblClick(); }   
}

function unTransformGraphElementOnUnselect( obj ){
    if ( obj.isGraphElement ) { obj.referent.unTransformOnDblClickOutside(); }  
}

function transformGraphElementOnWheel( obj ){
    if ( obj.isGraphElement ) { obj.referent.transformOnWheel(); }  
}

// Event listeners setup

function listenFor(){
    document.getElementById('visualizationContainer').addEventListener( 'click', onMouse, false );
    document.getElementById('visualizationContainer').addEventListener( 'mousemove', onMouse, false );
    document.getElementById('visualizationContainer').addEventListener( 'mousedown', onMouse, false );
    document.getElementById('visualizationContainer').addEventListener( 'dblclick', onMouse, false )
    document.getElementById('visualizationContainer').addEventListener( 'wheel', onMouse, false );
    document.getElementById('visualizationContainer').addEventListener( 'contextmenu', onMouse, false );
}

listenFor();

Answer №1

Special thanks to @marekful for the valuable tip that guided me towards solving the issue at hand. Unraveling the problem involved realizing that my splice action within the for loop was altering array indexes as I looped through them, causing a short-circuit in the loop. Additionally, the duplication arose from mistakenly pushing INTERSECTED back into the SELECTED array regardless of its presence.

Although another bug persists in my code - the inability to register a click when clicking on empty space in the sky where no objects exist - it seems unrelated to the current matter which now appears to be resolved. Below is the updated snippet of my mouseEventHandler():

function mouseEventHandler( event /* , fn, revFn */ ){

// update the picking ray with the camera and mouse position
ray.setFromCamera( mouse, entities.cameras.perspCamera );

// calculate objects intersecting the picking ray
var intersects = ray.intersectObjects( scene.children );

// if there's at least one intersected object...
if ( intersects && intersects[0] && intersects[0].object ){
    // Further code implementation goes here

INTERSECTED && console.log( 'INTERSECTED.isGraphElement: ', INTERSECTED.isGraphElement, 'MouseEvent: ', event.type );           
}

}

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

Unlocking Controller Functions in AngularJS Directives: A Step-by-Step Guide

Here is a sample controller and directive code: class DashboardCtrl { constructor ($scope, $stateParams) { "ngInject"; this.$scope = $scope; this.title = 'Dashboard'; } loadCharts () { // some logic here } } export def ...

Bypassing the "Your connection is not private" error in NodeJS + Express with fetch() using Javascript

Presently, I have a setup with a NodeJS + ExpressJS client-side server that communicates with the back-end server via API calls. However, every time I make a call, I need to manually navigate to the URL of the API back-end server and click on Advanced -> ...

Delivering Background Videos with Node.JS

Apologies if my question seems off base or confusing, as I am not very knowledgeable in the world of nodejs. I have been comfortable using just plain PHP and Apache for a while until I discovered ZURB Foundation's stack with Handlebars and SASS, along ...

Utilizing Sequelize's Where clause with the flexibility of optional parameters

Can you guide me on writing Sequelize queries with optional parameters? Consider the below query example: const result : SomeModel[] = await SomeModel.findAll( {where: { id: givenId, ...

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] ...

The functionality of this code is effective, however, it would be more efficient if it were implemented as a loop

While this code works, it has limitations. I believe adding some iteration would improve its functionality, but I am unsure of the best approach to take. For instance, how can I efficiently check 20 items instead of just 4, and have the flexibility to eas ...

Rendering React Router server-side with client-side session information

Currently, I am working with mozilla client-sessions in conjunction with express/node. My goal is to pass my session.user to the react-router within a standard * request. Despite my efforts and attempts, I keep encountering an issue where it becomes unde ...

Identify the absence of search results in an Ajax request to the search page before rendering the HTML content

I am attempting to retrieve JSON code from a page using the following PHP function: private function __ajax_admin_search($username = '') { $result = $this->admin_login->Admin_Username_Ajax($username); $count = count($result); for ...

The Flask web API is unable to process image files sent through AJAX requests

My Flask API is quite basic and it interacts with a DNN model. The Python backend code looks something like this: from flask import request from flask import jsonify from flask import Flask import io app = Flask(__name__) @app.route("/predict" ...

Unable to save a string value from a function to MongoDB is unsuccessful

I've hit a roadblock. Working tirelessly to solve a persistent bug, but it feels like I'm getting nowhere. What am I missing? My goal is clear - once the user submits a form with the enctype of "multipart/form-data", I want to extract t ...

I used the `MyWindow=window.open` function to display a pop-up window and then navig

On my webpage (http://localhost:8088/hse/public/explorer), I have implemented two buttons: When these buttons are clicked, a new pop-up window will open at (http://localhost:8088/hse/public/explorer/1) onClick="MyWindow=window.open('http://local ...

Need assistance as require function is not functioning as anticipated

const THREE = require('three'); require('three/examples/js/loaders/OBJLoader.js'); Once I imported threejs from node_modules, I decided to utilize the provided OBJLoader, but encountered an unexpected error. THREE is not defined a ...

Tips for bringing in and adding an excel spreadsheet to a kendo grid with the help of JQuery

I am facing a challenge with my kendo grid as I am trying to incorporate an excel file into it. Specifically, I would like to import and add an excel file to my kendo grid. If, for instance, my kendo grid initially has 3 rows, after importing an excel file ...

Combining duplicate objects in a JavaScript array

I am looking to identify duplicates by country code and merge them into a single object The array structure is: [{...},{...}] Objects {Country_Code: "RU", Country: "Russia", Provider: "Shell1", Price: "0.123"}, {Country_Code: "EN", Country: "Russia", P ...

Uncovering the main document and all predecessor records in MongoDB

I am in the process of creating a publication that will provide me with a series of documents from the collection. The relationship between these documents can be seen below: { "_id" : "peRuJcPMDzZgTvWSX", "author" : "author", "type" : "art ...

Node.js poses a challenge when it comes to decoding incoming request data

I am attempting to create a sample login page using the combination of node, express, and angularjs. Displayed below is my login view: <div class="login-page"> <div class="login-page-content"> <div style="margin-top:30px;padding:10px;w ...

Ways to prevent a loop from constantly restarting

After clicking the generate ID button once, it will become disabled and display a set of numbers. The last 4 digits are in a loop sequence starting with "0001". If I were to re-enable the generate ID button and click it again, the last 4 digits would incre ...

problem encountered while attempting to transmit data to multer in React

I was attempting to upload an image to the backend using Multer. I have reviewed the backend code multiple times and it appears to be correct. Could there be an issue with my front-end code? Here is a POST code snippet: const response = await fetch(' ...

Problem with sending variable via AJAX

Hey everyone, I'm attempting to send form data along with an extra variable using AJAX. Here's the code snippet: function tempFunction(obj) { var data = $('form').serializeArray(); data.push( { no: $(obj).at ...

Mastering the Art of Scrolling to a Specific Div with jQuery Animation

I've been searching for a solution on stack overflow, but because I'm not very proficient in jquery, I haven't been successful. My question is, how can I smoothly scroll from the top of the page to a specific div? I've successfully ach ...