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: