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> |