Skip to content

Instantly share code, notes, and snippets.

@HarryStevens

HarryStevens/.block

Last active May 28, 2021
Embed
What would you like to do?
Spin the Earth
license: gpl-3.0

Drag your mouse vertically to spin the Earth. Drag it to the bottom of the frame (100%) to view Antarctica; drag it to the top (0%) to search for Santa.

This map uses an orthographic projection with D3.js and Topojson to draw a map of the world's countries onto a spinning globe, rendered here with a graticule that is 10° by 10°.

The world countries polygons were downloaded from ArcGIS.

Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
<!DOCTYPE html>
<html>
<head>
<style>
body {
font-family: "Helvetica Neue", sans-serif;
margin: 0;
}
</style>
</head>
<body>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/topojson.v1.min.js"></script>
<script>
var width = window.innerWidth, height = window.innerHeight;
var projection = d3.geoOrthographic()
.scale(width / 4.1)
.translate([width / 2, height / 2])
.precision(1);
var path = d3.geoPath()
.projection(projection);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.style("cursor", "ns-resize");
var g = svg.append("g");
var graticule = d3.geoGraticule()
.step([10, 10]);
g.append("path")
.datum(graticule)
.attr("class", "graticule")
.attr("d", path)
.style("fill", "none")
.style("stroke", "#ccc");
var ph = d3.scaleLinear()
.domain([0, height])
.range([270, -270]);
var y = height / 2;
svg.append("line")
.attr("class", "line")
.attr("x1", 0)
.attr("x2", width)
.attr("y1", y)
.attr("y2", y)
.attr("stroke-dasharray", "5, 5")
.style("stroke", "steelblue")
.style("stroke-width", "2px");
svg.append("text")
.attr("class", "text")
.attr("x", 10)
.attr("y", height / 2)
.attr("dy", -5)
.attr("fill", "steelblue")
.text("50%");
svg.on("mousemove", function(){
var y = d3.mouse(this)[1];
d3.select(".line")
.attr("y1", y)
.attr("y2", y);
d3.select(".text")
.attr("y", y)
.text(Math.round(y / height * 100) + "%");
});
d3.timer(function(elapsed) {
projection.rotate([.05 * elapsed - 120, ph(d3.select(".line").attr("y1")), 0]);
g.selectAll("path").attr("d", path);
});
var c = d3.scaleOrdinal(d3.schemeCategory20);
d3.json("countries.json", function(error, data){
g.selectAll(".subunit")
.data(topojson.feature(data, data.objects.polygons).features)
.enter().append("path")
.attr("class", "subunit")
.attr("d", path)
.style("stroke", "#fff")
.style("stroke-width", "1px")
.style("fill", function(d,i){ return c(i); })
.style("opacity", ".6");
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment