防止d3.behaviour.zoom跳跃

时间:2017-05-15 20:08:47

标签: javascript d3.js svg

我有一个小应用程序,其中包含不同的tools。其中两个工具使用鼠标滚轮,但以不同的方式,我发现他们目前正在互相错误地互动。我想知道是否有办法阻止这种情况。

我将提供一个简化的noddy示例来演示这种影响。如果您运行代码段(在启动前单击SVG背景/圆圈),您应该可以使用鼠标滚轮进行缩放。

但是,如果您按住某个键(以模拟使用其他工具),则会记录鼠标滚轮增量而不是缩放。如果您在没有按下按键的情况下尝试变焦,则变焦会根据按下按键时的鼠标滚轮变化而跳跃。

我已经包含了一个动画gif来演示,当我试图在压制它一段时间后使用d3.behaviour.zoom时,缩放是如何大幅跳跃的。所以我的问题是,有没有办法可以改变d3.behaviour.zoom所以它只是在上一次操作后的delta上表现,或者有没有办法暂停它的刻度以防止这种跳跃?

enter image description here

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 + ")");
    }
}

0 个答案:

没有答案