block by mbostock 4282586

Three-Axis Rotation

Full Screen

D3 3.0 supports three-axis rotation for geographic projections. This example demonstrates rotating lambda (λ), phi (φ) and gamma (γ) in three side-by-side orthographic projections.

Updated Example →

index.html

<!DOCTYPE html>
<meta charset="utf-8">
<style>

.title {
  display: inline-block;
  font-size: 48px;
  line-height: 90px;
  text-align: center;
}

</style>
<body>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/topojson.v1.min.js"></script>
<script>

var diameter = 960 / 3,
    radius = diameter / 2,
    velocity = 0.01;

var projection = d3.geoOrthographic()
    .scale(radius - 2)
    .translate([radius, radius])
    .clipAngle(90)
    .precision(0);

d3.select("body").selectAll(".title")
  .data(["λ", "φ", "γ"])
  .enter().append("div")
    .attr("class", "title")
    .style("width", diameter + "px")
    .text(function(d) { return d; });

var canvas = d3.select("body").selectAll("canvas")
  .data(d3.range(3))
  .enter().append("canvas")
    .datum(function() { return this.getContext("2d"); })
    .attr("width", diameter)
    .attr("height", diameter);

var path = d3.geoPath()
    .projection(projection);

d3.json("/mbostock/raw/4090846/world-110m.json", function(error, world) {
  if (error) throw error;

  var land = topojson.feature(world, world.objects.land),
      globe = {type: "Sphere"};

  d3.timer(function(elapsed) {
    var angle = velocity * elapsed;
    canvas.each(function(context, i) {
      var rotate = [0, 0, 0];
      rotate[i] = angle, projection.rotate(rotate);
      context.clearRect(0, 0, diameter, diameter);
      context.beginPath(), path.context(context)(land), context.fill();
      context.beginPath(), path(globe), context.stroke();
    });
  });
});

</script>