Skip to content

Instantly share code, notes, and snippets.

@tlfrd
Last active August 22, 2017 15:52
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/685e3272c04365f0831e34cc8dde641f to your computer and use it in GitHub Desktop.
Save tlfrd/685e3272c04365f0831e34cc8dde641f to your computer and use it in GitHub Desktop.
Earth Small Multiples
license: mit

Experimenting with canvas (for the first time) to create small multiples of the Earth using an orthographic projection.

<!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; }
</style>
</head>
<body>
<script>
var width = 960,
height = 500;
var margin = {top: 100, left: 100, right: 100, bottom: 100};
var globesHorizontal = 8;
var diameter = (width - margin.left - margin.right) / globesHorizontal,
radius = diameter / 2,
velocity = 0.05;
var globesVertical = Math.floor((height - margin.top - margin.bottom) / diameter);
var data = d3.range(globesHorizontal * globesVertical);
var colour = d3.scaleSequential(d3.interpolateRainbow)
.domain([0, data.length]);
var canvas = d3.select("body").append("canvas")
.datum(function() { return this.getContext("2d"); })
.attr("width", width)
.attr("height", height)
.node().getContext("2d");
d3.json("https://unpkg.com/world-atlas@1.1.4/world/110m.json", function(error, world) {
if (error) throw error;
var land = topojson.feature(world, world.objects.land),
globe = {type: "Sphere"};
var graticule = d3.geoGraticule();
data.forEach(function(x) {
var projection = d3.geoOrthographic()
.scale(radius - 2)
.translate([(diameter * (x % globesHorizontal)) + radius + margin.left,
(diameter * Math.floor(x / globesHorizontal)) + radius + margin.top])
.clipAngle(90)
.precision(0.1);
var path = d3.geoPath()
.projection(projection)
.context(canvas);
var angle = 360 / data.length * x;
var rotate = [0, 0, 0];
rotate[0] = angle, projection.rotate(rotate);
// Clear Canvas
canvas.clearRect((diameter * (x % globesHorizontal)) + margin.left, (diameter * Math.floor(x / globesHorizontal)) + margin.top, diameter, diameter);
// Draw Sphere
canvas.beginPath(), path(globe), canvas.strokeStyle = colour(x), canvas.stroke(), canvas.stroke();
// Draw graticule lines
canvas.beginPath(), path(graticule()), canvas.strokeStyle = colour(x), canvas.stroke();
// Draw land
canvas.beginPath(), path(land), canvas.fillStyle = colour(x), canvas.fill();
});
});
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment