D3 Constrained zoom

http://bl.ocks.org/tommct/8047063

HTML

<!DOCTYPE html>
<meta charset="utf-8">
<title>Canvas image zoom</title>
<script src="https://d3js.org/d3.v3.min.js"></script>
<body>
<h1>D3 zoomable image class</h1>
<div id="figure" style="float:left; position:relative;"></div>
</body>
<script src="image.js" type="text/javascript"></script>
<script>
    let masterImg = new Image();
    let figure = new Figure(d3.select("div#figure"), 640, 480);
    masterImg.onload = function() {
        figure.loaded(masterImg)
    };
    masterImg.src = "http://www.dieselstation.com/wallpapers/albums/Lincoln/Mark-X-Concept-2004/Lincoln-Mark-X-Concept-2004-widescreen-03.jpg";
</script>
</html>

CSS

body {
  position: relative;
}

svg,
canvas {
  position: absolute;
}

.axis text {
  font: 10px sans-serif;
}

.axis path,
.axis line {
  fill: none;
  stroke: #000;
  shape-rendering: crispEdges;
}

JavaScript

const margin = {top: 20, right: 10, bottom: 20, left: 60};

class Figure {

    constructor(div,width,height) {
        this.width = width;
        this.height = height;

        // Canvas is drawn first, and then SVG over the top.
        this.canvas = div.append("canvas")
            .attr("width",width)
            .attr("height", height)
            .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
            .style("left", margin.left + "px")
            .style("top", margin.top + "px")
            .style("width", width + "px")
            .style("height", height + "px")
            .style("position", "absolute")
            .style("z-index",0)
            .on('click', () => {
                // Get coordinates of click relative to the canvas element
                let pos = d3.mouse(this.canvas.node());
                console.log('canvas click ' + pos);
            });

        this.svg = div.append("svg")
            .attr("width", width + margin.left + margin.right)
            .attr("height", height + margin.top + margin.bottom)
            .append("g")
            .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
            .style("position", "absolute")
            .style("z-index",1)
            .on('click', () => {
                // Get coordinates of click relative to the canvas element
                let pos = d3.mouse(this.svg.node());
                console.log('svg click ' + pos);
            });

        // We make an invisible rectangle to intercept mouse events
        this.rect=this.svg.append("rect")
            .attr("width", width)
            .attr("height", height)
            .style("fill", "000")
            .style("opacity", 1e-6)
            .style("position", "absolute")
            .style("z-index",2)
            .on("click", () => {
                let pos = d3.mouse(this.rect.node());
                console.log('rect click '+pos);
            })

        console.log('Figure...