block by mbostock 5707610

TopoJSON Parallax

Full Screen

Adding a little parallax to the U.S. TopoJSON example to illustrate the different layers.

index.html

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

svg {
  position: absolute;
  top: 0;
  left: 0;
}

path {
  stroke-linejoin: round;
}

.land-glow {
  fill: #000;
  fill-opacity: .2;
  filter: url(#glow);
}

.land-fill {
  fill: #fff;
}

.state-boundary {
  fill: none;
  stroke: #777;
  stroke-width: .70px;
}

.county-boundary {
  fill: none;
}

.land-fill,
.county-boundary {
  stroke: #777;
  stroke-width: .35px;
}

</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 = 600;

var projection = d3.geo.albersUsa()
    .scale(1285)
    .translate([width / 2, height / 2]);

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

d3.json("/mbostock/raw/4090846/us.json", function(error, us) {
  if (error) throw error;

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

  svgGlow.append("defs").append("path")
      .datum(topojson.feature(us, us.objects.land))
      .attr("id", "land")
      .attr("d", path);

  svgGlow.append("filter")
      .attr("id", "glow")
    .append("feGaussianBlur")
      .attr("stdDeviation", 5);

  svgGlow.append("use")
      .attr("class", "land-glow")
      .attr("xlink:href", "#land");

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

  svgLand.append("use")
      .attr("class", "land-fill")
      .attr("xlink:href", "#land");

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

  svgCounty.append("path")
      .datum(topojson.mesh(us, us.objects.counties, function(a, b) {
        return a !== b // a border between two counties
            && (a.id === 53000 || b.id === 5300 // where a and b are in puget sound
              || a.id % 1000 && b.id % 1000) // or a and b are not in a lake
            && !(a.id / 1000 ^ b.id / 1000); // and a and b are in the same state
      }))
      .attr("d", path)
      .attr("class", "county-boundary");

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

  svgState.append("path")
      .datum(topojson.mesh(us, us.objects.states, function(a, b) {
        return a !== b; // a border between two states
      }))
      .attr("d", path)
      .attr("class", "state-boundary");

  d3.selectAll("svg")
      .style(vendor + "transform-style", "preserve-3d");

  d3.select(window).on("mousemove", function() {
    var x = d3.event.clientX - width / 2,
        y = d3.event.clientY - height / 2;
    svgGlow.style(vendor + "transform", "translateX(" + x * .02 + "px)translateY(" + y * .01 + "px)");
    svgLand.style(vendor + "transform", "translateX(" + x * .04 + "px)translateY(" + y * .02 + "px)");
    svgCounty.style(vendor + "transform", "translateX(" + x * .08 + "px)translateY(" + y * .04 + "px)");
    svgState.style(vendor + "transform", "translateX(" + x * .16 + "px)translateY(" + y * .08 + "px)");
  });
});

d3.select(self.frameElement).style("height", height + "px");

var vendor = (function(p) {
  var i = -1, n = p.length, s = document.body.style;
  while (++i < n) if (p[i] + "Transform" in s) return "-" + p[i].toLowerCase() + "-";
  return "";
})(["webkit", "ms", "Moz", "O"]);

</script>