block by jeremybuis 7570402

7570402

Full Screen

Using d3.geo.tile to display raster image tiles underneath some TopoJSON vectors, and d3.behavior.zoom for pan & zoom. This version reprojects the geometry on interaction; compare to updating the transform.

index.html

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

body {
  margin: 0;
}

path {
  fill: none;
  stroke: red;
  stroke-linejoin: round;
  stroke-width: 1.5px;
}

</style>
<body>
<script src="//d3js.org/d3.v3.min.js"></script>
<script src="//d3js.org/d3.geo.tile.v0.min.js"></script>
<script src="//d3js.org/topojson.v1.min.js"></script>
<script>

var width = Math.max(960, window.innerWidth),
    height = Math.max(500, window.innerHeight);

var tile = d3.geo.tile()
    .size([width, height]);

var projection = d3.geo.mercator()
    .scale((1 << 12) / 2 / Math.PI)
    .translate([width / 2, height / 2]);

var center = projection([-100, 40]);

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

var zoom = d3.behavior.zoom()
    .scale(projection.scale() * 2 * Math.PI)
    .scaleExtent([1 << 11, 1 << 14])
    .translate([width - center[0], height - center[1]])
    .on("zoom", zoomed);

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

var raster = svg.append("g");

var vector = svg.append("path");

d3.json("/d/4090846/us.json", function(error, us) {
  svg.call(zoom);
  vector.datum(topojson.mesh(us, us.objects.states));
  zoomed();
});

function zoomed() {
  var tiles = tile
      .scale(zoom.scale())
      .translate(zoom.translate())
      ();

  projection
      .scale(zoom.scale() / 2 / Math.PI)
      .translate(zoom.translate());

  vector
      .attr("d", path);

  var image = raster
      .attr("transform", "scale(" + tiles.scale + ")translate(" + tiles.translate + ")")
    .selectAll("image")
      .data(tiles, function(d) { return d; });

  image.exit()
      .remove();

  image.enter().append("image")
      .attr("xlink:href", function(d) { return "//" + ["a", "b", "c", "d"][Math.random() * 4 | 0] + ".tiles.mapbox.com/v3/examples.map-vyofok3q/" + d[2] + "/" + d[0] + "/" + d[1] + ".png"; })
      .attr("width", 1)
      .attr("height", 1)
      .attr("x", function(d) { return d[0]; })
      .attr("y", function(d) { return d[1]; });
}

</script>