Tldr; dragging the SVG causes it to rotate as well as translate.
I am trying to implement dragging and zooming events on an SVG group using D3 (v.4) as part of an Angular service.
this.unitGroup = this.svg.append('g')
.attr('id', 'unitGroup')
.call(this.drag)
.call(this.zoom);
Dragging translates the 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);
});
While zooming rotates the 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);
});
My original code worked fine. However, integrating it into Angular has thrown up some problems.
The current problem is that when you drag the unitGroup
it triggers the zoom
event along with the drag
event.
The expected behaviour is that:
Here is a Plunker: https://embed.plnkr.co/0GrGG7T79ubpjYa2ChYp/
Actually, what you are seeing here is the expected behaviour.
In D3, d3.zoom()
handles not only the zoom but the panning as well. So, the mousemove is being handled by d3.drag()
and by the zoom function as well.
As Bostock (D3 creator) once said:
combining these two behaviors* means that gesture interpretation is ambiguous and highly sensitive to position. (*zoom and drag)
Off the top of my head the simplest solution is just checking if you had a "real" zoom (mouse wheel) in the zoom function and, if you didn't (no mouse wheel), return:
if(!d3.event.sourceEvent.deltaY) return;
Here is your plunker with that change only: https://plnkr.co/edit/jz5X4Vm9wIzbKmTQLBAT?p=preview
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.