D3变焦事件在Angular中拖动

时间:2017-09-26 09:46:38

标签: javascript angular d3.js svg

Tldr;拖动SVG会使其旋转和翻译。

我正在尝试使用D3(v.4)作为Angular服务的一部分在SVG组上实现拖动和缩放事件。

this.unitGroup = this.svg.append('g')
  .attr('id', 'unitGroup')
  .call(this.drag)
  .call(this.zoom);

拖动可翻译SVG。

drag = d3.drag()
.on('start', () => {
  console.log('drag start');
  this.setClickOrigin(d3.event);
})
.on('drag', (d, i, n) => {
  const target = d3.select(n[i]).node() as any;
  const m = target.getCTM();
  const x = d3.event.x - this.clickOrigin.x;
  const y = d3.event.y - this.clickOrigin.y;
  this.setClickOrigin(d3.event);
  this.translate(target, x, y);
});

缩放时旋转SVG。

zoom = d3.zoom()
.on('zoom', (d, i, n) => {
  const target = d3.select(n[i]).node() as any;
  const m = target.getCTM();
  const b = target.getBBox();
  const dir = (d3.event.sourceEvent.deltaY > 0) ? 1 : -1;
  this.rotate(target, dir);
});

我的原始代码运行正常。但是,将它集成到Angular中会引发一些问题。

目前的问题是,当您拖动unitGroup时,它会触发zoom事件以及drag事件。

预期的行为是:

  • '点击并拖动'在x和y维度上翻译小的深灰色框。
  • '鼠标滚轮滚动'将小而深灰色的盒子围绕其中心旋转。

这是一个Plunker:https://embed.plnkr.co/0GrGG7T79ubpjYa2ChYp/

1 个答案:

答案 0 :(得分:3)

实际上,你在这里看到的是预期的行为。

在D3中,d3.zoom()不仅可以处理缩放,还可以处理平移。因此,鼠标移动由d3.drag()和缩放功能处理。

正如Bostock(D3创造者)曾经说过的那样:

  

结合这两种行为*意味着手势解释模糊且对位置高度敏感。 (*缩放和拖动)

最简单的解决方案就是检查缩放功能中是否有“真正的”缩放(鼠标滚轮),如果没有(没有鼠标滚轮),则返回:

if(!d3.event.sourceEvent.deltaY) return;

以下是您的改编者:https://plnkr.co/edit/jz5X4Vm9wIzbKmTQLBAT?p=preview