【问题标题】:d3js jumpy zoom behaviord3js 跳跃的缩放行为
【发布时间】:2018-01-30 04:18:05
【问题描述】:

我正在探索 d3js(第 4 版)库,并在玩弄缩放行为时遇到了以下问题。

在通过单击 svg 触发程序化缩放后使用鼠标滚轮进行缩放时,它会导致失去其位置的 laagy/jumpy 行为。

我找到了这个 Stack Overflow 资源:d3.js pan and zoom jumps when using mouse after programatic zoom 并认为这可能会帮助我。但它没有。

我已经设置了一个简单的示例,以便您了解我的意思。 我在这里想念什么?

$(document).ready(function() {
    var svg = d3.select('svg');
    var group = d3.select('g#content');
    
    svg.call(
        d3.zoom().scaleExtent([1, 30]).on('zoom', function() {
            group.attr('transform', d3.event.transform);
        })
    );
    
    svg.on('click', function() {
        group
          .transition()
          .duration(1000)
          .attr("transform", "translate(100,100) scale(2)");
    });
});
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<svg width="1200" height="500" viewBox="0 0 1200 500">
    <g id="content">
       <path d="M10,10   l50,0  0,50  -50,0  0,-50 Z" />
       <path d="M70,10   l50,0  0,50  -50,0  0,-50 Z" />
       <path d="M130,10   l50,0  0,50  -50,0  0,-50 Z" />
       <path d="M190,10   l50,0  0,50  -50,0  0,-50 Z" />
       <path d="M250,10   l50,0  0,50  -50,0  0,-50 Z" />
       <path d="M310,10   l50,0  0,50  -50,0  0,-50 Z" />
    </g>
</svg>

编辑 通过向我的事件侦听器添加以下行,放大时行为得到改善。缩小时它仍然跳跃;

var transform = d3.zoomTransform(group.node());
transform.x = m.x;
transform.y = m.y;
transform.k = scale;

完整更新的 sn-p:

$(document).ready(function() {
    var svg = d3.select('svg');
    var group = d3.select('g#content');
    
    svg.call(
        d3.zoom().scaleExtent([1, 30]).on('zoom', function() {
            group.attr('transform', d3.event.transform);
        })
    );
    
    svg.on('click', function() {
        group
          .transition()
          .duration(1000)
          .attr("transform", "translate(100,100) scale(2)");

          var transform = d3.zoomTransform(group.node());
          transform.x = 100;
          transform.y = 100;
          transform.k = 2;

    });
});
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<svg width="1200" height="500" viewBox="0 0 1200 500">
    <g id="content">
       <path d="M10,10   l50,0  0,50  -50,0  0,-50 Z" />
       <path d="M70,10   l50,0  0,50  -50,0  0,-50 Z" />
       <path d="M130,10   l50,0  0,50  -50,0  0,-50 Z" />
       <path d="M190,10   l50,0  0,50  -50,0  0,-50 Z" />
       <path d="M250,10   l50,0  0,50  -50,0  0,-50 Z" />
       <path d="M310,10   l50,0  0,50  -50,0  0,-50 Z" />
    </g>
</svg>

提前致谢!

【问题讨论】:

    标签: javascript d3.js


    【解决方案1】:

    当您以编程方式应用缩放时,您应该这样做:

      svg.on('click', function() {
        svg.transition()
          .duration(750)
          .call(zoom.transform, d3.zoomIdentity
            .translate(100, 100) // set x and y transition
            .scale(2) // set scale value
          );
      });
    

    注意,翻译必须在比例之前应用。

    另外,请注意 d3-zoom 对双击事件有默认行为(缩放)。如果您不想要它,可以使用以下代码禁用它:

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

    工作演示:

    $(document).ready(function() {
      var svg = d3.select('svg');
      var group = d3.select('g#content');
      var zoom = d3.zoom().scaleExtent([1, 30]).on('zoom', function() {
        group.attr('transform', d3.event.transform);
      });
    
      svg.call(zoom);
    
    	svg.on("dblclick.zoom", null);
      
      svg.on('click', function() {
        svg.transition()
          .duration(750)
          .call(zoom.transform, d3.zoomIdentity
            .translate(100, 100)
            .scale(2)
          );
      });
    });
    <script src="https://d3js.org/d3.v4.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <svg width="1200" height="500" viewBox="0 0 1200 500">
      <g id="content">
        <path d="M10,10   l50,0  0,50  -50,0  0,-50 Z" />
        <path d="M70,10   l50,0  0,50  -50,0  0,-50 Z" />
        <path d="M130,10   l50,0  0,50  -50,0  0,-50 Z" />
        <path d="M190,10   l50,0  0,50  -50,0  0,-50 Z" />
        <path d="M250,10   l50,0  0,50  -50,0  0,-50 Z" />
        <path d="M310,10   l50,0  0,50  -50,0  0,-50 Z" />
      </g>
    </svg>

    【讨论】:

    • 哇!很好!这似乎有效......但是,我在手册中读到.scale().translate() 的顺序很重要。 “请注意,转换的顺序很重要!必须在比例之前应用翻译。” 我可以验证该语句是否正确。我将scale().translate() 的顺序交换为translate().scale() 并且效果很好。是否愿意更新您的答案,我会将其标记为正确答案?
    【解决方案2】:

    这是因为您在初始化缩放时从 event.transform(鼠标滚轮缩放事件)设置缩放值,而在单击事件处理程序中,您正在为变换属性设置静态值。

    所以下一次,缩放事件发生,event.transform 值和你的 svg 变换值会不同。所以它会跳。

    例如:您使用鼠标滚轮进行缩放。 event.transform 将是 (500x, 500y, 5k)。 您单击鼠标并将变换属性设置为(100x,100y,2k)。 下次您执行鼠标滚轮事件时,event.transform 将从 (500x, 500y,5k) 变为 (600x, 600y, 6k)。但是由于您的 svg 变换属性是 (100x, 100y, 2k),所以它似乎跳跃了。

    【讨论】:

    • 那些投反对票的人,你能解释一下原因吗?我遇到了完全相同的问题,我很确定这就是原因
    • 只是为了记录,我没有对你投反对票。我重视您的意见,并会考虑解决它。你有没有机会为你的论文提供一个例子?
    • 可能是由于 D3 紊乱综合征。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-05
    • 2019-06-15
    • 1970-01-01
    • 2016-04-22
    相关资源
    最近更新 更多