Skip to content

Instantly share code, notes, and snippets.

@thebinarypenguin
Created January 4, 2012 02:43
Show Gist options
  • Save thebinarypenguin/1558194 to your computer and use it in GitHub Desktop.
Save thebinarypenguin/1558194 to your computer and use it in GitHub Desktop.
Movable and re-sizable rectangle using Raphael SVG
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Movable and Re-sizable Raphael JS Shape</title>
</head>
<body>
<div id="paper"></div>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="http://github.com/DmitryBaranovskiy/raphael/raw/master/raphael-min.js"></script>
<script>
(function() {
var dragStart = function() {
// Save some starting values
this.ox = this.attr('x');
this.oy = this.attr('y');
this.ow = this.attr('width');
this.oh = this.attr('height');
this.dragging = true;
};
var dragMove = function(dx, dy) {
// Inspect cursor to determine which resize/move process to use
switch (this.attr('cursor')) {
case 'nw-resize' :
this.attr({
x: this.ox + dx,
y: this.oy + dy,
width: this.ow - dx,
height: this.oh - dy
});
break;
case 'ne-resize' :
this.attr({
y: this.oy + dy ,
width: this.ow + dx,
height: this.oh - dy
});
break;
case 'se-resize' :
this.attr({
width: this.ow + dx,
height: this.oh + dy
});
break;
case 'sw-resize' :
this.attr({
x: this.ox + dx,
width: this.ow - dx,
height: this.oh + dy
});
break;
default :
this.attr({
x: this.ox + dx,
y: this.oy + dy
});
break;
}
};
var dragEnd = function() {
this.dragging = false;
};
var changeCursor = function(e, mouseX, mouseY) {
// Don't change cursor during a drag operation
if (this.dragging === true) {
return;
}
// X,Y Coordinates relative to shape's orgin
var relativeX = mouseX - $('#paper').offset().left - this.attr('x');
var relativeY = mouseY - $('#paper').offset().top - this.attr('y');
var shapeWidth = this.attr('width');
var shapeHeight = this.attr('height');
var resizeBorder = 10;
// Change cursor
if (relativeX < resizeBorder && relativeY < resizeBorder) {
this.attr('cursor', 'nw-resize');
} else if (relativeX > shapeWidth-resizeBorder && relativeY < resizeBorder) {
this.attr('cursor', 'ne-resize');
} else if (relativeX > shapeWidth-resizeBorder && relativeY > shapeHeight-resizeBorder) {
this.attr('cursor', 'se-resize');
} else if (relativeX < resizeBorder && relativeY > shapeHeight-resizeBorder) {
this.attr('cursor', 'sw-resize');
} else {
this.attr('cursor', 'move');
}
};
// Create drawing area
var paper = Raphael("paper", 500, 500);
// Add a rectangle
var shapes = paper.add([{
'type' : 'rect',
'x' : 150,
'y' : 150,
'width' : 100,
'height' : 80,
'fill' : '#759dcd',
'stroke' : '#3b5068',
'stroke-width' : 10
}]);
// Attach "Mouse Over" handler to rectangle
shapes[0].mousemove(changeCursor);
// Attach "Drag" handlers to rectangle
shapes[0].drag(dragMove, dragStart, dragEnd);
})();
</script>
</body>
</html>
@surferxo3
Copy link

surferxo3 commented May 3, 2018

To prevent rectangle resize and drag out of paper border, use the following snippet below:

/**
 *  GETTER / SETTER METHOD(s)
 * */
getX(rect, ddx) {
	var width = rect.paper.width,
		thisBox = rect.getBBox();

	if (ddx < 0) {
		ddx = 0;
	} else if (ddx > width - thisBox.width) {
		ddx = width - thisBox.width;
	}

	return ddx;
}

getY(rect, ddy) {
	var height = rect.paper.height,
		thisBox = rect.getBBox();

	if (ddy < 0) {
		ddy = 0;
	} else if (ddy > height - thisBox.height) {
		ddy = height - thisBox.height;
	}

	return ddy;
}

getWidth(rect, ddw) {
	var width = rect.paper.width,
		thisBox = rect.getBBox();

	if (ddw < 45) {
		ddw = 45;
	} else if (ddw > width - thisBox.x) {
		ddw = width - thisBox.x;
	}

	return ddw;
}

getHeight(rect, ddh) {
	var height = rect.paper.height,
		thisBox = rect.getBBox();

	if (ddh < 45) {
		ddh = 45;
	} else if (ddh > height - thisBox.y) {
		ddh = height - thisBox.y;
	}

	return ddh;
}

/**
 * RAPHAEL EVENT(s)
 * */
dragStart() {
	this.ox = this.attr('x');
	this.oy = this.attr('y');
	this.ow = this.attr('width');
	this.oh = this.attr('height');
	this.dragging = true;
}

dragMove(dx, dy) {
	var ddx = this.ox + dx;
	var ddy = this.oy + dy;

	switch (this.attr('cursor')) {
		case 'nw-resize':
			this.attr({
				x: getX(this, ddx),
				y: getY(this, ddy),
				width: getWidth(this, this.ow - dx),
				height: getHeight(this, this.oh - dy)
			});
			break;
		case 'ne-resize':
			this.attr({
				y: getY(this, ddy),
				width: getWidth(this, this.ow + dx),
				height: getHeight(this, this.oh - dy)
			});
			break;
		case 'se-resize':
			this.attr({
				width: getWidth(this, this.ow + dx),
				height: getHeight(this, this.oh + dy)
			});
			break;
		case 'sw-resize':
			this.attr({
				x: getX(this, ddx),
				width: getWidth(this, this.ow - dx),
				height: getHeight(this, this.oh + dy)
			});
			break;
		case 'w-resize':
			this.attr({
				x: getX(this, ddx, this.ow - dx),
				width: getWidth(this, this.ow - dx)
			});
			break;
		case 'e-resize':
			this.attr({
				width: getWidth(this, this.ow + dx)
			});
			break;
		case 's-resize':
			this.attr({
				height: getHeight(this, this.oh + dy)
			});
			break;
		case 'n-resize':
			this.attr({
				y: getY(this, ddy),
				height: getHeight(this, this.oh - dy)
			});
			break;
		default:
			this.attr({
				x: getX(this, ddx),
				y: getY(this, ddy)
			});
			break;
	}
}

dragEnd(e) {
	this.dragging = false;
}

changeCursor(e, mouseX, mouseY) {
	if (this.dragging === true) {
		return;
	}

	var relativeX = mouseX - ($('#paper').offset().left) - this.attr('x');
	var relativeY = mouseY - ($('#paper').offset().top) - this.attr('y');
	var shapeWidth = this.attr('width');
	var shapeHeight = this.attr('height');
	var resizeBorder = 10;

	if (relativeX < resizeBorder && relativeY < resizeBorder) {
		this.attr('cursor', 'nw-resize');
	} else if (relativeX > shapeWidth - resizeBorder && relativeY < resizeBorder) {
		this.attr('cursor', 'ne-resize');
	} else if (relativeX > shapeWidth - resizeBorder && relativeY > shapeHeight - resizeBorder) {
		this.attr('cursor', 'se-resize');
	} else if (relativeX < resizeBorder && relativeY > shapeHeight - resizeBorder) {
		this.attr('cursor', 'sw-resize');
	} else if (relativeX < resizeBorder && relativeY < shapeHeight - resizeBorder) {
		this.attr('cursor', 'w-resize');
	} else if (relativeX > shapeWidth - resizeBorder && relativeY < shapeHeight - resizeBorder) {
		this.attr('cursor', 'e-resize');
	} else if (relativeX > resizeBorder && relativeY > shapeHeight - resizeBorder) {
		this.attr('cursor', 's-resize');
	} else if (relativeX > resizeBorder && relativeY < resizeBorder) {
		this.attr('cursor', 'n-resize');
	} else {
		this.attr('cursor', 'move');
	}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment