block by mbostock 6301817

Map Zooming II

Full Screen

This variation of the map zooming example uses interaction to control a smooth zooming interpolator. Mouse over the map to zoom between San Francisco and New York.

index.html

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

canvas {
  -webkit-tap-highlight-color: rgba(0,0,0,0);
}

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

var width = 960,
    height = 500;

// This projection is baked into the TopoJSON file,
// but is used here to compute the desired zoom translate.
var projection = d3.geo.mercator()
    .translate([0, 0])
    .scale(4000);

var interpolate = d3.interpolateZoom(
  projection([-122.417, 37.775]).concat(width / 6),
  projection([-74.0064, 40.7142]).concat(width / 4)
);

var scale,
    translate,
    area; // minimum area threshold for simplification

var clip = d3.geo.clipExtent()
    .extent([[0, 0], [width, height]]);

var simplify = d3.geo.transform({
  point: function(x, y, z) {
    if (z >= area) this.stream.point(x * scale + translate[0], y * scale + translate[1]);
  }
});

var canvas = d3.select("body").append("canvas")
    .attr("width", width)
    .attr("height", height)
    .on("mousemove", mousemoved)
    .on("touchmove", touchmoved);

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

var path = d3.geo.path()
    .projection({stream: function(s) { return simplify.stream(clip.stream(s)); }})
    .context(context);

d3.json("us-states.json", function(error, json) {
  if (error) throw error;

  canvas.datum(topojson.mesh(topojson.presimplify(json)));
  render(0);
});

function touchmoved() {
  render(d3.touches(this)[0][0] / width);
  d3.event.preventDefault();
}

function mousemoved() {
  render(d3.mouse(this)[0] / width);
}

function render(t) {
  var point = interpolate(t);
  scale = width / point[2];
  translate = [width / 2 - point[0] * scale, height / 2 - point[1] * scale];
  area = 1 / scale / scale;
  context.clearRect(0, 0, width, height);
  context.beginPath();
  canvas.each(path);
  context.stroke();
}

</script>