I want to achieve a draggable element in vanilla javascript. I want to make a small circular div draggable within a square div.
To make myself a bit more clear, I do NOT want to:
I already have a few events for handling dragging:
parent.addEventListener("mousedown", ..),
document.addEventListener("mouseup", ..)
and
document.addEventListener("mousemove", ..)
My question is how can I keep the draggable inside the given bounds of its parent?
You may use getBoundingClientRect that gives DOMRect object(an invincible rectangle that encompass the object) with eight properties: left, top, right, bottom, x, y, width, height.
var parent = document.querySelector('.parent');
var parentRect = parent.getBoundingClientRect();
var draggable = document.querySelector('.draggable');
var draggableRect = draggable.getBoundingClientRect();
You can get the mouse (X,Y) coordinates anytime by using e.clientX
and e.clientY
, so just check if they are outside the bounding rectable of .parent
div if so then only update the draggable
div's left
and top
properties
if( (e.clientX >= parentRect.left && (e.clientX+draggableRect.width <= parentRect.right)) &&
(e.clientY >= parentRect.top && (e.clientY+draggableRect.height <= parentRect.bottom))
//+draggableRect.height and +draggableRect.height accounts for the size of ball itself
){
draggable.style.left = `${e.clientX}px`;
draggable.style.top = `${e.clientY}px`;
}
Note that numbers increase down and towards right in graphics world
https://codepen.io/vsk/pen/PozVryr
UPDATE: To fix the issue mentioned in comment use this
if(/* mouse was moved withing red container's bounds*/)
else{
//if mouse went out of bounds in Horizontal direction
if(e.clientX+draggableRect.width >= parentRect.right){
draggable.style.left = `${parentRect.right-draggableRect.width}px`;
}
//if mouse went out of bounds in Vertical direction
if(e.clientY+draggableRect.height >= parentRect.bottom){
draggable.style.top = `${parentRect.bottom-draggableRect.height}px`;
}
}
And assign mousemove to document insted of the div container