globe3d — Interactions

A globe is a camera plus a body. No map projection is involved: the geometry stays on the sphere, the camera only looks at it, and the horizon does the clipping, which is why the same layers and the same elements work here and on a map.

Example 1

Aiming the camera

lookAt(lon, lat) is the only supported way to aim.

JavaScript snippet

var globe = board.create('globe3d', [[2.6, 0.6], [6.8, 6.8]], {
  data: DATA,
  tabindex: null
});

globe.lookAt(20, 10);
Example 2

Layers

The same layers a map has, drawn on the sphere instead of on a sheet. A layer switched off is skipped in the clipping pass rather than merely hidden.

JavaScript snippet

var globe = board.create('globe3d', [[2.6, 0.6], [6.8, 6.8]], {
  data: DATA,
  tabindex: null
});

globe.setLayer('countries', true);
Example 3

Selecting countries

With selectMode: 'multiple' every country stays selected until it is clicked again, so several can be held at once. The look of a selected country comes from highlightStyle.

JavaScript snippet

var globe = board.create('globe3d', [[2.6, 0.6], [6.8, 6.8]], {
  data: DATA,
  tabindex: null
});

out('tap a country · drag to turn'); // Define out() separately.

globe.on('selectionchange', function (ev) {
  var names = ev.selected.map(function (id) {
    var c = DATA.countries.filter(function (x) { return x.id === id; })[0];
    return c ? c.name.en : id;
  });
  out(names.length ?
    names.length + ' selected: ' + names.join(', ') : 'nothing selected');
});
Example 4

Changing the scale

The body can be shrunk so that something above it — an orbit, a satellite — fits inside the world cube. Every layer multiplies by the current scale while it draws, so nothing is rebuilt and layers above the surface follow by themselves. scaleTo eases between two values; without a frame timer it sets the target at once instead of throwing.

JavaScript snippet

var globe = board.create('globe3d', [[2.6, 0.6], [6.8, 6.8]], {
  data: DATA,
  tabindex: null
});

globe.scaleTo(0.5, { duration: 600, onEnd: function (lon, lat) { … } });
Example 5

Spin, and how the pointer may turn it

spin() turns the globe about its polar axis by itself; a running spin is stopped before a new one starts, so calling it twice does not leave two loops fighting over the same globe. rotateMode (free, azimuth, none) decides what the pointer may do: the free trackball, a turn about the polar axis alone — east and west, with the tilt towards the viewer kept — or nothing. "Azimuth" here names that turn; it is not an azimuth in the geodetic sense, which is a direction measured from north.

JavaScript snippet

var globe = board.create('globe3d', [[2.6, 0.6], [6.8, 6.8]], {
  data: DATA,
  tabindex: null
});

globe.rotateMode('azimuth');
Example 6

Draggable places

The same two paths, with their ends on handles. A geoHandle is a JSXGraph point bound to a geoPoint: drag it and everything built on that point follows — both paths, the marker riding them, and the trail behind it. The globe keeps turning while you do, because a drag on a handle is not a drag on the body.

Example 7

A logo on the globe

Rings placed on the sphere and turned with it. Nothing geographic about them at all, which is the point: a host that answers addGeoLayer will draw whatever is handed to it, and the clipping against the horizon does not care what the shape means.

Example 8

A spherical triangle

Three great circles meet at angles that add to more than 180 degrees, and the excess is the area — that is Girard's theorem, not an approximation. Drag a corner: the sum is never 180, and the further apart the corners, the further from it.

JavaScript snippet

var map = board.create('geomap', [[0.2, 0.2], [11.6, 5.7]], {
  data: DATA,
  tabindex: null
});

var corners = [
  [-20, 40],
  [40, 10],
  [10, 60]
].map(function (c) {
  return globe.geoPoint(c[0], c[1], { fillColor: '#cf9b3f' });
});

var tri = globe.geoTriangle(corners[0], corners[1], corners[2], {
  fillColor: '#cf9b3f',
  fillOpacity: 0.3,
  strokeColor: '#cf9b3f',
  strokeWidth: 1.4
});