d3.js: Zoom on click event

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