To bound the movement of nodes being dragged and dropped inside regions with KineticJS, we can use the dragBoundFunc property to define boundaries that the node cannot cross.
But in my client project I need to deal with more complex groups and multiple shapes. While using the dragBoundfuntion I realized there is bug and the main group position is not maintained properly.
So at last thought of writing my own dragbound function and the over view of this work around solution as follows.

This idea was tested and developed in .NET framework and it works perfectly. So it only a matter of implementing the solution in Java Script. In here a particular shape consist of many multiple shapes such as Circles , Lines and Polygon shapes or rectangle Shapes.
So what we have to do is extract the min and max position of the whole group shape.
//Extarct and get the small and large points coordintes from the point list
var smallPoint = { x: Math.min.apply(Math, pointListX), y: Math.min.apply(Math, pointListY) };
var largePoint = { x: Math.max.apply(Math, pointListX), y: Math.max.apply(Math, pointListY) };
From the Kinetics dragbound function get the position of the main group and update the correct min and max position of the whole shape group.
//Calculate the min and max points of the shape main group position
var minPoint = { x: mainGroup.getAbsolutePosition().x - smallPoint.x, y: mainGroup.getAbsolutePosition().y - smallPoint.y };
var maxPoint = { x: largePoint.x - mainGroup.getAbsolutePosition().x, y: largePoint.y - mainGroup.getAbsolutePosition().y };
That’s it now we have got the correct absolute position of the main group. Now it’s a matter of blocking the shape movement from the boundary.
/* Check for boundray values and
Update the Position of the shape */
var x = pos.x;
var y = pos.y;
if (x < minX) {
x = minX;
}
if (x > maxX) {
x = maxX;
}
if (y < minY) {
y = minY;
}
if (y > maxY) {
y = maxY;
}
return ({
x: x,
y: y
});
This above logic will check for the condition and will return the correct maingroup position so it will be bound inside a particular boundary.
The below is the overall solution in Java Script – Kinetics.js
/*
This function mainly deals with drag bound limitation
So basically when a polygon is moved through the canvas
it will check for min points and max points weather it
has been jumped from the border
But this funtion method has bug because of the "Kinetic.js" file
Renien (26/08/2013)
*/
function shape_BoundingBox(pos, mainGroup) {
/* Extract the point group from the main group
- Then get all the anchor points and identi
-fy the small and large coordinates in the
polygon
*/
var pointGroup = mainGroup.getChildren()[1];
var anchorPoints = pointGroup.getChildren();
//Order all the anchor point list to an array
var pointListX = [];
var pointListY = [];
anchorPoints.forEach(function (anchor) {
pointListX.push(anchor.getAbsolutePosition().x);
pointListY.push(anchor.getAbsolutePosition().y);
});
//Extarct and get the small and large points coordintes from the point list
var smallPoint = { x: Math.min.apply(Math, pointListX), y: Math.min.apply(Math, pointListY) };
var largePoint = { x: Math.max.apply(Math, pointListX), y: Math.max.apply(Math, pointListY) };
//Calculate the min and max points of the shape main group position
var minPoint = { x: mainGroup.getAbsolutePosition().x - smallPoint.x, y: mainGroup.getAbsolutePosition().y - smallPoint.y };
var maxPoint = { x: largePoint.x - mainGroup.getAbsolutePosition().x, y: largePoint.y - mainGroup.getAbsolutePosition().y };
// pre-calc some bounds so dragBoundFunc has less calc's to do
var minX = stage.getX() + (anchor_Radious * stage.getScale().x) + minPoint.x;
var minY = stage.getY() + (anchor_Radious * stage.getScale().y) + minPoint.y;
//Calclaulte the exact boundary for the polygon
var maxX = stage.getX() + stage.getWidth() - maxPoint.x - (anchor_Radious * stage.getScale().x);
var maxY = stage.getY() + stage.getHeight() - maxPoint.y - (anchor_Radious * stage.getScale().y);
/* Check for boundray values and
Update the Position of the shape */
var x = pos.x;
var y = pos.y;
if (x < minX) {
x = minX;
}
if (x > maxX) {
x = maxX;
}
if (y < minY) {
y = minY;
}
if (y > maxY) {
y = maxY;
}
return ({
x: x,
y: y
});
}