drag = (circles, canvas) => {
function dragsubject() {
const transform = d3.zoomTransform(canvas);
let subject = null;
let distance = maxDistance;
const x = transform.invertX(d3.event.x);
const y = transform.invertY(d3.event.y);
for (const c of circles) {
let d = Math.hypot(x - c.x, y - c.y);
if (d < distance) {
distance = d;
subject = c;
}
}
return subject
? {
circle: subject,
x: transform.applyX(subject.x),
y: transform.applyY(subject.y)
}
: null;
}
function dragstarted() {
circles.splice(circles.indexOf(d3.event.subject.circle), 1);
circles.push(d3.event.subject.circle);
d3.event.subject.active = true;
}
function dragged() {
const transform = d3.zoomTransform(canvas);
d3.event.subject.circle.x = transform.invertX(d3.event.x);
d3.event.subject.circle.y = transform.invertY(d3.event.y);
}
function dragended() {
d3.event.subject.active = false;
}
return d3
.drag()
.subject(dragsubject)
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended);
}