Unable to access a specific URL for the chosen items

I am looking to navigate to specific links when clicking on particular planets using raycaster. However, the current issue is that I get redirected to the URL of the last planet (referred to as category) whenever I click anywhere on the canvas. I have separate functions for creating the planets and tweening outside the init() function. How can I configure the raycaster to only register clicks on the planets so that I can navigate to their respective URLs? Thank you for your assistance.

Check out the code below:

class App extends Component{

  componentDidMount() {
    var scene, camera, renderer;
    var controls;
    var category, orbit, orbitContainer

    init();
    animate();

    function createSubCategory(){}

    function createCategory(name, radius, distance, tilt, color, speed, link) {
      orbitContainer = new THREE.Object3D();
      orbitContainer.rotation.x = tilt;

         var id = name

        orbit = new THREE.Object3D();

        var geometry = new THREE.CircleGeometry(distance, 100);
        geometry.vertices.shift();
        var line = new THREE.Line(
          geometry,
           new THREE.LineBasicMaterial({color: 'aqua'})
        );

        //ring movement
        line.rotation.x = Math.PI * 0.5;

        category = new THREE.Mesh(
          new THREE.SphereGeometry(radius, 0, 0),
            new THREE.MeshBasicMaterial({color:color,wireframe: true})
        );
        orbitContainer.userData.URL= link;

        category.position.set(distance, 0.0, 0.0);

        orbit.add(category);

        new TWEEN.Tween(orbit.rotation,{
          loop: true
      }).to({y: '+' + (Math.PI * 2)}, 4000 / speed);


        orbitContainer.add(orbit);
        scene.add(orbitContainer);


    }

    function init() {

        scene = new THREE.Scene();
        scene.background = new THREE.Color(0x202020);

        camera = new THREE.PerspectiveCamera(60, 4 / 3, 0.1, 10000.0);
        camera.position.set(20.0, 20.0, 20.0);
        camera.lookAt(new THREE.Vector3(0, 0, 0));

        renderer = new THREE.WebGLRenderer({antialias: false});
       document.addEventListener('mousedown', onDocumentMouseDown, false);
        controls = new OrbitControls(camera, renderer.domElement);

        var ambientLight = new THREE.AmbientLight(0xffffff, 0.1);
        scene.add(ambientLight);

        var solar = new THREE.Mesh(
            new THREE.SphereGeometry(2.5, 32, 32),
            new THREE.MeshBasicMaterial({emissive: 0xff5800, emissiveIntensity: 0.5, wireframe: true, color:'silver'})
        );

        var pointLight = new THREE.PointLight(0xffffff, 1.0, 300.0);
        solar.add(pointLight);
        scene.add(solar);

        createCategory('B',1.35, 7.2, 0.0, 'yellow', 0.4, "http://google.com" );
        createCategory('A',1.35, 11.0, 0.0, 'red', 0.3, "http://yahoo.com");
        createCategory('D Print', 1.35, 14.0, 0.0, 'blue', 0.2, "http://msn.com");
        createCategory('C Design', 1.35, 17.3, 0.0, 'green', 0.1, "http://facebook.com");
        createCategory('N', 1.35, 12.2, 5.0, 'pink', 0.4, "http://stackoverflow.com");

        window.addEventListener('resize', onWindowResize, false);
        onWindowResize();

        document.body.appendChild(renderer.domElement);
    }
    function onDocumentMouseDown(event) {
      event.preventDefault();


          var raycaster = new THREE.Raycaster(); 
          var mouse = new THREE.Vector2(); 
          mouse.x = ( event.clientX / renderer.domElement.clientWidth ) * 2 - 1;
          mouse.y = - ( event.clientY / renderer.domElement.clientHeight ) * 2 + 1;
          raycaster.setFromCamera( mouse, camera );

          var intersects = raycaster.intersectObjects(orbitContainer);
      if (intersects.length === 0) {
          window.open(orbitContainer.userData.URL);
      }
  }
    function onWindowResize() {
        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();
        renderer.setSize(window.innerWidth, window.innerHeight);
    }

    function animate() {

        controls.update();

        renderer.render(scene, camera);
        requestAnimationFrame(animate);
    }

  }

Answer №1

There are a couple of issues in your code:

Issue 1:

The code redirects me to the URL of the last planet

This happens because you're using the same global variable orbitContainer for creating multiple categories. Every time you call createCategory, the URL value gets overwritten. So, when you use

window.open(orbitContainer.userData.URL);
, it opens the URL of the last one you set. This is demonstrated by the following sequence:

orbitContainer.userData.URL = "http://google.com";
orbitContainer.userData.URL = "http://yahoo.com";
orbitContainer.userData.URL = "http://msn.com";
orbitContainer.userData.URL = "http://facebook.com";
orbitContainer.userData.URL = "http://stackoverflow.com";

window.open(orbitContainer.userData.URL); // <- this opens stackoverflow

Solution: Retrieve the URL from the raycaster result:

intersects = raycaster.intersectObjects( scene.children );

if (intersects.length > 0) {
    window.open(intersects[0].object.userData.URL);
}

Issue 2:

Clicking anywhere on the canvas triggers an action

This occurs because you're checking explicitly for zero intersections like this:

if (intersects.length === 0) {
    window.open(orbitContainer.userData.URL);
}

You should actually be looking for intersections with if (intersects.length > 0) as illustrated in the solution above.

Additionally, ensure that you're performing raycasting with the scene's children:

raycaster.intersectObjects( scene.children );
instead of using orbitContainer. This is crucial as every new category creation overwrites the old data and may not contain all the objects needed.

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

What is the best way to verify an array of objects within an asynchronous function?

I am struggling with validating an array of objects being sent to the server. It seems that my current code is not working properly when the array is empty or if the objects within it are invalid. I'm confused about why it's not functioning as ex ...

After successfully executing an AJAX request three times, it encountered a failure

I have implemented a script to send instant messages to my database asynchronously. Here is the code: function sendMessage(content, thread_id, ghost_id) { var url = "ajax_submit_message.php"; var data = { content: content, thread_id: thread_id }; ...

Changing data in Chart.js, strategies for modifying data after chart creation!

Apologies if this question seems basic. The challenge I am facing is that I need to utilize the same data for multiple charts, but with slight variations in options for each chart. The data is as follows: var data = { labels: freq, datase ...

Utilizing RabbitMQ's amqp.node integration within a Node.js Express application

The RabbitMQ Javascript tutorials feature the use of the amqp.node client library amqp.connect('amqp://localhost', function(err, conn) { conn.createChannel(function(err, ch) { var q = 'hello'; ch.assertQueue(q, {durable: fal ...

What is the benefit of using $q.all() with a single promise in AngularJS?

As I delve into this codebase, one snippet keeps popping up: $q.all([promise]).then(responseFunc); However, I find this confusing. After reading the documentation, I wonder why not simply use the following, as it's just a single promise... promise. ...

Error: Certain Prisma model mappings are not being generated

In my schema.prisma file, I have noticed that some models are not generating their @@map for use in the client. model ContentFilter { id Int @id @default(autoincrement()) blurriness Float? @default(0.3) adult ...

What is the significance of -= and += operators in JavaScript programming language?

I'm puzzled by the mathematical process behind this JavaScript code, which results in -11. let x = 2; let y = 4; console.log(x -= y += 9) ...

How to access event.target in Internet Explorer 8 with unobtrusive Javascript

Here is a function that retrieves the target element from a dropdown menu: function getTarget(evt){ var targetElement = null; //if it is a standard browser if (typeof evt.target != 'undefined'){ targetElement = evt.target; } //otherwise ...

"Enhance your Angular configuration with the powerful ngBootbox plugin

Is there a way to permanently change the locale of ngBootbox? I tried adding an extra angular configuration: var app = angular.module('some_module', ['highcharts-ng', 'ui.router', 'oc.lazyLoad', 'ui.selec ...

Transferring data between jQuery and other global JavaScript variables

I'm facing a challenge when trying to make functions I created in jQuery access JavaScript values defined elsewhere. For instance, I have a function set within my jQuery code. var parentImg = ''; //global variable. $(document).change(funct ...

issue with webpack-dev-server not refreshing after changes to HTML or Sass files

Here is the layout of my project: \root \webpack.config.js \public \ index.html \ ... \ css \ directives \ views \ dist (webpack output) \app.js ...

What is the best way to efficiently transmit Objects through AJAX utilizing bodyParser in node.js express?

Currently attempting to execute: $.ajax({ type:"POST", url:"/psychos", data:JSON.stringify(this.psycho) }) Upon reaching the server, I encounter the following: app.post("/psychos", function(request, respon ...

Ever since updating my jQuery version to 3.2.1, my ajax code seems to have stopped functioning properly

My program's ajax functionality was running smoothly with jquery version 1.7, but when I updated to version 3.3.1, the ajax part stopped working. I made sure to attach the ajax portion of my code after updating the jQuery version. In the PHP file, I s ...

Incorrect rendering of the <li> tag

I've been working on creating a simple web "to do list" but I've encountered an issue. When I manually add todos and click on them, the 'text-decoration: line-through;' property is ignored, and I can't see the strikethrough effect ...

When tapping on grid items in the Safari browser using React Material-UI, they mysteriously switch positions

I've encountered an issue with grid Items in my React MATERIAL-UI project, specifically in the Safari browser. The problem does not occur in Chrome or Firefox. Within the grid, there are checkboxes that move from one place to another when clicked, a ...

Translating Encryption from Javascript to Ruby

I have an application which utilizes HTML5 caching to enable offline functionality. When the app is offline, information is stored using JavaScript in localStorage and then transmitted to the server once online connectivity is restored. I am interested in ...

Creating an HTML Canvas effect where images are placed onto another image

Looking to create a similar effect as seen on this website () On this site, users can upload their images (4000 * 400) and have the option to add Mickey Mouse ears over their image before saving it. The Mickey Mouse ear is resizable from all four sides f ...

Attempting to initiate an AJAX request to an API

Hey everyone, I've been working on making an AJAX API call to Giphy but I keep receiving 'undefined' as a response. Can anyone offer some advice on how to troubleshoot and fix this issue? Thanks in advance for your help! var topics = ["Drak ...

Javascript is utilized to populate text within a div, although the animation is exclusively applied to the initial text

I am currently working on designing a landing page that showcases a dynamic display of rotating texts with a typewriter-like animation effect. While I have successfully implemented the animation for the first text, I am facing an issue where the subsequent ...

One webpage with various states managed by the URL conducted

After conducting a thorough search, I find it challenging to identify the precise terminology for my current inquiry. Mainly, my objective is to display a particular page state (showing/hiding a div) based on the URL. On a single page containing three di ...