<!DOCTYPE html>
<meta charset="utf-8">
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://d3js.org/topojson.v1.min.js"></script>
<script>

var width = 960,
    height = 500;

// Returns UTM zome from longitude
var utmZone = d3.scale.linear()
    .domain([-177, 177])
    .rangeRound([1, 60])
    .clamp(true);

var projection = d3.geo.transverseMercator()
    .translate([width / 2, height / 2])
    .scale(165)
    .clipAngle(90);

var graticule = d3.geo.graticule()
    .step([6, 8]);    

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

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

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

d3.json("/mbostock/raw/4090846/world-110m.json", function(error, world) {
  var land = topojson.feature(world, world.objects.land),
      center = -180,
      velocity = .015,
      zone, zoneText, zoneStart, zoneEnd,
      t0;

  d3.timer(function() {
    context.clearRect(0, 0, width, height);
    projection.rotate([-center, 0]);

    zone = utmZone(center);
    zoneText = (1e15 + zone + "").slice(-2), // Add leading zero
    zoneStart = -186 + zone * 6;
    zoneEnd = zoneStart + 6;
    t0 = Date.now();

    render();

    center += velocity * (Date.now() - t0); 
    if (center >= 180) { // New roundtrip
      center = -180; 
    }
  });

  function render() {
    context.beginPath();
    path(land);
    context.fillStyle = 'black';
    context.fill();

    context.beginPath();
    path({ 
      "type": "Polygon", 
      "coordinates": [[[zoneStart, 84], [zoneEnd, 84],  [zoneEnd, -80], [zoneStart, -80], [zoneStart, 84]]]
    });
    context.fillStyle = "rgba(255, 255, 0, .5)";
    context.fill();

    context.beginPath();
    path(graticule());
    context.lineWidth = .5;
    context.stroke();

    context.beginPath();
    context.fillStyle = "#eee";
    context.strokeStyle = "black";
    context.lineWidth = 1;    			
    context.font = "bold 40px Verdana";
    context.fillText(zoneText, width / 2 - 30, height / 2);
    context.strokeText(zoneText, width / 2 - 30, height / 2);
  }

});

</script>