Jump to content

Draggable Element within parent container.


Don E

Recommended Posts

Hello members,

I am trying to make a draggable div element that is similar to the jQuery draggable where you can contain the draggable element inside the parent container. I would like to implement this on one of my pages instead of using the jQuery draggable and also as a learning experience. 

The following is what I have so far. Everything works as intended but when moving the mouse too fast, it skips mouse coordinates thus not allowing the draggable box to get directly to the edges of the parent container, if that's where the user moves the box to. If move the mouse slow, it does. For example, if you move the box pretty fast to the right edge, it will stop little bit before the right edge. If you move slow, it will line up directly to the edge.

Basically works like this: When the user 'mousedown' on the draggable box, it gets the x and y coordinates, then calculate the end coordinates where the box will not move if met.

Perhaps I'm missing something or not doing something correctly. Any help is greatly appreciated! Thank you. :) 

<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Draggable</title>
	
<style>
	#parentCont{
		background-color: lightgrey;
		width: 800px;
		height: 800px;
		position: relative;
		border: 2px black solid;
	}
	
	#box{
		background-color: lightblue;
		width: 200px;
		height: 200px;
		position: absolute;
		top: 0;
		left: 0;
		cursor: move;
	}
	
</style>
	
<script>
	var startX = 0;
	var startY = 0;
	var endX = 0;
	var endY = 0;
	var endLeftMouse = 0;
	var endTopMouse = 0;
	var endRightMouse = 0;
	var endBottomMouse = 0;
	var box;
	var imageCont;

	
	window.onload = function()
	{
		
		box = document.getElementById("box");
		
		parentCont = document.getElementById('parentCont');	
		
		box.addEventListener('mousedown', function(){
			
			
			startX = event.clientX;
	  		startY = event.clientY;

			endLeftMouse = parseInt(Math.abs(box.offsetLeft - startX)); //left
			endTopMouse = parseInt(Math.abs(box.offsetTop - startY)); // top

			var rightDistBox = (parentCont.clientWidth - box.offsetLeft) - box.offsetWidth;
			var rightDistXcoor = parentCont.clientWidth - startX;
			var diffRight = Math.abs(rightDistBox - rightDistXcoor);
			endRightMouse = parseInt(parentCont.clientWidth - diffRight); //right
			
			var heightDistBox = (parentCont.clientHeight - box.offsetTop) - box.offsetHeight;
			var heightDistYcoor = parentCont.clientHeight - startY;
			var diffBott = Math.abs(heightDistBox - heightDistYcoor);
			endBottomMouse = parseInt(parentCont.clientHeight - diffBott); //bottom

			
			parentCont.addEventListener('mousemove', moveBox);
			parentCont.addEventListener("mouseup", stopMove);
			document.addEventListener("mouseup", stopMove);
		
		});
	
		
		

		
		
	}
	
	function moveBox()
	{
		
			
		if(event.clientX >= endLeftMouse && event.clientY >= endTopMouse && event.clientX <= endRightMouse && event.clientY <= endBottomMouse)
		{
			//moves box if no endMouse is met; boundary
			
			box.style.left = `${endX + (event.clientX - startX)}px`; 
			box.style.top = `${endY + (event.clientY - startY)}px`; 
				
			   
		}
		else if(event.clientX <= endLeftMouse && event.clientY >= endTopMouse  && event.clientY <= endBottomMouse){
				//if box is at left edge
				box.style.left = 0 + "px" ;
				box.style.top = endY + (event.clientY - startY)   + "px" 
		}
		else if(event.clientY <= endTopMouse && event.clientX >= endLeftMouse && event.clientX <= endRightMouse)
		{
				//if box is at top edge
				box.style.top = 0 + "px" ;
				box.style.left = endX + (event.clientX - startX)   + "px"; 
		}
		else if(event.clientX >= endRightMouse && event.clientY >= endTopMouse && event.clientY <= endBottomMouse)
		{ 
				//if box is at right edge
				 box.style.right = 0 + "px" ;
				 box.style.top = endY + (event.clientY - startY)   + "px"; 
		}
		else if(event.clientY >= endBottomMouse && event.clientX >= endLeftMouse && event.clientX <= endRightMouse) 
		{ 
				//if box is at bottom edge
				box.style.bottom = 0 + "px" ;
				box.style.left = endX + (event.clientX - startX)   + "px";  
		}
		
				
	}
		
	function stopMove()
	{
		
			
		parentCont.removeEventListener("mousemove", moveBox);
		endX = parseInt(box.offsetLeft);
		endY = parseInt(box.offsetTop);
			
			
			
	}
	
	
	
	
	

</script>
	
</head>

<body>
	
	<div id="parentCont">
		<div id="box"></div>
	</div>
	
	
	
</body>
</html>

 

Link to comment
Share on other sites

Hello JSG,

Actually it never moves outside the parent element. The issue is when moving the the draggable box really fast, say for example from left to the right edge, the draggable box is suppose to line up directly to the right edge but instead stops a certain amount or so pixels from the right edge thus not lining up directly to right edge. The same happens for the bottom as well. All works well though when moving the mouse slow.

For the left and top edges, it works fine regardless of how fast I move the mouse. With the jQuery draggable though, you can move the element as fast as you want toward the edges and it stops/lines up directly.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...