As I explore THREE.js to showcase a 3D rotating earth on the web, my goal is to also have an image surrounding the spinning globe.
Despite trying various methods, none seemed to work out for me. The image loader option I attempted failed to display anything at all.
var img = new THREE.ImageLoader();
img.load("texture/circle.png");
Essentially, I aimed for something similar to this reference: https://i.sstatic.net/2ZRZZ.jpg
The globe animation functions smoothly, yet incorporating the circular image overlay as depicted in the provided image remains my target.
Below is the script snippet:
<script>
var container, stats, raycaster;
var camera, scene, renderer;
var group;
var mouseX = 0, mouseY = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
init();
animate();
function init() {
container = document.getElementById( 'container' );
camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 2000 );
camera.position.z = 500;
scene = new THREE.Scene();
group = new THREE.Object3D();
scene.add( group );
// earth
var loader = new THREE.TextureLoader();
loader.load( 'textures/1.jpg', function ( texture ) {
var geometry = new THREE.SphereGeometry( 200, 20, 20 );
var material = new THREE.MeshBasicMaterial( { map: texture, overdraw: true } );
var mesh = new THREE.Mesh( geometry, material );
group.add( mesh );
raycaster = new THREE.Raycaster();
} );
// shadow
var canvas = document.createElement( 'canvas' );
canvas.width = 128;
canvas.height = 128;
var context = canvas.getContext( '2d' );
var gradient = context.createRadialGradient(
canvas.width / 2,
canvas.height / 2,
0,
canvas.width / 2,
canvas.height / 2,
canvas.width / 2
);
context.fillStyle = gradient;
context.fillRect( 0, 0, canvas.width, canvas.height );
var texture = new THREE.Texture( canvas );
texture.needsUpdate = true;
var geometry = new THREE.PlaneGeometry( 300, 300, 3, 3 );
var material = new THREE.MeshBasicMaterial( { map: texture, overdraw: true } );
var mesh = new THREE.Mesh( geometry, material );
mesh.position.y = - 250;
group.add( mesh );
renderer = new THREE.CanvasRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
container.appendChild( stats.domElement );
document.addEventListener( 'mousemove', onDocumentMouseMove, 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 onDocumentMouseMove( event ) {
mouseX = ( event.clientX - windowHalfX );
mouseY = ( event.clientY - windowHalfY );
}
function animate() {
requestAnimationFrame( animate );
render();
stats.update();
}
function render() {
camera.lookAt( scene.position );
group.rotation.y -= 0.001;
renderer.render( scene, camera );
}
</script>