dragging SVG elements
by Richard Hunter
HTML
<svg id="svg" width="500" height="500">
<rect x="50" y="50" width="100" height="100" fill="red" stroke-width="20" stroke="black" />
<g id="group" transform="translate(0, 0)">
<rect x="0" y="0" width="100" height="100" fill="red" />
<text x="0" y="0">hello rich</text>
<rect id="foo" x="0" y="0" width="100" height="100" opacity="0" fill="blue" />
</g>
</svg>
CSS
.foo {
border: dashed 10px blue;
background: pink;
}
JavaScript
const foo = document.getElementById('foo');
function makeDraggable(svgEl) {
let startX;
let startY;
let pointerDown = false;
svgEl.addEventListener('pointerdown', (event) => {
event.stopPropagation();
startX = event.clientX;
startY = event.clientY;
pointerDown = true;
svgEl.setPointerCapture(event.pointerId);
});
svgEl.addEventListener('pointermove', (event) => {
event.stopPropagation();
if (pointerDown) {
var dragEvent = new CustomEvent("drag", {
bubbles: true,
detail: {
id: 'foo',
xdiff: event.clientX - startX,
ydiff: event.clientY - startY,
}
});
startX = event.clientX;
startY = event.clientY;
event.target.dispatchEvent(dragEvent);
}
});
svgEl.addEventListener('pointerup', (event) => {
event.stopPropagation();
pointerDown = false;
svgEl.releasePointerCapture(event.pointerId);
});
}
makeDraggable(foo);
let svgEl = document.getElementById('svg');
let groupEl = document.getElementById('group');
let groupX = 0;
let groupY = 0;
svgEl.addEventListener('drag', (event) => {
groupX = event.detail.xdiff + groupX;
groupY = event.detail.ydiff + groupY;
group.setAttributeNS(null, 'transform', `translate(${groupX}, ${groupY})`);
});