Skip to content

Instantly share code, notes, and snippets.

@tlfrd
Last active August 22, 2017 15:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tlfrd/72563f24d7e86fcf8739f8c430c422b1 to your computer and use it in GitHub Desktop.
Save tlfrd/72563f24d7e86fcf8739f8c430c422b1 to your computer and use it in GitHub Desktop.
Another Earth(s)
license: mit

Using an orthographic projection to make rotating earths which orbit a given point. Very slow as it uses SVG. This may be modified to use canvas at a later point (see my early experiments with canvas here).

<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/topojson.v2.min.js"></script>
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
body {
background-color: black;
}
.orbit {
fill: none;
stroke: white;
}
</style>
</head>
<body>
<script>
var width = 960,
height = 500,
rotate = [0, 0, 0];
velocity = [0.05, 0, 0]
time = Date.now();
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + [width / 2, height / 2] + ")");
d3.json("https://unpkg.com/world-atlas@1.1.4/world/110m.json", function(error, world) {
if (error) throw error;
addOrbitingEarth(world, 200, 10, "#AED6F1", 0, 4);
addOrbitingEarth(world, 120, 20, "#dadada", 0, 5);
addOrbitingEarth(world, 40, 15, "#ff83c3", 0, 6);
})
function addOrbitingEarth(geometry, orbitRadius, earthRadius, colour, phi0, speed) {
var orbit = svg.append("circle")
.attr("class", "orbit")
.attr("r", orbitRadius);
var land = topojson.feature(geometry, geometry.objects.land);
var projection = d3.geoOrthographic()
.scale(earthRadius)
.translate([0, orbitRadius])
.clipAngle(90)
.precision(0);
var path = d3.geoPath()
.projection(projection);
var circle = svg.append("circle")
.attr("cy", orbitRadius)
.attr("r", earthRadius)
.style("stroke", "white")
.style("fill", colour);
var earth = svg.append("path")
.datum(land)
.attr("d", path);
d3.timer(function() {
var dt = Date.now() - time;
projection.rotate([rotate[0] + velocity[0] * dt, rotate[1] + velocity[1] * dt, rotate[2] + velocity[2] * dt]);
earth.attr("d", path);
earth.attr("transform", d => "rotate(" + phi0 + dt * speed / 200 + ")");
circle.attr("transform", d => "rotate(" + phi0 + dt * speed / 200 + ")");
});
}
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment