This done with svg /mbostock/6242308 using this technique /mbostock/2374239
xxxxxxxxxx
<head>
<meta charset="utf-8">
<title>FUN</title>
<style>
.graticule {
fill: none;
stroke: #777;
stroke-opacity: .5;
}
.boundary {
fill: none;
stroke: #fff;
}
.overlay {
fill: none;
pointer-events: all;
}
</style>
</head>
<body>
<script src="https://d3js.org/d3.v3.min.js"></script>
<script src="https://d3js.org/topojson.v1.min.js"></script>
<script>
var margin = {top: 0, right: 0, bottom: 0, left: 0};
var width = 960;
var height = 500;
var sf = [-122.417, 37.775],
ny = [-74.0064, 40.7142],
hk = [114.1589, 22.2783];
var scale = (width + 1) / 2 / Math.PI;
var projection = d3.geo.mercator()
.translate([0, 0])
.scale(scale)
.precision(0.1);
var graticule = d3.geo.graticule();
var path = d3.geo.path();
var zoom = d3.behavior.zoom()
.translate([0, 0])
.scale(1)
.scaleExtent([1, 8])
.on("zoom", zoomed);
var svg = d3.select('body').append('svg')
.attr('width', width)
.attr('height', height)
.attr('class', 'world');
var features = svg.append('g').attr('class', features);
projection.translate([width/2, height/2]).scale(scale);
path.projection(projection);
features.append("path")
.datum(graticule)
.attr("class", "graticule")
.style('stroke-width', 0.5 + 'px')
.attr("d", path);
var countries = features.insert('g', '.graticule')
.attr('class', 'countries');
var points = features.insert('g', '.graticule')
.attr('class', 'points');
d3.json('world.json', function(err, data) {
countries.selectAll('.country')
.data(topojson.feature(topojson.presimplify(data), data.objects.countries).features)
.enter().append('path')
.attr('class', 'country')
.attr('d', path)
.append('title')
.text(function(d) { return d.properties.name; });
features.insert("path", ".graticule")
.datum(topojson.mesh(topojson.presimplify(data), data.objects.countries, function(a, b) { return a !== b; }))
.attr("class", "boundary")
.style('stroke-width', 1.0)
.attr("d", path);
svg.append("rect")
.attr("class", "overlay")
.attr("width", width)
.attr("height", height)
.call(zoomTo(hk, 4).event)
.transition()
// .duration(60 * 1000 / 89 * 2)
.duration(5000)
.each(jump);
});
function zoomed() {
features.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
features.select('.graticule').style('stroke-width', 0.5 / d3.event.scale + "px");
features.select('.boundary').style('stroke-width', 1.0 / d3.event.scale + "px");
}
function zoomTo(location, scale) {
var point = projection(location);
return zoom
.translate([width / 2 - point[0] * scale, height / 2 - point[1] * scale])
.scale(scale);
}
function jump() {
var t = d3.select(this);
(function repeat() {
t = t.transition()
.call(zoomTo(ny, 4).event)
.transition()
.call(zoomTo(sf, 4).event)
.each("end", repeat);
})();
}
</script>
Modified http://d3js.org/d3.v3.min.js to a secure url
Modified http://d3js.org/topojson.v1.min.js to a secure url
https://d3js.org/d3.v3.min.js
https://d3js.org/topojson.v1.min.js