Tips for avoiding label overlap in JavaScript programming

I am having some trouble adding labels to a sphere. Only one label is attaching correctly, while the rest are overlapping in the corner of the screen. I have attached an image to show the issue. It may be a CSS problem, but I'm not entirely sure. Below is the full code. Any help with this problem would be greatly appreciated.

div.spritelabel {
position:absolute;
top:0px;
left:0px;
color:#0000FF;
font-family: 'Trebuchet MS', sans-serif;
font-size:22px;
font-weight:bold;
line-height:20px;
text-align: left;
padding:5px;

-webkit-box-shadow: 0px 4px 8px -3px rgba(0,0,0,0.75);
-moz-box-shadow: 0px 4px 8px -3px rgba(0,0,0,0.75);
box-shadow: 0px 4px 8px -5px rgba(0,0,0,0.75);
background:rgba(255, 255, 255, 0.8 );
}
a:link {color: brown; background-color: transparent; text-decoration: none;}
a:visited{color: green; background-color: transparent; text-decoration: none;}
a:hover{color: red; background-color: transparent; text-decoration: underline;} 
a:active {color: yellow; background-color: transparent; text-decoration: underline;}

window.onload = createsphere();

function createsphere() 
{
var sprite,controls,scene,camera,renderer;
var spritearray = [];
spritearray[0] = {"name": "North", "lat":0, "lon": 10};
spritearray[1] = {"name": "south", "lat":0, "lon": 20};
spritearray[2] = {"name": "East", "lat":0, "lon": 30};
spritearray[3] = {"name": "west", "lat":0, "lon": 40};
function convertlatlonToVec3(lat, lon)
{
    lat = lat * Math.PI / 180.0;
    lon = -lon * Math.PI /180.0;
    return new THREE.Vector3(
        Math.cos(lat)* Math.sin(lon),
        Math.sin(lat)* Math.sin(lon),
        Math.cos(lat));

}

function labelBox(Ncardinal, radius, domElement)
{
    this.screenVector = new THREE.Vector3(0, 0, 0);
    this.position = convertlatlonToVec3(Ncardinal.lat,Ncardinal.lon).multiplyScalar(radius);
    this.box = document.createElement('div');
    a = document.createElement('a');
    a.innerHTML = Ncardinal.name;
    a.href ='http://www.google.de';
    this.box.className = "spritelabel";
    this.box.appendChild(a);

    this.domElement = domElement;
    this.domElement.appendChild(this.box);
}

labelBox.prototype.update = function()
{
this.screenVector.copy(this.position);  
this.screenVector.project(camera);

var posx = Math.round((this.screenVector.x + 1)*   this.domElement.offsetWidth/2);
var posy = Math.round((1 - this.screenVector.y)* this.domElement.offsetHeight/2);

var boundingRect = this.box.getBoundingClientRect();

//update the box overlays position
this.box.style.left = (posx - boundingRect.width) + 'px';
this.box.style.top = posy + 'px';

};



function init() 
        {
            scene = new THREE.Scene();
            camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);
            camera.position.y = 1;
            camera.position.z = 5;

            var width = window.innerWidth;
            var height = window.innerHeight;
            renderer = new THREE.WebGLRenderer({antialias:true});
            renderer.setSize(width, height);
            document.body.appendChild(renderer.domElement);






            var radius = 2.5;
            var spheregeometry = new THREE.SphereGeometry(radius, 20, 20, 0, -6.283, 1, 1);
            var texture =  THREE.ImageUtils.loadTexture ('newimage/crate.jpg');
            texture.minFilter = THREE.NearestFilter;
            var spherematerial = new THREE.MeshBasicMaterial({map: texture});
            var sphere = new THREE.Mesh(spheregeometry, spherematerial);

            scene.add(sphere);
            scene.add(camera);
            scene.autoUpdate = true;

            controls = new THREE.OrbitControls(camera, renderer.domElement);
            controls.minPolarAngle = Math.PI/4;
            controls.maxPolarAngle = 3*Math.PI/4;

            for(var i = 0; i < spritearray.length; i++)
            {
                var Ncardinal = spritearray[i];
                sprite =  new labelBox(Ncardinal, radius, document.body);
                var marker = new THREE.Mesh(new THREE.SphereGeometry(0.05, 30, 30));
                marker.position.copy(sprite.position);
                scene.add(marker);
            }
        }

        function animate() {

        sprite.update();
        requestAnimationFrame(animate); 
        controls.update();
        renderer.render(scene, camera);
        }
        init();
        animate();
    }

Answer №1

Take a look at how the setup is structured

for(var i = 0; i< spritearray.length;i++)
        {
            var Ncardinal = spritearray[i];
            sprite =  new labelBox(Ncardinal, radius, document.body);
            var marker = new THREE.Mesh(new THREE.SphereGeometry(0.05, 30, 30));
            marker.position.copy(sprite.position);
            scene.add(marker);
        }

Within your

