【问题标题】:d3 zoom to bounding box II scrolling while zooming throws errord3 缩放到边界框 II 在缩放时滚动会引发错误
【发布时间】:2015-05-01 21:51:31
【问题描述】:

我在执行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);

【问题讨论】:

    标签: javascript d3.js zooming


    【解决方案1】:

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

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

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

    已添加 20150501 太平洋标准时间晚上 8:24

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

    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() 函数内部还有另一个转换,我们还需要在其中附加事件。

    【讨论】:

    • 这是一个指向 SO 页面的链接,如何在转换后使用回调:stackoverflow.com/questions/10692100/…
    • 这实际上更像是一个评论而不是一个答案。
    • 我正在尝试您的示例(在 plnkr 中效果很好——做得很好)。我无法在我自己的实现中恢复缩放行为。一旦缩放事件分离,它就不会恢复,即使 .each 函数附加了 _wheelZoomevent obj 引用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-27
    • 2013-02-10
    相关资源
    最近更新 更多