Adding html to sprite before adding as a location marker to earth sphere?

I have 3D Earth displaying. I draw a sphere, then wrap it in a texture, add a sprite image, then group it and add it to the scene.

My end goal is to have markers for certain cities. Each city will have a status(color changes based on status). The way I am currently adding the marker is as a sprite image. I don’t want to have to create different color variants of the sprite image, and exchange the image based on the status. I would rather have the marker be HTML/CSS, with an ID or Class so that I can update the color via Javascript when the status changes. I was thinking since I already have a sprite image working as my marker, I could just append some html element with an ID to it before it gets added?

I’m not sure the best way to go about doing this. Should I be using something different than Sprites to add my markers? To allow for updating and changing colors? This is more of an “I don’t know which direction to go” question.

My current javascript:

var earthContainer;

var camera, scene, renderer;

var group, text, plane;

var targetRotationX = 0;
var targetRotationOnMouseDownX = 0;

var targetRotationY = 0;
var targetRotationOnMouseDownY = 0;

var mouseX = 0;
var mouseXOnMouseDown = 0;

var mouseY = 0;
var mouseYOnMouseDown = 0;

var windowWidth = window.innerWidth;
var windowHeight = window.innerHeight;

var windowHalfX = windowWidth / 2;
var windowHalfY = windowHeight / 2;

var finalRotationY;

init();
animate();

function init() {
    
    var VIEW_ANGLE = 45; //Camera frustum vertical field of view, from bottom to top of view, in degrees. Default is 50.
    var ASPECT = windowWidth / windowHeight; //Camera frustum aspect ratio, usually the canvas width / canvas height. Default is 1 (square canvas).
    var NEAR = 0.1; //Camera frustum near plane. Default is 0.1.
    var FAR = 10000; //Camera frustum far plane. Default is 2000.
    
    camera = new THREE.PerspectiveCamera( VIEW_ANGLE, ASPECT, NEAR, FAR );
    camera.position.set(0, 0, 600);

    scene = new THREE.Scene();
    //scene.background = new THREE.Color("#343A40");
    scene.add(camera);

    //Create the globe
    const RADIUS = 200;
    const SEGMENTS = 50;
    const RINGS = 50;

    //Create group to hold sphere and texture
    group = new THREE.Group();
    scene.add(group);

    //Create sphere and texture, and mesh together using texture loader
    var loader = new THREE.TextureLoader();

    loader.load( '/images/world_on_fire.jpg', function ( texture ) {

        // Create the sphere
        var sphere = new THREE.SphereGeometry( RADIUS, SEGMENTS, RINGS );
        // Map the texture to the material. 
        var material = new THREE.MeshBasicMaterial( { map: texture, overdraw: 0.5, transparent: true, opacity: 0.9 } );
        // Create a new mesh with sphere geometry.
        var mesh = new THREE.Mesh( sphere, material );

        // Add mesh to globe
        group.add(mesh);

        //sprites
        var spriteMap = new THREE.TextureLoader().load( "/images/marker.png" );
        var spriteMaterial = new THREE.SpriteMaterial( { map: spriteMap } );
        var sprite = new THREE.Sprite( spriteMaterial );
        sprite.position.set(-81, 127, 141); //VAFB (x and y are 2D Coordinates, z is height)
        sprite.scale.set(25,25,25);
        group.add( sprite );
        
    });
    
    renderer = new THREE.WebGLRenderer( { antialias: true, alpha: true } );
        //Create orbit controls
    const controls = new THREE.OrbitControls(camera, renderer.domElement);
    controls.enableRotate = false;

    earthContainer = $('#earth_container'); //Getting dom element that we will attach to the scene.
    renderer.setSize(windowWidth, windowHeight); //set size of renderer to user's screen/browser window's width and height.
    earthContainer.append(renderer.domElement);

    document.addEventListener( 'mousedown', onDocumentMouseDown, false );
    document.addEventListener( 'touchstart', onDocumentTouchStart, false );
    document.addEventListener( 'touchmove', onDocumentTouchMove, false );
    window.addEventListener( 'resize', onWindowResize, false );

}

function onWindowResize() {

    windowHalfX = window.innerWidth / 2;
    windowHalfY = window.innerHeight / 2;

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

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

function onDocumentMouseDown( event ) {

    event.preventDefault();

    document.addEventListener( 'mousemove', onDocumentMouseMove, false );
    document.addEventListener( 'mouseup', onDocumentMouseUp, false );
    document.addEventListener( 'mouseout', onDocumentMouseOut, false );

    mouseXOnMouseDown = event.clientX - windowHalfX;
    targetRotationOnMouseDownX = targetRotationX;

    mouseYOnMouseDown = event.clientY - windowHalfY;
    targetRotationOnMouseDownY = targetRotationY;

}

function onDocumentMouseMove( event ) {

    mouseX = event.clientX - windowHalfX;
    mouseY = event.clientY - windowHalfY;

    targetRotationY = targetRotationOnMouseDownY + (mouseY - mouseYOnMouseDown) * 0.02;
    targetRotationX = targetRotationOnMouseDownX + (mouseX - mouseXOnMouseDown) * 0.02;

}

function onDocumentMouseUp( event ) {

    document.removeEventListener( 'mousemove', onDocumentMouseMove, false );
    document.removeEventListener( 'mouseup', onDocumentMouseUp, false );
    document.removeEventListener( 'mouseout', onDocumentMouseOut, false );

}

function onDocumentMouseOut( event ) {

    document.removeEventListener( 'mousemove', onDocumentMouseMove, false );
    document.removeEventListener( 'mouseup', onDocumentMouseUp, false );
    document.removeEventListener( 'mouseout', onDocumentMouseOut, false );

}

function onDocumentTouchStart( event ) {

    if ( event.touches.length == 1 ) {

        event.preventDefault();

        mouseXOnMouseDown = event.touches[ 0 ].pageX - windowHalfX;
        targetRotationOnMouseDownX = targetRotationX;

        mouseYOnMouseDown = event.touches[ 0 ].pageY - windowHalfY;
        targetRotationOnMouseDownY = targetRotationY;

    }

}

function onDocumentTouchMove( event ) {

    if ( event.touches.length == 1 ) {

        event.preventDefault();

        mouseX = event.touches[ 0 ].pageX - windowHalfX;
        targetRotationX = targetRotationOnMouseDownX + ( mouseX - mouseXOnMouseDown ) * 0.05;

        mouseY = event.touches[ 0 ].pageY - windowHalfY;
        targetRotationY = targetRotationOnMouseDownY + (mouseY - mouseYOnMouseDown) * 0.05;

    }

}

function animate() {

    requestAnimationFrame( animate );

    render();
}

function render() {
    //horizontal rotation   
    group.rotation.y += ( targetRotationX - group.rotation.y ) * 0.1;

    //vertical rotation 
    finalRotationY = (targetRotationY - group.rotation.x); 
    //group.rotation.x += finalRotationY * 0.05;

    //finalRotationY = (targetRotationY - group.rotation.x);  
    if (group.rotation.x  <= 1 && group.rotation.x >= -1 ) {
        group.rotation.x += finalRotationY * 0.1;
    }
    if (group.rotation.x  > 1 ) {
        group.rotation.x = 1
    }

    if (group.rotation.x  < -1 ) {
        group.rotation.x = -1
    }

    renderer.render( scene, camera );
}

Index.html:





How about using the approach from the following example:

https://threejs.org/examples/css2d_label

CSS2DRenderer is often used to render labels via HTML/CSS.

I will give this a shot! Thank you

So I have my label showing! However, my earth is looking very bad quality. I have a good texture map image that is high quality, not sure what is going on. In this example, they use SphereBufferGeometry instead of SphereGeometry. Also, the material uses MeshPhongMaterial instead of MeshBasicMaterial. Could this be causing the issue with quality?

Another annoying thing. My earth is displaying as all black, unless I put directional lighting on it. Can I get rid of the black/shadow? So that I can also remove the lighting?
UPDATE: The bad quality was actually my image. I upgraded from 1k to 8k image texture, png file format.

 const EARTH_RADIUS = 200;
const EARTH_SEGMENTS = 50;
const EARTH_RINGS = 50;

camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 10000);
camera.position.set(0, 0, 600);

scene = new THREE.Scene();

var light = new THREE.PointLight(0xffffff, 0.9);
camera.add(light);

scene.add(camera);

scene.background = new THREE.Color("#343A40");

var earthGeometry = new THREE.SphereBufferGeometry(EARTH_RADIUS, EARTH_SEGMENTS, EARTH_RINGS);
var earthMaterial = new THREE.MeshPhongMaterial({
    map: textureLoader.load('../images/earthmap1k.jpg'),
    normalScale: new THREE.Vector2(1, 1)
});
earth = new THREE.Mesh(earthGeometry, earthMaterial);
scene.add(earth);