Skip to content

Instantly share code, notes, and snippets.

@jczaplew
Last active February 17, 2017 05:20
Show Gist options
  • Save jczaplew/6830815 to your computer and use it in GitHub Desktop.
Save jczaplew/6830815 to your computer and use it in GitHub Desktop.
Lazy composite

Display global views using a Hammer projection with d3.js, everything else in a web mercator with Leaflet.js.

Edit: now with additional smoke and mirrors.

Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.6.3/leaflet.css" />
<script src="http://cdn.leafletjs.com/leaflet-0.6.3/leaflet.js"></script>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://d3js.org/d3.geo.projection.v0.min.js" charset="utf-8"></script>
<script src="http://d3js.org/topojson.v1.min.js"></script>
<style type="text/css">
.countries {
stroke: #000;
fill: #FEFBFB;
stroke-width: 0.5;
}
#map {
height:500px;
width:100%;
}
#zoom {
position: absolute;
margin-top:10px;
margin-left:10px;
}
</style>
</head>
<body>
<div id="zoom" class="leaflet-control-zoom leaflet-bar leaflet-control">
<a class="leaflet-control-zoom-in" href="#" title="Zoom in" id="zoomIn">+</a>
<a class="leaflet-control-zoom-out leaflet-disabled" href="#" title="Zoom out">-</a>
</div>
<div id="svgMap"></div>
<div id="map"></div>
<script type="text/javascript">
var map = new L.Map('map', {
center: new L.LatLng(7, 0),
zoom: 2,
maxZoom:10,
minZoom: 2
});
var attrib = 'Map tiles by <a href="http://stamen.com">Stamen Design</a>, <a href="http://creativecommons.org/licenses/by/3.0">CC BY 3.0</a> &mdash; Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors';
var stamen = new L.TileLayer('http://{s}.tile.stamen.com/toner-background/{z}/{x}/{y}.png', {attribution: attrib}).addTo(map);
map.on('moveend', function(d) {
var zoom = map.getZoom();
if (zoom < 3) {
d3.select("#map").style("width", 0);
d3.select("#svgMap").style("display", "block");
d3.selectAll("path").attr("d", path);
}
});
d3.select("#map").style("width", 0);
var width = window.innerWidth,
height = 500;
var projection = d3.geo.hammer()
.scale(165)
.translate([width / 2, height / 2])
.precision(.1);
var mercator = d3.geo.mercator()
.scale(165)
.precision(.1)
.translate([width / 2, height / 2]);
var path = d3.geo.path()
.projection(projection);
function changeMaps(mouse) {
var coords = mouse,
projected = mercator.invert(coords);
d3.select("#svgMap").style("display", "none");
d3.select("#map").style("width", "100%");
map.invalidateSize();
map.setView([parseInt(projected[1]), parseInt(projected[0])], 3, {animate:false});
}
var zoom = d3.behavior.zoom()
.on("zoom",function() {
if (d3.event.sourceEvent.wheelDelta > 0) {
changeMaps(d3.mouse(this));
}
});
var svg = d3.select("#svgMap").append("svg")
.attr("width", width)
.attr("height", height)
.call(zoom)
.on("click", function() {
changeMaps(d3.mouse(this));
});
svg.append("defs").append("path")
.datum({type: "Sphere"})
.attr("id", "sphere")
.attr("d", path);
svg.append("use")
.attr("class", "fill")
.attr("xlink:href", "#sphere");
d3.json("countries.json", function(error, data) {
svg.append("path")
.datum(topojson.feature(data, data.objects.countries))
.attr("class", "countries")
.attr("d", path);
});
d3.select("#zoomIn").on("click", function() {
d3.event.stopPropagation();
d3.select("#svgMap").style("display", "none");
d3.select("#map").style("width", "100%");
map.invalidateSize();
map.setView([7,0], 3, {animate:false});
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment