Skip to content

Instantly share code, notes, and snippets.

Forked from HarryStevens/.block
Created May 28, 2021
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>
body {
font-family: "Helvetica Neue", sans-serif;
margin: 0;
<script src=""></script>
<script src=""></script>
var width = window.innerWidth, height = window.innerHeight;
var projection = d3.geoOrthographic()
.scale(width / 4.1)
.translate([width / 2, height / 2])
var path = d3.geoPath()
var svg ="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]);
.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;
.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");
.attr("class", "text")
.attr("x", 10)
.attr("y", height / 2)
.attr("dy", -5)
.attr("fill", "steelblue")
svg.on("mousemove", function(){
var y = d3.mouse(this)[1];".line")
.attr("y1", y)
.attr("y2", y);".text")
.attr("y", y)
.text(Math.round(y / height * 100) + "%");
d3.timer(function(elapsed) {
projection.rotate([.05 * elapsed - 120, ph(".line").attr("y1")), 0]);
g.selectAll("path").attr("d", path);
var c = d3.scaleOrdinal(d3.schemeCategory20);
d3.json("countries.json", function(error, data){
.data(topojson.feature(data, data.objects.polygons).features)
.attr("class", "subunit")
.attr("d", path)
.style("stroke", "#fff")
.style("stroke-width", "1px")
.style("fill", function(d,i){ return c(i); })
.style("opacity", ".6");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment