Skip to content

Instantly share code, notes, and snippets.

@xyztlp
Forked from marcopompili/Globe.js
Created June 2, 2023 13:24
Show Gist options
  • Select an option

  • Save xyztlp/956b3367e25a7c92d20170b5ddf8233e to your computer and use it in GitHub Desktop.

Select an option

Save xyztlp/956b3367e25a7c92d20170b5ddf8233e to your computer and use it in GitHub Desktop.

Revisions

  1. Marco Pompili revised this gist Nov 14, 2016. 1 changed file with 0 additions and 0 deletions.
    Binary file modified wateretopo.png
    Loading
    Sorry, something went wrong. Reload?
    Sorry, we cannot display this file.
    Sorry, this file is invalid so it cannot be displayed.
  2. Marco Pompili revised this gist Nov 14, 2016. 2 changed files with 1 addition and 276 deletions.
    2 changes: 1 addition & 1 deletion index.html
    Original file line number Diff line number Diff line change
    @@ -11,7 +11,7 @@
    </style>
    </head>
    <body>
    <script src="three.min.js" charset="utf-8"></script>
    <script src="http://cdnjs.cloudflare.com/ajax/libs/three.js/r82/three.min.js" charset="utf-8"></script>
    <script src="TrackballControls.js" charset="utf-8"></script>
    <script src="Globe.js" charset="utf-8"></script>
    <script src="scene.js" charset="utf-8"></script>
    275 changes: 0 additions & 275 deletions three.min.js
    0 additions, 275 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
  3. Marco Pompili revised this gist Nov 14, 2016. 4 changed files with 134 additions and 698 deletions.
    163 changes: 81 additions & 82 deletions Globe.js
    Original file line number Diff line number Diff line change
    @@ -1,82 +1,81 @@
    var Globe = function (radius, segments) {

    THREE.Object3D.call(this);

    this.name = "Globe";

    var that = this;

    // instantiate a loader
    var loader = new THREE.TextureLoader();

    // earth textures
    var textures = {
    'map': {
    url: 'relief.jpg',
    val: undefined
    },
    'bumpMap': {
    url: 'elev_bump_4k.jpg',
    val: undefined
    },
    'specularMap': {
    url: 'wateretopo.png',
    val: undefined
    }
    };

    var texturePromises = [], path = './';

    for (var key in textures) {
    texturePromises.push(new Promise((resolve, reject) => {
    var entry = textures[key]
    var url = path + entry.url
    loader.load(url,
    texture => {
    entry.val = texture;
    if (entry.val instanceof THREE.Texture) resolve(entry);
    },
    xhr => {
    console.log(url + ' ' + (xhr.loaded / xhr.total * 100) +
    '% loaded');
    },
    xhr => {
    reject(new Error(xhr +
    'An error occurred loading while loading: ' +
    entry.url));
    }
    );
    }));
    }

    // load the geometry and the textures
    Promise.all(texturePromises).then(loadedTextures => {
    var geometry = new THREE.SphereGeometry(radius, segments, segments);
    geometry.rotateY(THREE.Math.degToRad(-90));
    var material = new THREE.MeshPhongMaterial({
    map: textures.map.val,
    bumpMap: textures.bumpMap.val,
    bumpScale: 0.005,
    specularMap: textures.specularMap.val,
    specular: new THREE.Color('grey')
    });

    var earth = that.earth = new THREE.Mesh(geometry, material);
    that.add(earth);
    });

    // clouds
    loader.load('n_amer_clouds.png', map => {
    var geometry = new THREE.SphereGeometry(radius + .05, segments, segments);
    var material = new THREE.MeshPhongMaterial({
    map: map,
    transparent: true
    });

    var clouds = that.clouds = new THREE.Mesh(geometry, material);
    that.add(clouds);
    });
    }

    Globe.prototype = Object.create(THREE.Object3D.prototype);
    Globe.prototype.constructor = Globe;
    var Globe = function (radius, segments) {

    THREE.Object3D.call(this);

    this.name = "Globe";

    var that = this;

    // instantiate a loader
    var loader = new THREE.TextureLoader();

    // earth textures
    var textures = {
    'map': {
    url: 'relief.jpg',
    val: undefined
    },
    'bumpMap': {
    url: 'elev_bump_4k.jpg',
    val: undefined
    },
    'specularMap': {
    url: 'wateretopo.png',
    val: undefined
    }
    };

    var texturePromises = [], path = './';

    for (var key in textures) {
    texturePromises.push(new Promise((resolve, reject) => {
    var entry = textures[key]
    var url = path + entry.url
    loader.load(url,
    texture => {
    entry.val = texture;
    if (entry.val instanceof THREE.Texture) resolve(entry);
    },
    xhr => {
    console.log(url + ' ' + (xhr.loaded / xhr.total * 100) +
    '% loaded');
    },
    xhr => {
    reject(new Error(xhr +
    'An error occurred loading while loading: ' +
    entry.url));
    }
    );
    }));
    }

    // load the geometry and the textures
    Promise.all(texturePromises).then(loadedTextures => {
    var geometry = new THREE.SphereGeometry(radius, segments, segments);
    var material = new THREE.MeshPhongMaterial({
    map: textures.map.val,
    bumpMap: textures.bumpMap.val,
    bumpScale: 0.005,
    specularMap: textures.specularMap.val,
    specular: new THREE.Color('grey')
    });

    var earth = that.earth = new THREE.Mesh(geometry, material);
    that.add(earth);
    });

    // clouds
    loader.load('n_amer_clouds.png', map => {
    var geometry = new THREE.SphereGeometry(radius + .05, segments, segments);
    var material = new THREE.MeshPhongMaterial({
    map: map,
    transparent: true
    });

    var clouds = that.clouds = new THREE.Mesh(geometry, material);
    that.add(clouds);
    });
    }

    Globe.prototype = Object.create(THREE.Object3D.prototype);
    Globe.prototype.constructor = Globe;
    104 changes: 52 additions & 52 deletions scene.js
    Original file line number Diff line number Diff line change
    @@ -1,52 +1,52 @@
    var scene = new THREE.Scene();
    var ratio = window.innerWidth / window.innerHeight;
    var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight,
    0.1, 10000);

    camera.position.z = -50;

    var renderer = new THREE.WebGLRenderer({
    antialias: true
    });
    renderer.setPixelRatio(window.devicePixelRatio);
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.setClearColor(0x000000, 1);

    var canvas = renderer.domElement;
    canvas.style.display = "block";

    document.body.appendChild(canvas);

    // Enable controls
    var controls = new THREE.TrackballControls(camera);

    //Add lighting
    scene.add(new THREE.AmbientLight(0x333333));

    var light = new THREE.DirectionalLight(0xe4eef9, .7);
    light.position.set(12, 12, 8);
    scene.add(light);

    var radius = 9.99,
    segments = 32,
    rotation = 0;

    var globe = new Globe(radius, segments);

    scene.add(globe);

    // Render the image
    function render() {
    controls.update();

    if(globe.earth)
    globe.earth.rotation.y += 0.0005;

    if(globe.clouds)
    globe.clouds.rotation.y += 0.0003;

    requestAnimationFrame(render);
    renderer.render(scene, camera);
    }

    render();
    var scene = new THREE.Scene();
    var ratio = window.innerWidth / window.innerHeight;
    var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight,
    0.1, 10000);

    camera.position.z = -50;

    var renderer = new THREE.WebGLRenderer({
    antialias: true
    });
    renderer.setPixelRatio(window.devicePixelRatio);
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.setClearColor(0x000000, 1);

    var canvas = renderer.domElement;
    canvas.style.display = "block";

    document.body.appendChild(canvas);

    // Enable controls
    var controls = new THREE.TrackballControls(camera);

    //Add lighting
    scene.add(new THREE.AmbientLight(0x333333));

    var light = new THREE.DirectionalLight(0xe4eef9, .7);
    light.position.set(12, 12, 8);
    scene.add(light);

    var radius = 9.99,
    segments = 32,
    rotation = 0;

    var globe = new Globe(radius, segments);

    scene.add(globe);

    // Render the image
    function render() {
    controls.update();

    if(globe.earth)
    globe.earth.rotation.y += 0.0005;

    if(globe.clouds)
    globe.clouds.rotation.y += 0.0003;

    requestAnimationFrame(render);
    renderer.render(scene, camera);
    }

    render();
    565 changes: 1 addition & 564 deletions three.min.js
    1 addition, 564 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
    Binary file modified wateretopo.png
    Loading
    Sorry, something went wrong. Reload?
    Sorry, we cannot display this file.
    Sorry, this file is invalid so it cannot be displayed.
  4. Marco Pompili revised this gist Nov 14, 2016. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions scene.js
    Original file line number Diff line number Diff line change
    @@ -1,9 +1,9 @@
    var scene = new THREE.Scene();
    var ratio = window.innerWidth / window.innerHeight;
    var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight,
    0.1, 50);
    0.1, 10000);

    camera.position.z = -30;
    camera.position.z = -50;

    var renderer = new THREE.WebGLRenderer({
    antialias: true
  5. Marco Pompili revised this gist Nov 13, 2016. 9 changed files with 1579 additions and 3 deletions.
    82 changes: 82 additions & 0 deletions Globe.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,82 @@
    var Globe = function (radius, segments) {

    THREE.Object3D.call(this);

    this.name = "Globe";

    var that = this;

    // instantiate a loader
    var loader = new THREE.TextureLoader();

    // earth textures
    var textures = {
    'map': {
    url: 'relief.jpg',
    val: undefined
    },
    'bumpMap': {
    url: 'elev_bump_4k.jpg',
    val: undefined
    },
    'specularMap': {
    url: 'wateretopo.png',
    val: undefined
    }
    };

    var texturePromises = [], path = './';

    for (var key in textures) {
    texturePromises.push(new Promise((resolve, reject) => {
    var entry = textures[key]
    var url = path + entry.url
    loader.load(url,
    texture => {
    entry.val = texture;
    if (entry.val instanceof THREE.Texture) resolve(entry);
    },
    xhr => {
    console.log(url + ' ' + (xhr.loaded / xhr.total * 100) +
    '% loaded');
    },
    xhr => {
    reject(new Error(xhr +
    'An error occurred loading while loading: ' +
    entry.url));
    }
    );
    }));
    }

    // load the geometry and the textures
    Promise.all(texturePromises).then(loadedTextures => {
    var geometry = new THREE.SphereGeometry(radius, segments, segments);
    geometry.rotateY(THREE.Math.degToRad(-90));
    var material = new THREE.MeshPhongMaterial({
    map: textures.map.val,
    bumpMap: textures.bumpMap.val,
    bumpScale: 0.005,
    specularMap: textures.specularMap.val,
    specular: new THREE.Color('grey')
    });

    var earth = that.earth = new THREE.Mesh(geometry, material);
    that.add(earth);
    });

    // clouds
    loader.load('n_amer_clouds.png', map => {
    var geometry = new THREE.SphereGeometry(radius + .05, segments, segments);
    var material = new THREE.MeshPhongMaterial({
    map: map,
    transparent: true
    });

    var clouds = that.clouds = new THREE.Mesh(geometry, material);
    that.add(clouds);
    });
    }

    Globe.prototype = Object.create(THREE.Object3D.prototype);
    Globe.prototype.constructor = Globe;
    606 changes: 606 additions & 0 deletions TrackballControls.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,606 @@
    /**
    * @author Eberhard Graether / http://egraether.com/
    * @author Mark Lundin / http://mark-lundin.com
    * @author Simone Manini / http://daron1337.github.io
    * @author Luca Antiga / http://lantiga.github.io
    */

    THREE.TrackballControls = function ( object, domElement ) {

    var _this = this;
    var STATE = { NONE: - 1, ROTATE: 0, ZOOM: 1, PAN: 2, TOUCH_ROTATE: 3, TOUCH_ZOOM_PAN: 4 };

    this.object = object;
    this.domElement = ( domElement !== undefined ) ? domElement : document;

    // API

    this.enabled = true;

    this.screen = { left: 0, top: 0, width: 0, height: 0 };

    this.rotateSpeed = 1.0;
    this.zoomSpeed = 1.2;
    this.panSpeed = 0.3;

    this.noRotate = false;
    this.noZoom = false;
    this.noPan = false;

    this.staticMoving = false;
    this.dynamicDampingFactor = 0.2;

    this.minDistance = 0;
    this.maxDistance = Infinity;

    this.keys = [ 65 /*A*/, 83 /*S*/, 68 /*D*/ ];

    // internals

    this.target = new THREE.Vector3();

    var EPS = 0.000001;

    var lastPosition = new THREE.Vector3();

    var _state = STATE.NONE,
    _prevState = STATE.NONE,

    _eye = new THREE.Vector3(),

    _movePrev = new THREE.Vector2(),
    _moveCurr = new THREE.Vector2(),

    _lastAxis = new THREE.Vector3(),
    _lastAngle = 0,

    _zoomStart = new THREE.Vector2(),
    _zoomEnd = new THREE.Vector2(),

    _touchZoomDistanceStart = 0,
    _touchZoomDistanceEnd = 0,

    _panStart = new THREE.Vector2(),
    _panEnd = new THREE.Vector2();

    // for reset

    this.target0 = this.target.clone();
    this.position0 = this.object.position.clone();
    this.up0 = this.object.up.clone();

    // events

    var changeEvent = { type: 'change' };
    var startEvent = { type: 'start' };
    var endEvent = { type: 'end' };


    // methods

    this.handleResize = function () {

    if ( this.domElement === document ) {

    this.screen.left = 0;
    this.screen.top = 0;
    this.screen.width = window.innerWidth;
    this.screen.height = window.innerHeight;

    } else {

    var box = this.domElement.getBoundingClientRect();
    // adjustments come from similar code in the jquery offset() function
    var d = this.domElement.ownerDocument.documentElement;
    this.screen.left = box.left + window.pageXOffset - d.clientLeft;
    this.screen.top = box.top + window.pageYOffset - d.clientTop;
    this.screen.width = box.width;
    this.screen.height = box.height;

    }

    };

    this.handleEvent = function ( event ) {

    if ( typeof this[ event.type ] == 'function' ) {

    this[ event.type ]( event );

    }

    };

    var getMouseOnScreen = ( function () {

    var vector = new THREE.Vector2();

    return function getMouseOnScreen( pageX, pageY ) {

    vector.set(
    ( pageX - _this.screen.left ) / _this.screen.width,
    ( pageY - _this.screen.top ) / _this.screen.height
    );

    return vector;

    };

    }() );

    var getMouseOnCircle = ( function () {

    var vector = new THREE.Vector2();

    return function getMouseOnCircle( pageX, pageY ) {

    vector.set(
    ( ( pageX - _this.screen.width * 0.5 - _this.screen.left ) / ( _this.screen.width * 0.5 ) ),
    ( ( _this.screen.height + 2 * ( _this.screen.top - pageY ) ) / _this.screen.width ) // screen.width intentional
    );

    return vector;

    };

    }() );

    this.rotateCamera = ( function() {

    var axis = new THREE.Vector3(),
    quaternion = new THREE.Quaternion(),
    eyeDirection = new THREE.Vector3(),
    objectUpDirection = new THREE.Vector3(),
    objectSidewaysDirection = new THREE.Vector3(),
    moveDirection = new THREE.Vector3(),
    angle;

    return function rotateCamera() {

    moveDirection.set( _moveCurr.x - _movePrev.x, _moveCurr.y - _movePrev.y, 0 );
    angle = moveDirection.length();

    if ( angle ) {

    _eye.copy( _this.object.position ).sub( _this.target );

    eyeDirection.copy( _eye ).normalize();
    objectUpDirection.copy( _this.object.up ).normalize();
    objectSidewaysDirection.crossVectors( objectUpDirection, eyeDirection ).normalize();

    objectUpDirection.setLength( _moveCurr.y - _movePrev.y );
    objectSidewaysDirection.setLength( _moveCurr.x - _movePrev.x );

    moveDirection.copy( objectUpDirection.add( objectSidewaysDirection ) );

    axis.crossVectors( moveDirection, _eye ).normalize();

    angle *= _this.rotateSpeed;
    quaternion.setFromAxisAngle( axis, angle );

    _eye.applyQuaternion( quaternion );
    _this.object.up.applyQuaternion( quaternion );

    _lastAxis.copy( axis );
    _lastAngle = angle;

    } else if ( ! _this.staticMoving && _lastAngle ) {

    _lastAngle *= Math.sqrt( 1.0 - _this.dynamicDampingFactor );
    _eye.copy( _this.object.position ).sub( _this.target );
    quaternion.setFromAxisAngle( _lastAxis, _lastAngle );
    _eye.applyQuaternion( quaternion );
    _this.object.up.applyQuaternion( quaternion );

    }

    _movePrev.copy( _moveCurr );

    };

    }() );


    this.zoomCamera = function () {

    var factor;

    if ( _state === STATE.TOUCH_ZOOM_PAN ) {

    factor = _touchZoomDistanceStart / _touchZoomDistanceEnd;
    _touchZoomDistanceStart = _touchZoomDistanceEnd;
    _eye.multiplyScalar( factor );

    } else {

    factor = 1.0 + ( _zoomEnd.y - _zoomStart.y ) * _this.zoomSpeed;

    if ( factor !== 1.0 && factor > 0.0 ) {

    _eye.multiplyScalar( factor );

    }

    if ( _this.staticMoving ) {

    _zoomStart.copy( _zoomEnd );

    } else {

    _zoomStart.y += ( _zoomEnd.y - _zoomStart.y ) * this.dynamicDampingFactor;

    }

    }

    };

    this.panCamera = ( function() {

    var mouseChange = new THREE.Vector2(),
    objectUp = new THREE.Vector3(),
    pan = new THREE.Vector3();

    return function panCamera() {

    mouseChange.copy( _panEnd ).sub( _panStart );

    if ( mouseChange.lengthSq() ) {

    mouseChange.multiplyScalar( _eye.length() * _this.panSpeed );

    pan.copy( _eye ).cross( _this.object.up ).setLength( mouseChange.x );
    pan.add( objectUp.copy( _this.object.up ).setLength( mouseChange.y ) );

    _this.object.position.add( pan );
    _this.target.add( pan );

    if ( _this.staticMoving ) {

    _panStart.copy( _panEnd );

    } else {

    _panStart.add( mouseChange.subVectors( _panEnd, _panStart ).multiplyScalar( _this.dynamicDampingFactor ) );

    }

    }

    };

    }() );

    this.checkDistances = function () {

    if ( ! _this.noZoom || ! _this.noPan ) {

    if ( _eye.lengthSq() > _this.maxDistance * _this.maxDistance ) {

    _this.object.position.addVectors( _this.target, _eye.setLength( _this.maxDistance ) );
    _zoomStart.copy( _zoomEnd );

    }

    if ( _eye.lengthSq() < _this.minDistance * _this.minDistance ) {

    _this.object.position.addVectors( _this.target, _eye.setLength( _this.minDistance ) );
    _zoomStart.copy( _zoomEnd );

    }

    }

    };

    this.update = function () {

    _eye.subVectors( _this.object.position, _this.target );

    if ( ! _this.noRotate ) {

    _this.rotateCamera();

    }

    if ( ! _this.noZoom ) {

    _this.zoomCamera();

    }

    if ( ! _this.noPan ) {

    _this.panCamera();

    }

    _this.object.position.addVectors( _this.target, _eye );

    _this.checkDistances();

    _this.object.lookAt( _this.target );

    if ( lastPosition.distanceToSquared( _this.object.position ) > EPS ) {

    _this.dispatchEvent( changeEvent );

    lastPosition.copy( _this.object.position );

    }

    };

    this.reset = function () {

    _state = STATE.NONE;
    _prevState = STATE.NONE;

    _this.target.copy( _this.target0 );
    _this.object.position.copy( _this.position0 );
    _this.object.up.copy( _this.up0 );

    _eye.subVectors( _this.object.position, _this.target );

    _this.object.lookAt( _this.target );

    _this.dispatchEvent( changeEvent );

    lastPosition.copy( _this.object.position );

    };

    // listeners

    function keydown( event ) {

    if ( _this.enabled === false ) return;

    window.removeEventListener( 'keydown', keydown );

    _prevState = _state;

    if ( _state !== STATE.NONE ) {

    return;

    } else if ( event.keyCode === _this.keys[ STATE.ROTATE ] && ! _this.noRotate ) {

    _state = STATE.ROTATE;

    } else if ( event.keyCode === _this.keys[ STATE.ZOOM ] && ! _this.noZoom ) {

    _state = STATE.ZOOM;

    } else if ( event.keyCode === _this.keys[ STATE.PAN ] && ! _this.noPan ) {

    _state = STATE.PAN;

    }

    }

    function keyup( event ) {

    if ( _this.enabled === false ) return;

    _state = _prevState;

    window.addEventListener( 'keydown', keydown, false );

    }

    function mousedown( event ) {

    if ( _this.enabled === false ) return;

    event.preventDefault();
    event.stopPropagation();

    if ( _state === STATE.NONE ) {

    _state = event.button;

    }

    if ( _state === STATE.ROTATE && ! _this.noRotate ) {

    _moveCurr.copy( getMouseOnCircle( event.pageX, event.pageY ) );
    _movePrev.copy( _moveCurr );

    } else if ( _state === STATE.ZOOM && ! _this.noZoom ) {

    _zoomStart.copy( getMouseOnScreen( event.pageX, event.pageY ) );
    _zoomEnd.copy( _zoomStart );

    } else if ( _state === STATE.PAN && ! _this.noPan ) {

    _panStart.copy( getMouseOnScreen( event.pageX, event.pageY ) );
    _panEnd.copy( _panStart );

    }

    document.addEventListener( 'mousemove', mousemove, false );
    document.addEventListener( 'mouseup', mouseup, false );

    _this.dispatchEvent( startEvent );

    }

    function mousemove( event ) {

    if ( _this.enabled === false ) return;

    event.preventDefault();
    event.stopPropagation();

    if ( _state === STATE.ROTATE && ! _this.noRotate ) {

    _movePrev.copy( _moveCurr );
    _moveCurr.copy( getMouseOnCircle( event.pageX, event.pageY ) );

    } else if ( _state === STATE.ZOOM && ! _this.noZoom ) {

    _zoomEnd.copy( getMouseOnScreen( event.pageX, event.pageY ) );

    } else if ( _state === STATE.PAN && ! _this.noPan ) {

    _panEnd.copy( getMouseOnScreen( event.pageX, event.pageY ) );

    }

    }

    function mouseup( event ) {

    if ( _this.enabled === false ) return;

    event.preventDefault();
    event.stopPropagation();

    _state = STATE.NONE;

    document.removeEventListener( 'mousemove', mousemove );
    document.removeEventListener( 'mouseup', mouseup );
    _this.dispatchEvent( endEvent );

    }

    function mousewheel( event ) {

    if ( _this.enabled === false ) return;

    event.preventDefault();
    event.stopPropagation();

    _zoomStart.y -= event.deltaY * 0.01;

    _this.dispatchEvent( startEvent );
    _this.dispatchEvent( endEvent );

    }

    function touchstart( event ) {

    if ( _this.enabled === false ) return;

    switch ( event.touches.length ) {

    case 1:
    _state = STATE.TOUCH_ROTATE;
    _moveCurr.copy( getMouseOnCircle( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ) );
    _movePrev.copy( _moveCurr );
    break;

    default: // 2 or more
    _state = STATE.TOUCH_ZOOM_PAN;
    var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
    var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;
    _touchZoomDistanceEnd = _touchZoomDistanceStart = Math.sqrt( dx * dx + dy * dy );

    var x = ( event.touches[ 0 ].pageX + event.touches[ 1 ].pageX ) / 2;
    var y = ( event.touches[ 0 ].pageY + event.touches[ 1 ].pageY ) / 2;
    _panStart.copy( getMouseOnScreen( x, y ) );
    _panEnd.copy( _panStart );
    break;

    }

    _this.dispatchEvent( startEvent );

    }

    function touchmove( event ) {

    if ( _this.enabled === false ) return;

    event.preventDefault();
    event.stopPropagation();

    switch ( event.touches.length ) {

    case 1:
    _movePrev.copy( _moveCurr );
    _moveCurr.copy( getMouseOnCircle( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ) );
    break;

    default: // 2 or more
    var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
    var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;
    _touchZoomDistanceEnd = Math.sqrt( dx * dx + dy * dy );

    var x = ( event.touches[ 0 ].pageX + event.touches[ 1 ].pageX ) / 2;
    var y = ( event.touches[ 0 ].pageY + event.touches[ 1 ].pageY ) / 2;
    _panEnd.copy( getMouseOnScreen( x, y ) );
    break;

    }

    }

    function touchend( event ) {

    if ( _this.enabled === false ) return;

    switch ( event.touches.length ) {

    case 0:
    _state = STATE.NONE;
    break;

    case 1:
    _state = STATE.TOUCH_ROTATE;
    _moveCurr.copy( getMouseOnCircle( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ) );
    _movePrev.copy( _moveCurr );
    break;

    }

    _this.dispatchEvent( endEvent );

    }

    function contextmenu( event ) {

    event.preventDefault();

    }

    this.dispose = function() {

    this.domElement.removeEventListener( 'contextmenu', contextmenu, false );
    this.domElement.removeEventListener( 'mousedown', mousedown, false );
    this.domElement.removeEventListener( 'wheel', mousewheel, false );

    this.domElement.removeEventListener( 'touchstart', touchstart, false );
    this.domElement.removeEventListener( 'touchend', touchend, false );
    this.domElement.removeEventListener( 'touchmove', touchmove, false );

    document.removeEventListener( 'mousemove', mousemove, false );
    document.removeEventListener( 'mouseup', mouseup, false );

    window.removeEventListener( 'keydown', keydown, false );
    window.removeEventListener( 'keyup', keyup, false );

    };

    this.domElement.addEventListener( 'contextmenu', contextmenu, false );
    this.domElement.addEventListener( 'mousedown', mousedown, false );
    this.domElement.addEventListener( 'wheel', mousewheel, false );

    this.domElement.addEventListener( 'touchstart', touchstart, false );
    this.domElement.addEventListener( 'touchend', touchend, false );
    this.domElement.addEventListener( 'touchmove', touchmove, false );

    window.addEventListener( 'keydown', keydown, false );
    window.addEventListener( 'keyup', keyup, false );

    this.handleResize();

    // force an update at start
    this.update();

    };

    THREE.TrackballControls.prototype = Object.create( THREE.EventDispatcher.prototype );
    THREE.TrackballControls.prototype.constructor = THREE.TrackballControls;
    Binary file added elev_bump_4k.jpg
    Loading
    Sorry, something went wrong. Reload?
    Sorry, we cannot display this file.
    Sorry, this file is invalid so it cannot be displayed.
    4 changes: 1 addition & 3 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -11,10 +11,8 @@
    </style>
    </head>
    <body>
    <script src="https://code.jquery.com/jquery-3.1.1.js" charset="utf-8"></script>
    <script src="three.js" charset="utf-8"></script>
    <script src="three.min.js" charset="utf-8"></script>
    <script src="TrackballControls.js" charset="utf-8"></script>
    <script src="threeGeoJson.js" charset="utf-8"></script>
    <script src="Globe.js" charset="utf-8"></script>
    <script src="scene.js" charset="utf-8"></script>
    </body>
    Binary file added n_amer_clouds.png
    Loading
    Sorry, something went wrong. Reload?
    Sorry, we cannot display this file.
    Sorry, this file is invalid so it cannot be displayed.
    Binary file added relief.jpg
    Loading
    Sorry, something went wrong. Reload?
    Sorry, we cannot display this file.
    Sorry, this file is invalid so it cannot be displayed.
    52 changes: 52 additions & 0 deletions scene.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,52 @@
    var scene = new THREE.Scene();
    var ratio = window.innerWidth / window.innerHeight;
    var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight,
    0.1, 50);

    camera.position.z = -30;

    var renderer = new THREE.WebGLRenderer({
    antialias: true
    });
    renderer.setPixelRatio(window.devicePixelRatio);
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.setClearColor(0x000000, 1);

    var canvas = renderer.domElement;
    canvas.style.display = "block";

    document.body.appendChild(canvas);

    // Enable controls
    var controls = new THREE.TrackballControls(camera);

    //Add lighting
    scene.add(new THREE.AmbientLight(0x333333));

    var light = new THREE.DirectionalLight(0xe4eef9, .7);
    light.position.set(12, 12, 8);
    scene.add(light);

    var radius = 9.99,
    segments = 32,
    rotation = 0;

    var globe = new Globe(radius, segments);

    scene.add(globe);

    // Render the image
    function render() {
    controls.update();

    if(globe.earth)
    globe.earth.rotation.y += 0.0005;

    if(globe.clouds)
    globe.clouds.rotation.y += 0.0003;

    requestAnimationFrame(render);
    renderer.render(scene, camera);
    }

    render();
    838 changes: 838 additions & 0 deletions three.min.js
    838 additions, 0 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
    Binary file added wateretopo.png
    Loading
    Sorry, something went wrong. Reload?
    Sorry, we cannot display this file.
    Sorry, this file is invalid so it cannot be displayed.
  6. Marco Pompili created this gist Nov 13, 2016.
    21 changes: 21 additions & 0 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,21 @@
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    <title>Globe</title>
    <style media="screen">
    html, body {
    margin: 0;
    padding: 0
    }
    </style>
    </head>
    <body>
    <script src="https://code.jquery.com/jquery-3.1.1.js" charset="utf-8"></script>
    <script src="three.js" charset="utf-8"></script>
    <script src="TrackballControls.js" charset="utf-8"></script>
    <script src="threeGeoJson.js" charset="utf-8"></script>
    <script src="Globe.js" charset="utf-8"></script>
    <script src="scene.js" charset="utf-8"></script>
    </body>
    </html>