Skip to content

Instantly share code, notes, and snippets.

@mbostock
Last active Sep 12, 2018
Embed
What would you like to do?
TopoJSON Parallax
license: gpl-3.0
<!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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment