Mega Code Archive

 
Categories / JavaScript DHTML / Page Components
 

Rotating globe in JavaScript

<?xml version="1.0" encoding="utf-8" ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"                       "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>rotating globe</title> <!-- misc.js --> <script language="JavaScript" > /*------------------------------------------------------------------------------    Copyright (c) 2005 Tyrell Corporation.     This file is part of the Locative Blog project.     http://locblog.sourceforge.net/    Author   : $Author: darkeye $    Version  : $Revision: 1.1.1.1 $    Location : $Source: /cvsroot/locblog/rotatingGlobe/var/public_html/misc.js,v $    Abstract :      Utility functions.    Copyright notice:     This program is free software; you can redistribute it and/or     modify it under the terms of the GNU General Public License       as published by the Free Software Foundation; either version 2     of the License, or (at your option) any later version.         This program is distributed in the hope that it will be useful,     but WITHOUT ANY WARRANTY; without even the implied warranty of      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      GNU General Public License for more details.         You should have received a copy of the GNU General Public License     along with this program; if not, write to the Free Software     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. ------------------------------------------------------------------------------*/ /**  *  Constructor to reate an object, based on a named element from the document,  *  browser-independently.  *  The created object will have two properties:  *  obj   - the named object itself  *  style - the stylesheet object for the named object.  *  *  based on http://www.quirksmode.org/js/dhtmloptions.html  *  *  @param name the name of the element to create this object upon.  */ function getObj(name) {     if (document.getElementById) {         this.obj   = document.getElementById(name);         this.style = document.getElementById(name).style;     } else if (document.all) {         this.obj   = document.all[name];         this.style = document.all[name].style;     } else if (document.layers) {         this.obj   = document.layers[name];         this.style = document.layers[name];     } } /**  *  Find the X coordinate of an element in the document.  *  based on http://www.quirksmode.org/js/findpos.html  *  *  @param obj the element in the document.  *  @return the x coordinate for this element.  */ function findPosX(obj) {     var curleft = 0;     if (obj.offsetParent) {         while (obj.offsetParent) {             curleft += obj.offsetLeft             obj = obj.offsetParent;         }     } else if (obj.x) {         curleft += obj.x;     }     return curleft; } /**  *  Find the Y coordinate of an element in the document.  *  based on http://www.quirksmode.org/js/findpos.html  *  *  @param obj the element in the document.  *  @return the x coordinate for this element.  */ function findPosY(obj) {     var curtop = 0;     if (obj.offsetParent) {         while (obj.offsetParent) {             curtop += obj.offsetTop             obj = obj.offsetParent;         }     } else if (obj.y) {         curtop += obj.y;     }     return curtop; } /**  *  Replace the contenst of a DOM element.  *  based on http://www.quirksmode.org/js/layerwrite.html  *  *  @param id the id of the element.  *  @param text the new text of the element.  */ function replaceContent(id, text) {     if (document.getElementById) {         x = document.getElementById(id);         x.innerHTML = '';         x.innerHTML = text;     } else if (document.all) {         x = document.all[id];         x.innerHTML = text;     } else if (document.layers) {         x = document.layers[id];         text2 = '<P CLASS="testclass">' + text + '</P>';         x.document.open();         x.document.write(text2);         x.document.close();     } } /**  *  Function to calculate the X coordinate of an orthographic projection.  *  based on http://mathworld.wolfram.com/OrthographicProjection.html  *  *  @param phi the lattitude of the point on the sphere  *  @param lambda the longitude of the point on the sphere  *  @param phi1 the lattitude of the viewpoint  *  @param lambda1 the longitued of the viewpoint  *  @return the x coordinate of the specified point.  */ function orthographicX(phi, lambda, phi1, lambda1) {     var x = Math.cos(phi) * Math.sin(lambda - lambda1);     return x; } /**  *  Function to calculate the Y coordinate of an orthographic projection  *  based on http://mathworld.wolfram.com/OrthographicProjection.html  *  *  @param phi the lattitude of the point on the sphere  *  @param lambda the longitude of the point on the sphere  *  @param phi1 the lattitude of the viewpoint  *  @param lambda1 the longitued of the viewpoint  *  @return the y coordinate of the specified point.  */ function orthographicY(phi, lambda, phi1, lambda1) {     var y = Math.cos(phi1) * Math.sin(phi)           - Math.sin(phi1) * Math.cos(phi) * Math.cos(lambda - lambda1);     return y; } /**  *  Helper function to convert a latitude or longitued into radii.  *  *  @param degrees the latitude or longitude  *  @return the same value, in radii  */ function toRadii(degrees) {     return (degrees / 180.0) * Math.PI; } </script> <!-- GeoLocation.js --> <script language="JavaScript"> /*------------------------------------------------------------------------------    Copyright (c) 2005 Tyrell Corporation.     This file is part of the Locative Blog project.     http://locblog.sourceforge.net/    Author   : $Author: darkeye $    Version  : $Revision: 1.1.1.1 $    Location : $Source: /cvsroot/locblog/rotatingGlobe/var/public_html/GeoLocation.js,v $    Abstract :      A class representing a geogpraphical location.    Copyright notice:     This program is free software; you can redistribute it and/or     modify it under the terms of the GNU General Public License       as published by the Free Software Foundation; either version 2     of the License, or (at your option) any later version.         This program is distributed in the hope that it will be useful,     but WITHOUT ANY WARRANTY; without even the implied warranty of      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      GNU General Public License for more details.         You should have received a copy of the GNU General Public License     along with this program; if not, write to the Free Software     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. ------------------------------------------------------------------------------*/ /**  *  Constructor for a geographic location, with a link.  *  *  @param id the id of the location (no spaces, etc.)  *  @param name the name of the location  *  @param longitude the longitude coordinate of the location  *  @param latitude the latitude coordinate of the location  *  @param url the url for more info on the location  */ function GeoLocation(id,                      name,                      longitude,                      latitude,                      url) {     // the id of the location     this.id = id;     // the name of the location     this.name = name;     // the longitude coordinate of the location     this.longitude = longitude < 0 ? 360 + longitude : longitude;     // the latitude coordinate of the location     this.latitude = latitude;     // the url for more info on the location     this.url = url;     // the image used to mark the location visually     this.markerImage = 'globeImages/5x5.png';     // the width of the marker image     this.markerWidth = 5;     // the height of the marker image     this.markerHeight = 5;     // the x coordinate of this location, relative to the page window     this.x = 0;     // the y coordinate of this location, relative to the page window     this.y = 0;     // create the CSS definition for this location     this.styleDefinition = geoLocationStyleDefinition;     // create the HTML element source for this location     this.htmlDefinition = geoLocationHtmlDefinition;     // display the location object on a RotatingGlobe object     this.display = geoLocationDisplay;     // move the marker depiciting the location to the specified position     this.moveMarker = geoLocationMoveMarker;     // hide the marker depiciting the location     this.hideMarker = geoLocationHideMarker;     // show the location popup near the geo location     this.showPopup = geoLocationShowPopup;     // hide the location popup near the geo location     this.hidePopup = geoLocationHidePopup;     // Tell if the longitude coordinate of the GeoLocation object is visible     // from a reference viewpoint.     this.longitudeVisible = geoLocationLongitudeVisible; } /**  *  Create the CSS definition for this location  *  *  @return the CSS definition for this location, as a string  */ function geoLocationStyleDefinition() {     return '#' + this.id + '{'          + ' position: absolute; '          + ' top:      0px; '          + ' left:     0px; '          + '}\n'; } /**  *  Create the HTML element source for this location  *  *  @return the HTML element source for this location, as a string.  */ function geoLocationHtmlDefinition() {     return '<a id="' + this.id + '" href="' + this.url + '">'          + '<img name="' + this.id + '" alt="' + this.name + '" '             + 'src="' + this.markerImage + '" '             + 'width="' + this.markerWidth + '" '             + 'height="' + this.markerHeight + '" border="0"/>'          + '</a>\n'; } /**  *  Move the marker depicting the location to the specified coordinates.  */ function geoLocationMoveMarker() {     var locationObject = new getObj(this.id);     locationObject.style.top        = this.y + "px";     locationObject.style.left       = this.x + "px";     locationObject.style.visibility = "visible"; } /**  *  Hide the Marker depicting the location.  */ function geoLocationHideMarker() {     var locationObject = new getObj(this.id);     locationObject.style.visibility = "hidden"; } /**  *  Show the popup text near the location.  */ function geoLocationShowPopup() {     replaceContent("locationPopup", this.name);     var popup = new getObj("locationPopup");     // display a bit to the right and above     popup.style.left       = (this.x + 10) + "px";     popup.style.top        = (this.y - 15) + "px";     popup.style.visibility = "visible"; } /**  *  Hide the popup near the location.  */ function geoLocationHidePopup() {     var popup = new getObj("locationPopup");     popup.style.visibility = "hidden"; } /**  *  Display the location on the map.  *  *  @param globe a RotatingGlobe object, on which to display the location  */ function geoLocationDisplay(globe) {     longStepSize  = 360.0 / globe.maxPosition;     viewLongitude = globe.position * longStepSize;     if (!this.longitudeVisible(viewLongitude)) {         this.hideMarker();         return;     }     lambda  = toRadii(this.longitude);     phi     = toRadii(this.latitude);     lambda1 = toRadii(viewLongitude);     phi1    = toRadii(0);     x = (orthographicX(phi, lambda, phi1, lambda1) * (globe.realGlobeWidth/2))       + (globe.globeImage.width / 2);     y = globe.globeImage.height       - ((orthographicY(phi, lambda, phi1, lambda1) * (globe.realGlobeHeight/2))          + (globe.globeImage.height / 2) );     this.x = globe.globeImageX + x;     this.y = globe.globeImageY + y;     this.moveMarker(); } /**  *  Tell if the longitude coordinate of the GeoLocation object is visible  *  from a reference viewpoint.  *  It's not visible if it would be "on the other side of the planet"  *  *  @param refLongitude the reference view point, to check from.  *  @return true if longitude is visible, false otherwise  */ function geoLocationLongitudeVisible(refLongitude) {     var westEdge = refLongitude - 90;     var eastEdge = refLongitude + 90;     if (westEdge >= 0 && eastEdge < 360) {         return westEdge <= this.longitude && this.longitude <= eastEdge;     } else if (eastEdge >= 360) {         eastEdge -= 360;         return westEdge <= this.longitude || this.longitude <= eastEdge;     } else {         westEdge += 360;         return westEdge <= this.longitude || this.longitude <= eastEdge;     } } </script> <!-- RotatingGlobe.js --> <script language="JavaScript"> /*------------------------------------------------------------------------------    Copyright (c) 2005 Tyrell Corporation.     This file is part of the Locative Blog project.     http://locblog.sourceforge.net/    Author   : $Author: darkeye $    Version  : $Revision: 1.1.1.1 $    Location : $Source: /cvsroot/locblog/rotatingGlobe/var/public_html/RotatingGlobe.js,v $    Abstract :      A rotating globe JavaScript object.    Copyright notice:     This program is free software; you can redistribute it and/or     modify it under the terms of the GNU General Public License       as published by the Free Software Foundation; either version 2     of the License, or (at your option) any later version.         This program is distributed in the hope that it will be useful,     but WITHOUT ANY WARRANTY; without even the implied warranty of      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      GNU General Public License for more details.         You should have received a copy of the GNU General Public License     along with this program; if not, write to the Free Software     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. ------------------------------------------------------------------------------*/ /**  *  Event handler for a preloaded image finishing loading.  *  This function expects the rotating globe, for which preloaded images  *  are checked, being available at the global variable named 'globe'.  *  *  @return true if all images are loaded, false otherwise.  */ function globeImageLoaded() {     if (globe.imagesLoaded()) {         globe.init();         return true;     }     return false; } /**  *  Start dragging the image by the mouse move.  *  This function expects the rotating globe at a global variable named 'globe'  */ function globeDragImage() {     globe.startDragImage();     document.globe.onmousemove = globeTrackMouseMove; } /**  *  Stop dragging the image by the mouse move.  *  This function expects the rotating globe at a global variable named 'globe'  */ function globeUndragImage() {     document.globe.onmousemove = null;     globe.stopDragImage(); } /**  *  Track the mouse movement, and change the globe view if necessary.  *  This function expects the rotating globe at a global variable named 'globe'  *  *  @param event the mouse movement event.  */ function globeTrackMouseMove(event) {     // first tell the current mouse position, possibly in all browsers     // thanks to http://www.quirksmode.org/js/events_properties.html     var posx = 0;     var posy = 0;     if (!event) {         var event = window.event;     }     if (event.pageX || event.pageY) {         posx = event.pageX;         posy = event.pageY;     } else if (event.clientX || event.clientY) {         posx = event.clientX + document.body.scrollLeft;         posy = event.clientY + document.body.scrollTop;     }     // display the detected coordinates, for debug reasons     document.test.x.value = posx;     document.test.y.value = posy;     globe.updateView(posx, posy); } /**  *  The contructor class depicting the rotating globe.  *  *  @param globeImage the globe <img/> tag in the page,  *         that holds the globe images.  *  @param globeBorder the number of pixels the image has a border around  *         the enclosed globe. it is expected that the image has a globe at  *         its center, which is surrounded by a border on each side with  *         this many pixels. thus the actual globe is  *         globeImage.width - (2 * globeBorder) wide, and  *         globeImage.height - (2 * globeBorder) in height.  *  @param locations an array holding GeoLocation object, the list of  *         interesting locations.  */ function RotatingGlobe(globeImage, globeBorder, locations) {     // the <img/> element in the page, holding the globe images     this.globeImage = globeImage;     // the size of the border around the globe in the image     this.globeBorder = globeBorder;     // the interesting locations on the globe     this.locations = locations;     // the X coordinate of the upper-left corner of the globe image     // in the browser window     this.globeImageX = findPosX(document.globe);     // the Y coordinate of the upper-left corner of the globe image     // in the browser window     this.globeImageY = findPosY(document.globe);     // the real height of the globe itself, inside the image     this.realGlobeHeight = this.globeImage.width - (2 * this.globeBorder);     // the real width of the globe itself, inside the image     this.realGlobeWidth  = this.globeImage.height - (2 * this.globeBorder);     // the number of view positions available     this.maxPosition = 36;     // the current view position     this.position = 0;     // the prefix for each globe image     // the image names are: imagePrefix + position + imagePostfix     this.imagePrefix = "globeImages/globe";     // the postfix for each globe image     // the image names are: imagePrefix + position + imagePostfix     this.imagePostfix = ".jpg";     // the globe images, as an array     this.images = Array(this.maxPosition);     // the x coordinate, which if passed by the mouse, triggers a move to east     this.eastThreshold = 0;     // the x coordinate, which if passed by the mouse, triggers a move to west     this.westThreshold = 0;     // the size of the x coordinate window to trigger a move to east or west     // by the mouse movement     this.thresholdStep = 20;     // a flag indicating if this object has already been initialized     this.initialized = false;     // preload all the images for the globe     this.preloadImages = rotatingGlobePreloadImages;     // tell if all images that are to be preloaded have completed loading.     this.imagesLoaded = rotatingGlobeImagesLoaded;     // initialize the globe, after all the images have been loaded     this.init = rotatingGlobeInit;     // start mouse dragging     this.startDragImage = rotatingGlobeStartDragImage;     // stop mouse dragging     this.stopDragImage = rotatingGlobeStopDragImage;     // update the view point according to the new mouse coordinates, if needed     this.updateView = rotatingGlobeUpdateView;     // function to return the name of an image for a specified position     this.imageName = rotatingGlobeImageName;     // rotate the viewpoint one step to the east     this.rotateEast = rotatingGlobeRotateEast;     // rotate the viewpoint one step to the west     this.rotateWest = rotatingGlobeRotateWest;     // reset the mouse movement thresholds triggering view point change     this.resetThreshold = rotatingGlobeResetThreshold;     // display the locations     this.displayLocations = rotatingGlobeDisplayLocations; } /**  *  Function returning the name of an image for a specified position  *  *  @param position the view position to get the image for, must be  *         in the interval [0:maxPosition[  *  @return the name of the appropariate globe image, as a string  */ function rotatingGlobeImageName(position) {     return this.imagePrefix + position + this.imagePostfix; } /**  *  Rotate the current viewpoint one step to the east.  */ function rotatingGlobeRotateEast() {     this.position = (++this.position) % this.maxPosition;     this.globeImage.src = this.images[this.position].src;     this.displayLocations(); } /**  *  Rotate the current viewpoint one step to the east.  */ function rotatingGlobeRotateWest() {     this.position = (--this.position) % this.maxPosition;     if (this.position < 0) {         this.position += this.maxPosition;     }     this.globeImage.src = this.images[this.position].src;     this.displayLocations(); } /**  *  Preload all the images, so that they are in the browsers cache.  */ function rotatingGlobePreloadImages() {     this.initialized = false;     for (i = 0; i < this.maxPosition; ++i) {         this.images[i] = new Image(this.globeImage.width,                                    this.globeImage.height);         this.images[i].onload = globeImageLoaded;         this.images[i].src    = this.imageName(i);     } } /**  *  Tell if all images that are to be preloaded have completed loading.  *  *  @return true if all images have been loaded, false otherwise  */ function rotatingGlobeImagesLoaded() {     var   allCompleted = true;     for (i = 0; i < this.maxPosition; ++i) {         if (!this.images[i].complete) {             allCompleted = false;             break;         }     }     return allCompleted; } /**  *  Initialize the globe, after all the images have been loaded.  *  This means grabbing event handlers, etc.  */ function rotatingGlobeInit() {     if (this.initialized) {         return;     }     this.thresholdStep        = this.globeImage.width / (this.maxPosition + 1);     this.globeImage.onmousedown = globeDragImage;     this.globeImage.onmouseup   = globeUndragImage;     this.globeImage.src         = this.images[0].src;     this.initialized            = true;     for (i = 0; i < locations.length; ++i) {         var obj = new getObj(locations[i].id);         obj.obj.onmouseover = locationShowPopup;         obj.obj.onmouseout  = locationHidePopup;     }     this.displayLocations(); } /**  *  Find a location in an array of locations, by its id.  *  *  @param locations an array of GeoLocation objects.  *  @param id the id of the location to look for  *  @return the requested GeoLocation object, or null if not found.  */ function getLocationById(locations, id) {     for (i = 0; i < locations.length; ++i) {         if (locations[i].id == id) {             return locations[i];         }     }     return null; } /**  *  Event hanlder for showing the popup near a location.  *  *  @param event the event triggering this call. it is expected that the event  *         target name is a valid GeoLocation id in the locations array.  */ function locationShowPopup(event) {     geoLocation = getLocationById(locations, event.target.name);     if (geoLocation != null ) {         geoLocation.showPopup();     } } /**  *  Event hanlder for hiding the popup near a location.  *  *  @param event the event triggering this call. it is expected that the event  *         target name is a valid GeoLocation id in the locations array.  */ function locationHidePopup(event) {     geoLocation = getLocationById(locations, event.target.name);     if (geoLocation != null ) {         geoLocation.hidePopup();     } } /**  *  Reset the mouse movement thresholds. Set the new limits for when  *  to change the view point, if the mouse move beyonds these limints.  *  *  @param posx the current position, from where the relative thresholds  *         have to be set up.  */ function rotatingGlobeResetThreshold(posx) {     this.eastThreshold = posx - this.thresholdStep;     this.westThreshold = posx + this.thresholdStep; } /**  *  Start mouse dragging  */ function rotatingGlobeStartDragImage() {     this.eastThreshold = 0;     this.westThreshold = 0; } /**  *  Stop mouse dragging.  */ function rotatingGlobeStopDragImage() {     this.eastThreshold = 0;     this.westThreshold = 0; } /**  *  Update the view point according to the new mouse coordinates, if needed.  *  *  @param x the new x coordinate for the mouse  *  @param y the new y coordinate for the mouse  */ function rotatingGlobeUpdateView(x, y) {     // if this is the first event after started dragging, initialize     // the appropriate thresholds     if (this.eastThreshold == 0 && this.westThreshold == 0) {         this.resetThreshold(x);     }     // change the view point, if needed     if (x > this.westThreshold) {         this.rotateWest();         this.resetThreshold(x);     } else if (x < this.eastThreshold) {         this.rotateEast();         this.resetThreshold(x);     } } /**  *  Display all interesting locations on the map.  */ function rotatingGlobeDisplayLocations() {     for (i = 0; i < locations.length; ++i) {         this.locations[i].display(this);     } } </script> <script language="JavaScript"> /**  *  The global rotating globe object, the event handlers depend on this.  */ var globe; /**  *  The locations.  */ var locations = Array(); </script> <!-- locations.js --> <script language="JavaScript"> /*------------------------------------------------------------------------------    Copyright (c) 2005 Tyrell Corporation.     This file is part of the Locative Blog project.     http://locblog.sourceforge.net/    Author   : $Author: darkeye $    Version  : $Revision: 1.1.1.1 $    Location : $Source: /cvsroot/locblog/rotatingGlobe/var/public_html/locations.js,v $        Abstract :      A sample location data definition file.    Copyright notice:     This program is free software; you can redistribute it and/or     modify it under the terms of the GNU General Public License       as published by the Free Software Foundation; either version 2     of the License, or (at your option) any later version.         This program is distributed in the hope that it will be useful,     but WITHOUT ANY WARRANTY; without even the implied warranty of      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      GNU General Public License for more details.         You should have received a copy of the GNU General Public License     along with this program; if not, write to the Free Software     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. ------------------------------------------------------------------------------*/ locations.push(new GeoLocation(     "amsterdam", "Amsterdam", 4.54, 52.23, "/amsterdam")); locations.push(new GeoLocation(     "bangkok", "Bangkok", 100.50, 13.73, "/bangkok")); locations.push(new GeoLocation(     "budapest", "Budapest", 19.05, 47.50, "/budapest")); locations.push(new GeoLocation(     "chiang_mai", "Chiang Mai", 99.03, 18.82, "/chiang_mai")); locations.push(new GeoLocation(     "linz", "Linz", 14.18, 48.19, "/linz")); locations.push(new GeoLocation(     "london", "London", -0.16, 51.50, "/london")); locations.push(new GeoLocation(     "luang_prabang", "Luang Prabang", 102.14, 19.88, "/luang_prabang")); locations.push(new GeoLocation(     "new_york", "New York", -74.00, 40.70, "/new_york")); locations.push(new GeoLocation(     "Paris", "Paris", 2.33, 48.87, "/paris")); locations.push( new GeoLocation(     "philadelphia", "Philadelphia", -75.12, 39.96, "/philadelphia")); locations.push( new GeoLocation(     "prague", "Prague", 14.43, 50.10, "/prague")); locations.push( new GeoLocation(     "rotterdam", "Rotterdam", 4.29, 51.55, "/rotterdam")); locations.push( new GeoLocation(     "taipei", "Taipei", 121.36, 25.01, "/taipei")); locations.push( new GeoLocation(     "tokyo", "Tokyo", 139.50, 35.75, "/tokyo")); locations.push( new GeoLocation(     "vienna", "Vienna", 16.36, 48.20, "/vienna")); locations.push( new GeoLocation(     "washington", "Washington DC", -77.03, 38.88, "/washington")); </script> <script language="JavaScript"> /**  *  Initialize the page, after it has loaded.  */ function onPageLoad() {     globe = new RotatingGlobe(document.globe, 30, locations);     // this sets up event handlers for the preloaded images     globe.preloadImages();     // as not all event handlers are called (damn these lame browswers)     // set a timout value and call the load image hanlder ourselves     makeSureImagesAreLoaded() } /**  *  Make sure all images are loaded, by checking on this regularly.  */ function makeSureImagesAreLoaded() {     if (!globeImageLoaded()) {         // if not ready, check a second later as well         setTimeout("makeSureImagesAreLoaded()", 1000);     } } /**  *  Rotate the globe one step to the east.  */ function rotateEast() {     globe.rotateEast(); } /**  *  Rotate the globe one step to the west.  */ function rotateWest() {     globe.rotateWest(); } </script> <script language="JavaScript"> // create the style sheet definition for each geo location document.write('<style type="text/css">'); for (i = 0; i < locations.length; ++i) {     document.write(locations[i].styleDefinition()); } document.write('</style>'); </script> <style type="text/css"> #locationPopup {     position:    absolute;     top:         0px;     left:        0px;     visibility:  hidden;     font:        14px arial;     font-weight: bold;     color:       yellow; } </style> </head> <body onLoad="onPageLoad();"> <a href="#" onClick="javascript:rotateWest(); return false;">west</a> | <a href="#" onClick="javascript:rotateEast(); return false;">east</a> <br/> <img name="globe" src="images/loading.png" width="650" height="650" alt="globe"/> <br/> <form name="test">     X: <input type="text" name="x" size="4">     Y: <input type="text" name="y" size="4"> </form> <script language="JavaScript"> // create the HTML element for each geo location for (i = 0; i < locations.length; ++i) {     document.write(locations[i].htmlDefinition()); } </script> <div id="locationPopup"></div> </body>                     rotatingGlobe-0.1.zip( 4,605 k)