Open Earth View - Tutorial
Jump to navigation
Jump to search
Introduction
The goal is to show how we can easily create a navigation system around the earth easily in web and 3D context.
Environment
We'll rely massively on three.js library and its OrbitControls example
Sources
Hack the system
We'll modify three.js OrbitControls source code just a little bit to get "panUp()" and "panLeft()" methods publicly available to override them from our main page.
Add this:
this.panLeft = panLeft;
this.PanUp = panUp;
And replace function calls by their public methods:
# panLeft( 2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix );
# panUp( 2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix );
scope.panLeft( 2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix );
scope.panUp( 2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix );
And now, back to the main html page and three.js 3D scene: Put earth on the scene:
loader.load( 'https://github.com/mrdoob/three.js/raw/dev/examples/textures/planets/earth_atmos_4096.jpg', function ( texture ) {
geometry = new THREE.SphereGeometry( R, 32, 32 );
material = new THREE.MeshBasicMaterial( { map: texture, overdraw: 0.5 } );
earth = new THREE.Mesh( geometry, material );
earth.position.z = -R;
earth.updateMatrix();
scene.add( earth );
} );
And make the earth itself move around itself:
controls = new THREE.OrbitControls( camera, renderer.domElement );
controls.mouseButtons = { LEFT: THREE.MOUSE.RIGHT, MIDDLE: THREE.MOUSE.MIDDLE, RIGHT: THREE.MOUSE.LEFT };
# (...)
controls.panLeft = function ( distance ) {
earth.rotation.y += (distance / R) * (Math.cos(controls.getAzimuthalAngle())) / ( Math.max (0.2, Math.cos(earth.rotation.x)));
theta = -(distance / R) * (Math.sin(controls.getAzimuthalAngle()));
earth.rotation.x = Math.max(Math.min(earth.rotation.x + theta, Math.PI / 2), -Math.PI / 2);
};
controls.panUp = function ( distance ) {
earth.rotation.y += (distance / R) * (Math.sin(controls.getAzimuthalAngle())) / ( Math.max (0.2, Math.cos(earth.rotation.x)));
theta = (distance / R) * (Math.cos(controls.getAzimuthalAngle()));
earth.rotation.x = Math.max(Math.min(earth.rotation.x + theta, Math.PI / 2), -Math.PI / 2);
};
Demo
Screenshot: