/* prettier-ignore */ d3.select('body') .append('canvas') .attr('width', 960) .attr('height', 500); const canvas = d3.select('canvas'); const context = canvas.node().getContext('2d'); const width = canvas.property('width'); const height = canvas.property('height'); const circles = [{ x: 50, y: 60, radius: 10 }, { x: 100, y: 80, radius: 10 }]; const rects = [{ x: 10, y: 10, x2: 210, y2: 210 }]; render(); canvas.call( d3 .drag() .subject(dragSubject) .on('start', dragStarted) .on('drag', dragged) .on('end', dragEnded) .on('start.render drag.render end.render', render) ); function render() { context.clearRect(0, 0, width, height); // draw the black rectangle rects.forEach(rect => { context.fillStyle = 'black'; context.clearRect(0, 0, width, height); context.fillRect(rect.x, rect.y, rect.x2, rect.y2); // draw the red circles circles.forEach(circle => { context.beginPath(); context.moveTo(circle.x + rect.x + circle.radius, circle.y + rect.y); context.arc( circle.x + rect.x, circle.y + rect.y, circle.radius, 0, 2 * Math.PI ); context.fillStyle = 'red'; context.fill(); }); }); } function dragSubject() { let i; const n = circles.length; let dx; let dy; let d2; const radius = 10; let s2 = radius * radius * 4; // Double the radius let circle; let subject; for (i = 0; i < n; i += 1) { circle = circles[i]; console.log('circle from dragSubject', circle); dx = d3.event.x - circle.x - rects[0].x; dy = d3.event.y - circle.y - rects[0].y; d2 = dx * dx + dy * dy; console.log('dx', dx); console.log('dy', dy); console.log('d2', d2); console.log('s2', s2); if (d2 < s2) { subject = circle; s2 = d2; } else if (typeof subject === 'undefined') { rect = rects[0]; subject = rect; } } return subject; } function dragStarted() { // circles.splice(circles.indexOf(d3.event.subject), 1); // circles.push(d3.event.subject); d3.event.subject.active = true; } function dragged() { d3.event.subject.x = d3.event.x; d3.event.subject.y = d3.event.y; } function dragEnded() { d3.event.subject.active = false; } // const group = container.append('g'); // const rect = group // .append('rect') // .attr('width', w) // .attr('height', h) // .attr('x', 10) // .attr('yx', 10); // const circle1 = group // .append('circle') // .attr('cx', 50) // .attr('cy', 50) // .attr('r', 10) // .style('fill', 'red'); // const circle2 = group // .append('circle') // .attr('cx', 100) // .attr('cy', 70) // .attr('r', 10) // .style('fill', 'red'); // circle1.call(drag); // circle2.call(drag); // group.call(drag);