Dragging with custom events and pointer capture
Demonstration of using custom events and pointer capture to drag an element round the screen
by Richard Hunter
HTML
<div id="container">
<div id="foo" class="draggable"></div>
</div>
CSS
.draggable {
background: pink;
padding: 10px;
width: 50px;
height: 40px;
border: solid 3px black;
position: absolute;
left: 0;
top: 0;
}
#container {
position: relative;
background: green;
height: 100vh;
width: 100vw;
}
body {
margin: 0;
}
JavaScript
let pointerDown = false;
let startX;
let startY;
let fooPosition = {
left: 20,
top: 20,
};
function render() {
foo.style.transform = `translate(${fooPosition.left}px, ${fooPosition.top}px)`;
}
foo.addEventListener('pointerdown', (event) => {
event.target.setPointerCapture(event.pointerId);
pointerDown = true;
startX = event.clientX;
startY = event.clientY;
});
foo.addEventListener('pointermove', (event) => {
if (pointerDown) {
var dragEvent = new CustomEvent("drag", {
bubbles: true,
detail: {
id: 'foo',
xdiff: event.clientX - startX,
ydiff: event.clientY - startY,
hazcheeseburger: true
}
});
startX = event.clientX;
startY = event.clientY;
event.target.dispatchEvent(dragEvent);
}
});
foo.addEventListener('pointerup', (event) => {
event.target.releasePointerCapture(event.pointerId);
pointerDown = false;
});
const leftLimit = 200;
const topLimit = 200;
container.addEventListener('drag', (event) => {
fooPosition = {
...fooPosition,
left: Math.min(leftLimit, Math.max(20, fooPosition.left + event.detail.xdiff)),
top: Math.min(topLimit, Math.max(20, fooPosition.top + event.detail.ydiff)),
};
render();
});
render();