Common solution for setting dragbound for the objects and avoid overlapping of the Objects Using Kinetic JS

Click here for Live Demo
Click here to download

Setting drag bounds for the elements has become a very common feature now a days.
By using kinetic JS it is very easy to implement. The most common problem which
I faced in setting dragbounds to the objects or elements is after dragging the
object to the drag bound and release the mouse outside the dragbound and then
move the mouse pointer to the drag area, you can see that object moves along
with the mouse pointer. Also overlapping of objects is the most frequent issue
I have faced.In this post we are going to derive a common logic for both the problems
using Kinetic JS. Lets write up our code first by setting dragbound to the objects.

<!DOCTYPE HTML>
<html>
  <head>
    <style>
      body {
        margin: 0px;
        padding: 0px;
      }
	  #container{
			border: 2px solid red;
			height: 400px;
			margin-left: 353px;
			margin-top: 134px;
			width: 750px;
	  }
    </style>
    <body>
      <div id="container"></div>
      <script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.5.4.min.js"></script>
	   <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
	   
      <script defer="defer">
	  parent.$(document).mouseup(function(event){
		$(document).trigger('drend');
		});

		$(document).bind('drend',function(event){
		onDocumentMouseUp(event);
		});
		function onDocumentMouseUp(event){
			event.preventDefault();
		}

        var stage = new Kinetic.Stage({
          container: 'container',
          width: 750,
          height: 400
        });
        var layer = new Kinetic.Layer();

        var firstGroup = new Kinetic.Group({
          x: 100,
          y: 0,
		  draggable: true,
          dragBoundFunc: function(pos) {
			if(pos.y < 0)
			{
				var newY = 0;
			}
			else if(pos.y > 353)
			{
				var newY = 353;
			}
			else
			{
				var newY = pos.y;
			}
			
			if(pos.x < 0)
			{
				var newX = 0;
			}
			else if(pos.x > 558)
			{
				var newX = 558;
			}
			else
			{
				var newX = pos.x;
			}
			
            return {
              x: newX,
              y: newY
            };
          }
        });

		
		function checkCollide(pointX, pointY, objectx, objecty, objectw, objecth) { // pointX, pointY belong to one rectangle, while the object variables belong to another rectangle
		var oTop = objecty;
		var oLeft = objectx; 
		var oRight = objectx+objectw;
		var oBottom = objecty+objecth; 
		if(pointX >= oLeft && pointX < oRight || pointX < oLeft && (pointX+objectw > oLeft && pointX+objectw < oRight)){
			if(pointY >= oTop && pointY < oBottom || pointY < oTop && (pointY+objecth > oTop && pointY+objecth < oBottom)){		
			 console.log("collideddddd");
				return 1;
			}
		}
		else{
			return 0;
		}
	 };
		
        var secondGroup = new Kinetic.Group({
          x: stage.getWidth() / 2,
          y: 70,
          draggable: true,
          dragBoundFunc: function(pos) {
			if(pos.y < 0)
			{
				var newY = 0;
			}
			else if(pos.y > 353)
			{
				var newY = 353;
			}
			else
			{
				var newY = pos.y;
			}
			
			if(pos.x < 0)
			{
				var newX = 0;
			}
			else if(pos.x > 558)
			{
				var newX = 558;
			}
			else
			{
				var newX = pos.x;
			}
			
            return {
              x: newX,
              y: newY
            };
           }
        });
		
		
        var firstText = new Kinetic.Text({
          fontSize: 26,
          fontFamily: 'Calibri',
          text: 'I will catch You..',
          fill: 'black',
          padding: 10
        });

        var firstRect = new Kinetic.Rect({
          width: firstText.getWidth(),
          height: firstText.getHeight(),
          fill: 'green',
          stroke: 'black',
          strokeWidth: 4
        });

        var secondText = new Kinetic.Text({
          fontSize: 26,
          fontFamily: 'Calibri',
          text: 'Catch me ifucan',
		  fill: 'black',
          padding: 10
        });

        var secondRect = new Kinetic.Rect({
          width: secondText.getWidth(),
          height: secondText.getHeight(),
          fill: 'yellow',
          stroke: 'black',
          strokeWidth: 4
        });
		
        firstGroup.add(firstRect).add(firstText);
        secondGroup.add(secondRect).add(secondText);

        layer.add(firstGroup);
        layer.add(secondGroup);
        stage.add(layer);

      </script>
  </head>
  </body>
</html>

In the above code you can see this piece of code.

parent.$(document).mouseup(function(event){
$(document).trigger('drend');
});

This handles the mouse up event when clicked outside the stage area.

Try executing this code, you can see that the drag bounds seems to work fine but you
can also see that the object seems to over lap . Now lets try to avoid the overlapping
of the objects. So to know the overlapping we have to detect the collision of objects.
To know the collision we need to know the position of both the objects and the height
and width of the objects.Lets write a small kinetic js piece of code for this

function checkCollide(pointX, pointY, objectx, objecty, objectw, objecth) { // pointX, pointY belong to one rectangle, while the object variables belong to another rectangle
		var oTop = objecty;
		var oLeft = objectx; 
		var oRight = objectx+objectw;
		var oBottom = objecty+objecth; 
		if(pointX >= oLeft && pointX < oRight || pointX < oLeft && (pointX+objectw > oLeft && pointX+objectw < oRight)){
			if(pointY >= oTop && pointY < oBottom || pointY < oTop && (pointY+objecth > oTop && pointY+objecth < oBottom)){		
			 console.log("collideddddd");
				return 1;
			}
		}
		else{
			return 0;
		}
	 };

call this function on drag move

firstGroup.on("dragmove", function(evt) {
						if(checkCollide(firstGroup.getX() +1, firstGroup.getY() - 1,secondGroup.getX(),secondGroup.getY(),secondText.getWidth(),secondText.getHeight()))
						{
//implement your code here
}

By implementing the above piece of code using kinetic js we get the common solution for
Setting dragbounds for the objects and also avoid overlapping of the objects.
Hope this is helpful 🙂

About This Author

Venkatesh has 2 years experience in the field of web Designing. He holds bachelor degree in Computer Science Engineering from JNT University ,Hyderabad. Venkatesh is well versed with HTML5, CSS3 and JQUERY. He has also worked on KINETIC JS and EXT JS. As a UX developer, Venkatesh has tried to bring about effective teaching and learning in the courses he designed.

  • nikhilrao

    I was looking for overlapping issue and finally got one….
    Thanks dude… its really helpful….

  • Pingback: hermes カタログ()