d3 zoom to bounding box II 缩放时滚动会抛出错误

d3 zoom to bounding box II scrolling while zooming throws error

我在执行 Mike Bostock's zoom to bounding box II.

时出错

如果您在缩放事件期间滚动,错误会中途停止缩放并锁定地图。

关于修复有什么想法吗?该错误出现在 Bostock 的示例中。

错误截图如下:

代码:

var width = 500,
    height = 370,
    active = d3.select(null);

var projection = d3.geo.albersUsa()
    .scale(675)
    .translate([width / 2, height / 2]);

var path = d3.geo.path()
    .projection(projection);

var svg = d3.select(".app-map")
    .append("svg")
      .attr("width", width)
      .attr("height", height);

var g = svg.append("g")
      .attr("class", "app-counties-map");

function ready(error, us) {

  g.selectAll("path")
    .data(topojson.feature(us, us.objects.counties).features)
  .enter().append("path")
    .attr("class", "app-counties")
    .attr("d", path)
    .on("click",clicked);

  function clicked(d) {
    if (active.node() === this) return reset();
    active.classed("active", false);
    active = d3.select(this).classed("active", true);

    var bounds = path.bounds(d),
      dx = bounds[1][0] - bounds[0][0],
      dy = bounds[1][3] - bounds[0][4],
      x = (bounds[0][0] + bounds[1][0]) / 2,
      y = (bounds[0][5] + bounds[1][6]) / 2,
      scale = 3.5,
      translate = [width / 2 - scale * x, height / 2 - scale * y];

    svg.transition()
      .duration(450)
      .call(zoom.translate(translate).scale(scale).event);
  };

  function reset() {
    active.classed("active", false);
    active = d3.select(null);

    svg.transition()
      .duration(450)
      .call(zoom.translate([0, 0]).scale(1).event);
  };

  var zoom = d3.behavior.zoom()
    .translate([0, 0])
    .scale(1)
    .scaleExtent([1, 8])
    .on("zoom", zoomed);

  svg.on("click", stopped, true);

  svg
    .call(zoom)
    .call(zoom.event);

  function zoomed() {
    g.style("stroke-width", 1.5 / d3.event.scale + "px");
    g.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
  }

  function stopped() {
    if (d3.event.defaultPrevented) d3.event.stopPropagation();
  }

}


queue()
    .defer(d3.json, "./data/us (2).json")
    .await(ready);

我认为问题的发生是因为鼠标滚轮事件试图缩放,而来自点击事件的缩放过渡动画仍在播放(我在 chrome 中没有得到错误,但在 IE 中) .

您可以在单击事件开始时关闭鼠标滚轮事件,并在 animation/transition 完成后重新启用它。

为了等待转换完成,我使用了.each,但也许也可以使用.call。

已添加 20150501 8:24PM PST

我现在下班了,所以我可以更详细地解释一下。

jsfiddle example

1。禁用鼠标滚动缩放事件

var _wheelZoomEvent = svg.on("wheel.zoom");
function clicked(d) {

        svg.on("wheel.zoom", null);

在执行点击过渡时,我们希望防止鼠标滚轮事件触发另一个缩放过渡。 svg.on("wheel.zoom") 正在返回对事件处理程序的引用,以便我可以在转换完成时重新附加。 svg.on("wheel.zoom", null) 从鼠标滚轮事件中分离事件处理程序。

2。在转换结束时添加回调

转换完成后,我们需要将鼠标滚轮事件重新附加回 svg 对象。

svg.transition()
            .duration(750)
            .call(zoom.translate([0, 0]).scale(1).event)
            .each("end", function(){ 
                  svg.on("wheel.zoom", _wheelZoomEvent);
            });

reset() 函数中还有另一个转换,我们也需要将事件附加到那里。