A quick hack on the beautifully executed projection example from Andy Woodruff. I just wanted to see them all on one screen.
Click the Open in new window button to see them all.
Novel code Inspired once again by Jason Davies.
Andy's original text:
We've all seen the projected head from Elements of map projection with applications to map and chart construction, but the authors in 1921 did not have D3 to help them show a full range of weird distorted faces. This is based on the Map Projection Transitions example by Jason Davies.
xxxxxxxxxx
<meta charset="utf-8">
<title>PROJECTION FACE</title>
<style>
body{ text-align: center }
canvas {
cursor: move;
}
.world {
float:left;
margin-right: 20px;
position:relative;
}
.center {
text-align: center;
}
#maps {
width: 1200px;
margin: auto;
}
.world h2 {
font-size: 16px;
width: 250px;
margin: auto;
position: absolute;
text-align: center;
}
</style>
<div id="maps"></div>
<script src="https://d3js.org/d3.v3.min.js"></script>
<script src="https://d3js.org/d3.geo.projection.v0.min.js"></script>
<script src="https://d3js.org/d3.geo.polyhedron.v0.min.js"></script>
<script>
var ratio = window.devicePixelRatio || 1,
width = 250 * ratio,
height = 250 * ratio;
scaler = 0.5;
var options = [
{name: "Aitoff", projection: d3.geo.aitoff()},
{name: "Albers", projection: d3.geo.albers().scale(145).parallels([20, 50])},
{name: "August", projection: d3.geo.august().scale(60)},
{name: "Baker", projection: d3.geo.baker().scale(100)},
{name: "Berghaus", projection: d3.geo.berghaus().scale(100)},
{name: "Boggs", projection: d3.geo.boggs()},
{name: "Bonne", projection: d3.geo.bonne().scale(100)},
{name: "Bromley", projection: d3.geo.bromley()},
{name: "Collignon", projection: d3.geo.collignon().scale(93)},
{name: "Craster Parabolic", projection: d3.geo.craster()},
{name: "Eckert I", projection: d3.geo.eckert1().scale(165)},
{name: "Eckert II", projection: d3.geo.eckert2().scale(165)},
{name: "Eckert III", projection: d3.geo.eckert3().scale(180)},
{name: "Eckert IV", projection: d3.geo.eckert4().scale(180)},
{name: "Eckert V", projection: d3.geo.eckert5().scale(170)},
{name: "Eckert VI", projection: d3.geo.eckert6().scale(170)},
{name: "Eisenlohr", projection: d3.geo.eisenlohr().scale(60)},
{name: "Equirectangular (Plate Carrée)", projection: d3.geo.equirectangular()},
{name: "Fahey", projection: d3.geo.fahey().scale(120)},
{name: "Gall Stereographic", projection: d3.geo.cylindricalStereographic().parallel(45).scale(140)},
{name: "Goode Homolosine", projection: d3.geo.homolosine()},
{name: "Ginzburg IV", projection: d3.geo.ginzburg4().scale(120)},
{name: "Ginzburg V", projection: d3.geo.ginzburg5().scale(120)},
{name: "Ginzburg VI", projection: d3.geo.ginzburg6().scale(120)},
{name: "Ginzburg VIII", projection: d3.geo.ginzburg8().scale(120)},
{name: "Ginzburg IX", projection: d3.geo.ginzburg9().scale(120)},
{name: "Gringorten", projection: d3.geo.gringorten().scale(220)},
{name: "Guyou", projection: d3.geo.guyou().scale(150)},
{name: "Hammer", projection: d3.geo.hammer().scale(165)},
{name: "Hammer Retroazimuthal", projection: d3.geo.hammerRetroazimuthal().scale(90)},
{name: "HEALPix", projection: d3.geo.healpix()},
{name: "Hill", projection: d3.geo.hill().scale(120)},
{name: "Kavrayskiy VII", projection: d3.geo.kavrayskiy7()},
{name: "Lagrange", projection: d3.geo.lagrange().scale(120)},
{name: "Lambert cylindrical equal-area", projection: d3.geo.cylindricalEqualArea()},
{name: "Larrivée", projection: d3.geo.larrivee().scale(95)},
{name: "Laskowski", projection: d3.geo.laskowski().scale(120)},
{name: "Loximuthal", projection: d3.geo.loximuthal()},
{name: "Mercator", projection: d3.geo.mercator().scale(100)},
{name: "Miller", projection: d3.geo.miller().scale(100)},
{name: "McBryde–Thomas Flat-Polar Parabolic", projection: d3.geo.mtFlatPolarParabolic()},
{name: "McBryde–Thomas Flat-Polar Quartic", projection: d3.geo.mtFlatPolarQuartic()},
{name: "McBryde–Thomas Flat-Polar Sinusoidal", projection: d3.geo.mtFlatPolarSinusoidal()},
{name: "Mollweide", projection: d3.geo.mollweide().scale(165)},
{name: "Natural Earth", projection: d3.geo.naturalEarth()},
{name: "Nell–Hammer", projection: d3.geo.nellHammer()},
{name: "Orthographic", projection: d3.geo.orthographic().scale(200)},
{name: "Polyconic", projection: d3.geo.polyconic().scale(100)},
{name: "Rectangular Polyconic", projection: d3.geo.rectangularPolyconic().scale(120)},
{name: "Robinson", projection: d3.geo.robinson()},
{name: "Sinusoidal", projection: d3.geo.sinusoidal()},
{name: "Sinu-Mollweide", projection: d3.geo.sinuMollweide()},
{name: "Stereographic", projection: d3.geo.stereographic()},
{name: "Times", projection: d3.geo.times().scale(140)},
{name: "Van der Grinten", projection: d3.geo.vanDerGrinten().scale(75)},
{name: "Van der Grinten II", projection: d3.geo.vanDerGrinten2().scale(75)},
{name: "Van der Grinten III", projection: d3.geo.vanDerGrinten3().scale(75)},
{name: "Van der Grinten IV", projection: d3.geo.vanDerGrinten4().scale(120)},
{name: "Wagner IV", projection: d3.geo.wagner4()},
{name: "Wagner VI", projection: d3.geo.wagner6()},
{name: "Wagner VII", projection: d3.geo.wagner7()},
{name: "Waterman", projection: d3.geo.polyhedron.waterman().scale(70)},
{name: "Winkel Tripel", projection: d3.geo.winkel3()}
];
var i = 0,
n = options.length - 1;
var projection = options[i].projection;
options.forEach(function(option) {
option.projection
.translate([width / 2, height / 2])
.scale(option.projection.scale() * ratio * scaler)
.clipExtent([[2 * ratio, 2 * ratio], [width - 2 * ratio, height - 2 * ratio]]);
});
var graticule = d3.geo.graticule()(),
origin = {x: 0, y: 0},
face,
boundaries;
function draw(error, face) {
var div = d3.select("#maps").selectAll(".world")
.data(options)
var divE = div.enter().append("div")
.attr("class", "world")
divE.append("h2").text(function(d) { return d.name; });
divE.append("canvas")
.attr("width", width)
.attr("height", height)
.style("width", width / ratio + "px")
.style("height", height / ratio + "px")
.call(d3.behavior.drag()
.origin(function() { return origin; })
.on("drag", function() {
origin.x = d3.event.x;
origin.y = d3.event.y;
update();
}))
.datum(function(d) {
var projection = d.projection;
var canvas = this;
var context = canvas.getContext("2d");
var path = d3.geo.path()
.context(context)
.projection(projection);
return function() {
context.clearRect(0, 0, width, height);
context.fillStyle = "#eef";
context.beginPath(), path({type: "Sphere"}), context.fill();
context.fillStyle = "#3c3";
context.lineWidth = .5 * ratio;
context.beginPath(), path(d[1]), context.fill(), context.stroke();
context.strokeStyle = "#999";
context.beginPath(), path(graticule), context.stroke();
if (face) {
context.strokeStyle = "#000";
context.lineWidth = 2;
context.beginPath(), path(face), context.stroke();
}
};
})
update();
function update() {
options.forEach(function(option) {
var projection = option.projection;
projection.rotate([origin.x, -origin.y]);
});
div.selectAll("canvas").each(function(d) {
d();
});
}
}
function redraw(path) {
context.clearRect(0, 0, width, height);
context.lineWidth = .5 * ratio;
context.strokeStyle = "#999";
context.beginPath(), path(graticule), context.stroke();
context.beginPath(), path({type: "Sphere"}), context.stroke();
context.lineWidth = 2 * ratio;
if (face) {
context.strokeStyle = "#000";
context.lineWidth = 2;
context.beginPath(), path(face), context.stroke();
}
}
d3.json("face.geojson", function(error, data) {
face = data;
draw(error, face)
});
</script>
</body>
</html>
Modified http://d3js.org/d3.v3.min.js to a secure url
Modified http://d3js.org/d3.geo.projection.v0.min.js to a secure url
Modified http://d3js.org/d3.geo.polyhedron.v0.min.js to a secure url
https://d3js.org/d3.v3.min.js
https://d3js.org/d3.geo.projection.v0.min.js
https://d3js.org/d3.geo.polyhedron.v0.min.js