如何使d3的transform:translate-drag函数更加流畅?

4
这个JSFiddle中,我已经在svg中实现了元素。我希望这些元素可以作为一个组进行拖动,我已经尝试使用d3.dragtransform:translate进行拖动。但是拖动不够平滑,会出现闪烁和跳跃的情况。
这是什么原因,如何解决?
以下是拖动函数:
var dragcontainer = d3.drag()
  .on("start", function() {})
  .on("drag", function(d, i) {
    var x = d3.event.x;
    var y = d3.event.y;
      d3.select(this.parentNode.parentNode).attr("transform", "translate(" + x + "," + y + ")");
  })
  .on("end", function() {});

3
猜测一下,d3.event.x 是相对于父元素的,通过移动父元素而不是拖动的元素,您可以改变下一个“tick”的 d3.event.x - Joseph Young
1
也许可以看一下 drag.subject - Joseph Young
1个回答

6

不要将拖动监听器附加到外部对象div上:

d3.select("#input-container-div").call(dragcontainer);

将它添加到 SVG 组中,方法如下:

d3.select(d3.select("#input-container-div").node().parentNode.parentNode).call(dragcontainer);

其次,不要使用d3.event.x / d3.event.y。
var x = d3.event.x;
var y = d3.event.y;

使用dx和dy来获取鼠标移动的差异,并将其存储为将来进行拖动操作。就像这样:
  this.x = this.x || 0;//reset if not there
  this.y = this.y || 0;

    this.x += d3.event.dx;
    this.y += d3.event.dy;
  d3.select(this).attr("transform", "translate(" + this.x + "," + this.y + ")");

这里有可用的代码,点击这里查看。


没错,它可以工作。也许如果我去掉div并用<g>替换foreignObject,它会更清晰。在SVG内使用div好还是不好? - S.Dan
1
如果您使用g而不是foreignObject,那么您就不能使用divs。我认为最好不要使用divs,而是使用SVG DOM元素,除非您有非常好的理由想要使用它。 - Cyril Cherian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接