我有一个小应用程序,其中包含不同的tools
。其中两个工具使用鼠标滚轮,但以不同的方式,我发现他们目前正在互相错误地互动。我想知道是否有办法阻止这种情况。
我将提供一个简化的noddy示例来演示这种影响。如果您运行代码段(在启动前单击SVG背景/圆圈),您应该可以使用鼠标滚轮进行缩放。
但是,如果您按住某个键(以模拟使用其他工具),则会记录鼠标滚轮增量而不是缩放。如果您在没有按下按键的情况下尝试变焦,则变焦会根据按下按键时的鼠标滚轮变化而跳跃。
我已经包含了一个动画gif来演示,当我试图在压制它一段时间后使用d3.behaviour.zoom
时,缩放是如何大幅跳跃的。所以我的问题是,有没有办法可以改变d3.behaviour.zoom
所以它只是在上一次操作后的delta上表现,或者有没有办法暂停它的刻度以防止这种跳跃?
var keydown = false;
// Random circles
const circles = d3.range(1000).map(function() {
return {
x: Math.random() * 700,
y: Math.random() * 400
}
});
// Create the random data, just so we can see when we're zooming
d3.select(".view")
.selectAll("circle")
.data(circles)
.enter()
.append("circle")
.attr("cx", d => d.x)
.attr("cy", d => d.y)
.attr("r", 5)
.style("fill", "red")
.style("pointer-events", "none");
// Create the D3 zoom and hook it up to the interaction layer
const zoom = d3.behavior.zoom()
.scaleExtent([0.1, 10])
.on("zoom", () => {
if (!keydown) {
d3.select(".view").attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
}
});
d3.select(document)
.on("keydown", () => {
keydown = true;
})
.on("keyup", () => {
keydown = false;
});
d3.select("#interaction").call(zoom);
// Listen to the mousewheel somewhere else
d3.select("#interaction").on("mousewheel.test", () => {
if (keydown) {
console.log(d3.event.wheelDeltaY);
}
});
svg {
background: black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<svg width="700" height="400">
<g class="view">
<rect id="interaction" x="0" y="0" width="700" height="400"></rect>
</g>
<svg>
export default class PanAndZoomTool extends Tool {
constructor(toolManager) {
// Create a zoom behavior to listen to events
const zoom = d3.behavior.zoom()
.scaleExtent([minZoom, maxZoom])
.on("zoom", () => { this.zoomed(); })
// Hook up the zoom behaviour
d3.select(INTERACTION)
.call(zoom);
}
/** Respond to the zoomed event on the interaction layer */
zoomed() {
if(!this.isActive()) return;
d3.select(VIEWPORT).attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
}
}