function animate() {

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

During initialization, it sets the sprite to be the last item in the array, which is the "West" labelBox.

In the animate function, update is only called on the last sprite set. To address this issue, store the sprites in an array.

var spriteboxes = [];

Save them within the sprite loop

        for(var i = 0; i< spritearray.length;i++)
        {
            var Ncardinal = spritearray[i];
            sprite =  new labelBox(Ncardinal, radius, document.body);
            var marker = new THREE.Mesh(new THREE.SphereGeometry(0.05, 30, 30));
            marker.position.copy(sprite.position);
            scene.add(marker);
            spriteboxes.push(sprite);
        }

Update the animate method accordingly

function animate() {
    spriteboxes.forEach(function(e) { e.update()} );
    sprite.update();
    requestAnimationFrame(animate); 
    controls.update();
    renderer.render(scene, 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

Understanding the functionality of the Array.prototype.map() method when used with JavaScript Objects

Experimenting with code: let obj ={}; let newItems = ["Apple", "Banana", "Carrot", "Donut"].map(item => { obj.count= Math.random()*item.length; obj.itemName= item; return obj; }); console.log(newItems); The output ...

Incorporate a smooth infinite scroll feature in a CSS carousel that seamlessly loops without

Looking for a solution to the carousel jerk issue when it reaches the end of the loop? Is there a way to seamlessly loop start without any noticeable interruptions? Here is the code in question. Avoiding the use of JavaScript, is there a method to achieve ...

asp.net menu control automatically hides items that exceed the width of the page

I'm currently using an asp.net menu control created from codebehind for a better user experience. However, when the browser is resized or the resolution is lower than intended, items that don't fit get pushed down to a second line. I want to hide ...

Disabling the loading of JavaScript on a Magento website

Seeking advice - I'm experiencing a delay on my website due to 3 unnecessary javascripts that are being loaded. Is there a way to prevent these scripts from loading or being searched for? Listed below is the website log where I am unable to locate jq ...

Resizing the Vue page to fit the viewport and using Flexbox to anchor the footer to the bottom

My Vue.js page structure consists of a navigation bar, main body content, and a footer: <template> <div class="flex_container"> <div class="container_navigation"> <nav-bar /> </div> < ...

Add elements to an array with express, Node.js, and MongoDB

I'm currently learning about the MERN stack and I'm working on creating users with empty queues to store telephone numbers in E.164 format. My goal is to add and remove these numbers from the queue (type: Array) based on API requests. However, I ...

Rendering a ImageBitMap/Image on an OffScreenCanvas using a web-worker

In my vue.js application, I have implemented vue-workers/web-workers to handle image processing tasks such as scaling and cropping in the background after a user uploads images. Due to the lack of support for Canvas and Image Object in web workers, I opte ...

A basic problem involving appending content using jQuery

I have encountered a puzzling issue. Whenever I attempt to insert new content into the <div> element using my JS code, it briefly appears and then disappears abruptly. I am unsure of the reason behind this behavior. Is there a way to prevent this fr ...

After replacing the Partial View with jQuery select picker, the CSS is not being applied

Encountering an issue ... I came across this helpful solution to swap out a partial view within a view. However, upon changing the partial view, the dropdown does not retain the default template CSS. To address this, I utilized the following jQuery code to ...

Use Javascript to toggle the display to none for a specific table row (tr)

Is there a way to implement JavaScript code that will hide a specific table row using display:none;, and then reveal it again when a button is clicked? ...

Having trouble with Angular UI Select functionality?

I have integrated the angular ui select library from https://github.com/angular-ui/ui-select into my project. Instead of using the traditional select element, I am now utilizing the ui-select directive. This is a snippet of my code: <select class=" ...

Configuring bitfinex-api-node with Node.js to efficiently handle data from the websocket connection

Apologies for the vague title of this question, as I am not well-versed in programming and even less so in node.js My goal is simple: I aim to utilize the bitfinex-api-node package (a node.js wrapper for the bitfinex cryptocurrency exchange) that I instal ...

How can I customize the offset and achieve a smooth transition to each section using Jquery or JavaScript in Bootstrap scrollspy?

My goal is to customize the scrollspy offset and create a smooth transition between sections without relying on plugins or data attributes. I have a JavaScript function that sets the offset for scrollspy, but I need help adding a smooth animated scroll eff ...

JavaScript keeps repeating as you perform basic addition operations

Dealing with a similar issue where things are not adding up correctly, I encountered a problem in a previous question about JavaScript variables only concatenating as strings. The pure JavaScript solution worked fine, so I have now consolidated all the cod ...

Tips on implementing SCSS styles in my create-react-app application along with Material UI components?

I recently developed a React app using Create-React-App, and now I am looking to incorporate Material UI with styling through SCSS. https://i.sstatic.net/JLEjX.png To manage my styles, I created a main.css file using node-sass. While attempting to apply ...

Binding variables in JSX with Vue.js scope involves connecting data directly to the template

I am in search of code similar to this: <div v-for="item in items" :key="item"> {{ item }} ... <div v-with:newValue="calculateValue(item)"> {{ newValue }} </div> </div> I'm not sure what to call this pattern, but ...

Custom server not required for optional dynamic routes in NextJS version 9.5.2

I am attempting to implement localized routes with an optional first parameter in the form of /lang?/../../, all without requiring a custom server. Starting from NextJS version 9.5, there is a new dynamic optional parameters feature that can be set up by c ...

error": "message": "Property 'name' cannot be read because it is undefined

I've encountered an issue while creating a route to handle POST data. Despite testing it on postman, I have not been able to find a solution for the problem that many others seem to be facing as well. It seems like the 'name' field is not be ...

Is there an error in the way three.js calculates spotlight reflections?

Looking for advice on how to achieve a spotlight reflection like the one seen here: to look similar to the reflection seen here: . Is there a way to make the reflection appear more natural and get reflected to the camera? It seems odd that it doesn't ...

Strategies for Implementing Multi-Step Password Form Validation

Currently, I am using https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_form_steps as the foundation of my form with some adjustments. Validation is functioning correctly where empty fields disable the next button. However, when I attempt to add ...