I was trying to get same behavior Wil Linssen's implementation but on d3.js version 4. I am quite confused with zoom api in version 4.
The changes that I made in the original implementation is:
zoom.translate()
replaced with
d3.zoomTransform(selection.node())
and appropriate points added instead:
svg.attr("transform",
"translate(" + t.x + "," + t.y + ")" +
"scale(" + t.k + ")"
);
This one:
zoom
.scale(iScale(t))
.translate(iTranslate(t));
replaced to
var foo = iTranslate(t);
zoom.
translateBy(selection, foo[0], foo[1]);
zoom
.scaleBy(selection, iScale(t));
But it's still has a problem, looks like with scale, zoom out...
Example: Example on d3.v4 - jsfiddle
Thanks for the help
After researching the most easiest way to use d3 v4 api that provides interpolation etc out of box. In original question zoom implemented from scratch, that doesn't make sense in version 4. Solution is similar to @Nixie answers and has few lines of code.
This version includes pan as well, if you do not need, remove svg.call(zoom);
Final example: Zoom D3 v4 - jsfiddle
One interesting note: The function:
function transition() {
svg.transition()
.delay(100)
.duration(700)
.call(zoom.scaleTo, zoomLevel);
//.on("end", function() { canvas.call(transition); });
}
call(zoom.ScaleTo, zoomLevel)
- will zoom to the center of page. But if you need the center of an image, use this one: call(zoom.transform, transform);
Where transform
is a function that sets center of your image. For example of such function:
function transform() {
return d3.zoomIdentity
.translate(width / 2.75, height / 2.75)
.scale(zoomLevel)
.translate(-width/2.75, -height/2.75);
}
This piece of code does not resolve all the problems, but could be a starting point. In D3 v4 you can transition zoom in one line of code (see also https://github.com/d3/d3-zoom/blob/master/README.md#zoom_transform)
function interpolateZoom (translate, scale) {
return selection.transition().duration(350)
.call(zoom.transform,
d3.zoomIdentity.translate(translate[0], translate[1]).scale(scale))
}
Modified example: https://jsfiddle.net/2yx1cLrq/. Also, you need to replace selection
with selection.node()
in all calls to d3.zoomTransform
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With