<div class="container">
<div style="top: 100px; left: 100px" class="box" draggable="false"></div>
<div style="top: 200px; left: 200px" class="box" draggable="false"></div>
<div style="top: 300px; left: 300px" class="box" draggable="false"></div>
<div style="top: 400px; left: 400px" class="box" draggable="false"></div>
</div>
.container {
width: 600px;
height: 600px;
background-color: darkgrey;
touch-action: none;
}
.box {
position: absolute;
width: 100px;
height: 100px;
background-color: black;
}
const container = document.querySelector('.container');
container.addEventListener('pointerdown', userPressed, { passive: true });
var element, bbox, inputX, inputY, boxCenterX, boxCenterY, raf;
function userPressed(event) {
element = event.target;
if (element.classList.contains('box')) {
inputX = event.clientX;
inputY = event.clientY;
bbox = element.getBoundingClientRect();
boxCenterX = bbox.left + bbox.width/2;
boxCenterY = bbox.top + bbox.height/2;
container.addEventListener('pointermove', userMoved, { passive: true });
container.addEventListener('pointerup', userReleased, { passive: true });
container.addEventListener('pointercancel', userReleased, { passive: true });
raf = requestAnimationFrame(userMovedRaf);
};
};
function userMoved(event) {
inputX = event.clientX;
inputY = event.clientY;
};
function userMovedRaf() {
let x = lerp(boxCenterX, inputX, 0.05);
let y = lerp(boxCenterY, inputY, 0.05);
element.style.left = x - bbox.width/2 + "px";
element.style.top = y - bbox.width/2 + "px";
boxCenterX = x;
boxCenterY = y;
raf = requestAnimationFrame(userMovedRaf)
};
function userReleased(event) {
container.removeEventListener('pointermove', userMoved);
container.removeEventListener('pointerup', userReleased);
container.removeEventListener('pointercancel', userReleased);
if (raf) {
cancelAnimationFrame(raf);
raf = null;
};
};
function lerp (start, end, amt) {
return (1-amt)*start+amt*end
};
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.