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...