Skip to content

Instantly share code, notes, and snippets.

@rob4acre
Last active May 16, 2018 05:53
Show Gist options
  • Save rob4acre/c42948e51c486d2fa98cd1fa0f8159ca to your computer and use it in GitHub Desktop.
Save rob4acre/c42948e51c486d2fa98cd1fa0f8159ca to your computer and use it in GitHub Desktop.
drag rotate globe
license: mit
<!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>
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment