Built with blockbuilder.org
Last active
May 16, 2018 05:53
-
-
Save rob4acre/c42948e51c486d2fa98cd1fa0f8159ca to your computer and use it in GitHub Desktop.
drag rotate globe
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
license: mit |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<head> | |
<meta charset="utf-8"> | |
<script src="https://d3js.org/d3.v5.min.js"></script> | |
<script src="//d3js.org/d3-geo-projection.v1.min.js"></script> | |
<script src="//d3js.org/topojson.v2.min.js"></script> | |
<style> | |
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; } | |
.graticule { | |
fill: none; | |
stroke: #777; | |
stroke-width: .5px; | |
stroke-opacity: .5; | |
} | |
.sphere { | |
fill: #7BB5FF; | |
} | |
.gradient { | |
fill: url(#gradient); | |
} | |
.country { | |
fill: #404F24; | |
fill-opacity: 0.7; | |
stroke: #eee; | |
stroke-width: 0.2; | |
} | |
</style> | |
</head> | |
<body> | |
<script> | |
function createMap() { | |
var width = 800, | |
height = 800, | |
scale = 300, | |
lastX = 0, | |
origin = { | |
x: 55, | |
y: 0 | |
}; | |
var svg = d3.select('body').append('svg') | |
.style('width', 1000) | |
.style('height', 1000) | |
.style('border', '1px black solid') | |
var projection = d3.geoOrthographic() | |
.scale(scale) | |
.translate([width / 2, height / 2]) | |
.rotate([origin.x, origin.y]) | |
.center([0, 0]) | |
.clipAngle(90); | |
var geoPath = d3.geoPath() | |
.projection(projection); | |
var graticule = d3.geoGraticule(); | |
var sphere = {type: "Sphere"}; | |
// setup the gradient to make the earth look brighter at top left | |
var gradient = svg.append("svg:defs") | |
.append("svg:linearGradient") | |
.attr("id", "gradient") | |
.attr("x1", "0%") | |
.attr("y1", "0%") | |
.attr("fx1", "50%") | |
.attr("fy1", "50%") | |
.attr("x2", "100%") | |
.attr("y2", "100%") | |
.attr("spreadMethod", "pad"); | |
gradient.append("svg:stop") // middle step setting | |
.attr("offset", "50%") | |
.attr("stop-color", "#fff") | |
.attr("stop-opacity", 0.6); | |
gradient.append("svg:stop") // final step setting | |
.attr("offset", "100%") | |
.attr("stop-color", "#006") | |
.attr("stop-opacity", 0.6); | |
// end setup gradient | |
// zoom AND rotate | |
svg.call(d3.zoom().on('zoom', zoomed)); | |
// code snippet from http://stackoverflow.com/questions/36614251 | |
var λ = d3.scaleLinear() | |
.domain([-width, width]) | |
.range([-180, 180]) | |
var globe = svg.append('g'); | |
// Draw the sphere for the earth | |
globe.append("path") | |
.datum(sphere) | |
.attr("class", "sphere") | |
.attr("d", geoPath); | |
// draw a gradient sphere because it looks cool | |
globe.append("path") | |
.datum(sphere) | |
.attr("class", "gradient") | |
.attr("d", geoPath) | |
globe.append('path') | |
.datum(graticule) | |
.attr('class', 'graticule') | |
.attr('d', geoPath); | |
d3.json('world-110m.json').then(function(world) { | |
var countries = topojson.feature(world, world.objects.countries).features; | |
// draw country outlines | |
globe.selectAll('.country') | |
.data(countries) | |
.enter() | |
.append('path') | |
.attr('class', 'country') | |
.attr('d', geoPath); | |
}); | |
function zoomed() { | |
var transform = d3.event.transform; | |
var r = { | |
x: λ(transform.x), | |
}; | |
// var k = Math.sqrt(100 / projection.scale()); | |
// if (d3.event.sourceEvent.wheelDelta) { | |
// projection.scale(scale * transform.k) | |
// transform.x = lastX; | |
// } else { | |
projection.rotate([origin.x + r.x, 0]); | |
lastX = transform.x; | |
// } | |
updatePaths(globe, graticule, geoPath); | |
}; | |
}; | |
function updatePaths(globe, graticule, geoPath) { | |
globe.selectAll('path.graticule').attr('d', geoPath); | |
globe.selectAll('path.country').attr('d', geoPath); | |
}; | |
createMap(); | |
</script> | |
</body> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment