https://jsfiddle.net/Goulu/gyf74p9q/显示http://bl.ocks.org/tommct/8047063的可重复使用的D3js类实现,其中svg层叠加在画布上以处理pan&缩放事件
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 created')
}
当在JSfiddle中运行时它运行得很好(好吧,缩放还没有......)但是当点击图像时,控制台显示事件被svg和rect拦截,而不是画布,应该是。
现在,在我的机器上运行完全相同的代码时,通过打开包含以下内容的html文档(以及image.js中的JSFiddle脚本),日志显示点击仅由画布处理!!! / p>
这怎么可能?我只是浪费了几个小时......
<!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>
BTW,为什么原作者在画布上添加一个svg rect而不是直接处理事件并用画布直接缩放?