block by davo 4355678

4355678

Full Screen

See discussion on Hacker News. Built with D3 and TopoJSON.

index.html

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

h1 {
  position: absolute;
  top: 280px;
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 18px;
  text-align: center;
  width: 960px;
}

</style>
<h1></h1>
<script src="//d3js.org/d3.v3.min.js"></script>
<script src="//d3js.org/queue.v1.min.js"></script>
<script src="//d3js.org/topojson.v0.min.js"></script>
<script>

var width = 960,
    height = 500;

var projection = d3.geo.orthographic()
    .scale(248)
    .clipAngle(87);

var canvas = d3.select("body").append("canvas")
    .attr("width", width)
    .attr("height", height);

var c = canvas.node().getContext("2d");

var path = d3.geo.path()
    .projection(projection)
    .context(c);

var title = d3.select("h1");

queue()
    .defer(d3.json, "/d/4090846/world-110m.json")
    .defer(d3.tsv, "/d/4090846/world-country-names.tsv")
    .await(ready);

function ready(error, world, names) {
  var globe = {type: "Sphere"},
      land = topojson.object(world, world.objects.land),
      countries = topojson.object(world, world.objects.countries).geometries,
      borders = topojson.mesh(world, world.objects.countries, function(a, b) { return a.id !== b.id; }),
      i = -1,
      n = countries.length;

  countries.forEach(function(d) { d.name = names.filter(function(n) { return d.id == n.id; })[0].name; });
  countries.sort(function(a, b) { return a.name.localeCompare(b.name); });

  (function transition() {
    d3.transition()
        .duration(1250)
        .each("start", function() {
          title.text(countries[i = (i + 1) % n].name);
        })
        .tween("rotate", function() {
          var p = d3.geo.centroid(countries[i]),
              r = d3.interpolate(projection.rotate(), [-p[0], -p[1]]);
          return function(t) {
            projection.rotate(r(t));
            c.clearRect(0, 0, width, height);
            c.fillStyle = "#bbb", c.beginPath(), path(land), c.fill();
            c.fillStyle = "#f00", c.beginPath(), path(countries[i]), c.fill();
            c.strokeStyle = "#fff", c.lineWidth = .5, c.beginPath(), path(borders), c.stroke();
            c.strokeStyle = "#000", c.lineWidth = 2, c.beginPath(), path(globe), c.stroke();
          };
        })
      .transition()
        .each("end", transition);
  })();
}

</script>