I have taken an example of Mike Bostock's D3 zoom transitions in canvas. After trying to set the projection without magic numbers (via this post) I'm still unable to zoom in on an arbitrary feature dynamically. I've created an example jsfiddle that has a series of buttons at the bottom that correspond to geojson features.
It has a function called onClick
that takes a feature. I'm trying to compute the translation and scale, and then update zoomTo
, and finally call the zoom transition
to ease into the bounding box.
function onClick(state) {
console.log('zoom transition to state: ', state);
var bounds = path.bounds(state),
dx = bounds[1][0] - bounds[0][0],
dy = bounds[1][4] - bounds[0][5],
x = (bounds[0][0] + bounds[1][0]) / 2,
y = (bounds[0][6] + bounds[1][7]) / 2,
scale = .9 / Math.max(dx / width, dy / height),
translate = [width / 2 - scale * x, height / 2 - scale * y];
console.log('bounds', bounds);
console.log('scale', scale);
console.log('translate', translate);
// var locaction = getLocation(state);
// var scale = getScale(state);
// transition and zoom to state.
// zoomTo(location, scale);
}
Other zooming examples like "Zoom to Bounding Box" don't quite fit in this case. Instead of rendering to SVG and using svg attributes like transform
, we're rendering to canvas. path
is perfectly capable of rendering to HTML canvas, but take note that the path
function is highly customized with its own projection. Indeed, attempting to use bounds
to find the bounding box will give back NaN, NaN. These are logged to the console.
Success is being able to click on a state and watch it zoom in smoothly.