Built with blockbuilder.org
forked from Fil's block: Poor man's Composite projection
license: mit |
Built with blockbuilder.org
forked from Fil's block: Poor man's Composite projection
<!DOCTYPE html> | |
<head> | |
<meta charset="utf-8"> | |
<script src="https://d3js.org/d3.v4.js"></script> | |
<script src="https://d3js.org/d3-geo-projection.v2.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; } | |
path { fill: none; stroke: black; } | |
#land { fill: black } | |
#sphere { stroke-width: 2; fill: lightblue; } | |
#invert { fill: red} | |
</style> | |
</head> | |
<body> | |
<script> | |
// Feel free to change or delete any of the code you see in this editor! | |
var svg = d3.select("body").append("svg") | |
.attr("width", 960) | |
.attr("height", 500) | |
var projections = [ | |
d3.geoLagrange() | |
.clipExtent([[0,0],[480,250]]), | |
d3.geoAzimuthalEqualArea() | |
.clipExtent([[480,0],[960,250]]), | |
d3.geoOrthographic() | |
.clipExtent([[0,250],[480,500]]), | |
d3.geoAzimuthalEquidistant() | |
.clipExtent([[480,250],[960,500]]) | |
]; | |
//o = d3.geoCircle().center([0,0]).radius(10)(); | |
var paths = projections.map(p => d3.geoPath(p)); | |
var projection = {}; | |
projection.invert = function(p) { | |
for( var i = 0; i < projections.length; i++) { | |
var k = projections[i].invert(p); | |
if (k && paths[i]({type:"Point", coordinates: k})) | |
return k; | |
} | |
} | |
svg.on('mousemove', function(){ | |
var m = d3.mouse(this); | |
point.datum({ | |
type:"Point", | |
coordinates: projection.invert(m) | |
}) | |
}) | |
var path = function(d) { | |
return paths.map(p => p(d)) | |
.filter(d => !!d) | |
.join("") || null; | |
} | |
svg.append("path") | |
.attr("id", "sphere") | |
.datum({type: "Sphere"}) | |
.attr('d', d3.geoPath(d3.geoOrthographic())) | |
svg.append("path") | |
.datum(d3.geoGraticule()()) | |
.classed('composite', true) | |
var land = svg.append("path") | |
.attr('id', 'land') | |
.classed('composite', true); | |
var point = svg.append("path") | |
.attr('id', "invert") | |
.classed('composite', true) | |
.datum({ type:"Point", coordinates: [1,2] }) | |
d3.json("https://unpkg.com/world-atlas@1/world/110m.json", function( | |
error, | |
world | |
) { | |
land.datum(topojson.merge(world, world.objects.countries.geometries)); | |
} | |
); | |
if (1) | |
d3.timer(_ => { | |
projections[0].rotate([_/100, 0]) | |
projections[1].rotate([30, _/100, -_/100]) | |
projections[2].rotate([_/100, 0, -_/100]) | |
projections[3].rotate([_/100, _/100, _/100]) | |
svg.selectAll('path.composite') | |
.attr("d", path); | |
}) | |
</script> | |
</body> |