@fxi/d3-geo-zoom
Version:
Zoom and Pan D3 Geo projections (Ported from vasturiano/d3-geo-zoom)
89 lines (76 loc) • 2.14 kB
HTML
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>D3 Geo Zoom Demo</title>
<style>
body {
margin: 0;
overflow: hidden;
background: linear-gradient(135deg, #1a1a1a 0%, #2c2c2c 100%);
}
.sphere {
fill: #1a1f35;
}
.land {
fill: #2a1b3d;
stroke: #ff69b4;
stroke-width: 0.5;
filter: url(#glow);
}
.land:hover {
fill: #3d2656;
}
</style>
</head>
<body>
<div id="world"></div>
<script type="module">
import { GeoZoom } from '/dist/@fxi/d3-geo-zoom.esm.js';
import * as d3 from 'd3';
import { feature } from 'topojson-client';
const MARGIN = 5;
const width = window.innerWidth;
const height = window.innerHeight;
const svg = d3.select('#world').append('svg')
.attr('width', width)
.attr('height', height);
// Add glow filter
const defs = svg.append('defs');
const filter = defs.append('filter')
.attr('id', 'glow');
filter.append('feGaussianBlur')
.attr('stdDeviation', '2')
.attr('result', 'coloredBlur');
const feMerge = filter.append('feMerge');
feMerge.append('feMergeNode')
.attr('in', 'coloredBlur');
feMerge.append('feMergeNode')
.attr('in', 'SourceGraphic');
const projection = d3.geoOrthographic()
.scale((Math.min(width, height)) / 2 - MARGIN)
.translate([width / 2, height / 2]);
const path = d3.geoPath()
.projection(projection);
new GeoZoom(svg.node())
.setProjection(projection)
.onMove(render)
.setNorthUp(true);
fetch('https://unpkg.com/world-atlas@1/world/110m.json')
.then(response => response.json())
.then(world => {
svg.append('path')
.attr('class', 'sphere')
.datum({ type: 'Sphere' });
svg.append('path')
.attr('class', 'land')
.datum(feature(world, world.objects.land));
render();
});
function render() {
svg.selectAll('path').attr('d', path);
}
</script>
</body>
</html>