docs: function addRectHandle($canvas, parent, px, py) {
  	var handle, cursor;
  
  	// Determine cursor to use depending on handle's placement
  	if ((px === -1 && py === -1) || (px === 1 && py === 1)) {
  		cursor = 'nwse-resize';
  	} else if (px === 0 && (py === -1 || py === 1)) {
  		cursor = 'ns-resize';
  	} else if ((px === -1 || px === 1) && py === 0) {
  		cursor = 'ew-resize';
  	} else if ((px === 1 && py === -1) || (px === -1 && py === 1)) {
  		cursor = 'nesw-resize';
  	}
  
  	handle = $.extend({
  		// Set cursors for handle
  		cursors: {
  			mouseover: cursor
  		}
  	}, parent.handle, {
  		// Define constant properties for handle
  		layer: true,
  		draggable: true,
  		x: parent.x + ((px * parent.width / 2) + ((parent.fromCenter) ? 0 : parent.width / 2)),
  		y: parent.y + ((py * parent.height / 2) + ((parent.fromCenter) ? 0 : parent.height / 2)),
  		_parent: parent,
  		_px: px,
  		_py: py,
  		fromCenter: true,
  		dragstart: function (layer) {
  			$(this).triggerLayerEvent(layer._parent, 'handlestart');
  		},
  		// Resize rectangle when dragging a handle
  		drag: function (layer) {
  			var parent = layer._parent;
  
  			if (parent.width + (layer.dx * layer._px) < parent.minWidth) {
  				parent.width = parent.minWidth;
  				layer.dx = 0;
  			}
  			if (parent.height + (layer.dy * layer._py) < parent.minHeight) {
  				parent.height = parent.minHeight;
  				layer.dy = 0;
  			}
  
  			if (!parent.resizeFromCenter) {
  				// Optionally constrain proportions
  				if (parent.constrainProportions) {
  					if (layer._py === 0) {
  						// Manage handles whose y is at layer's center
  						parent.height = parent.width / parent.aspectRatio;
  					} else {
  						// Manage every other handle
  						parent.width = parent.height * parent.aspectRatio;
  						layer.dx = layer.dy * parent.aspectRatio * layer._py * layer._px;
  					}
  				}
  				// Optionally resize rectangle from corner
  				if (parent.fromCenter) {
  					parent.width += layer.dx * layer._px;
  					parent.height += layer.dy * layer._py;
  				} else {
  					// This is simplified version based on math. Also you can write this using an if statement for each handle
  					parent.width += layer.dx * layer._px;
  					if (layer._px !== 0) {
  						parent.x += layer.dx * ((1 - layer._px) && (1 - layer._px) / Math.abs((1 - layer._px)));
  					}
  					parent.height += layer.dy * layer._py;
  					if (layer._py !== 0) {
  						parent.y += layer.dy * ((1 - layer._py) && (1 - layer._py) / Math.abs((1 - layer._py)));
  					}
  				}
  				// Ensure diagonal handle does not move
  				if (parent.fromCenter) {
  					if (layer._px !== 0) {
  						parent.x += layer.dx / 2;
  					}
  					if (layer._py !== 0) {
  						parent.y += layer.dy / 2;
  					}
  				}
  			} else {
  				// Otherwise, resize rectangle from center
  				parent.width += layer.dx * layer._px * 2;
  				parent.height += layer.dy * layer._py * 2;
  				// Optionally constrain proportions
  				if (parent.constrainProportions) {
  					if (layer._py === 0) {
  						// Manage handles whose y is at layer's center
  						parent.height = parent.width / parent.aspectRatio;
  					} else {
  						// Manage every other handle
  						parent.width = parent.height * parent.aspectRatio;
  					}
  				}
  			}
  			updateRectHandles(parent);
  			$(this).triggerLayerEvent(parent, 'handlemove');
  		},
  		dragstop: function (layer) {
  			var parent = layer._parent;
  			$(this).triggerLayerEvent(parent, 'handlestop');
  		},
  		dragcancel: function (layer) {
  			var parent = layer._parent;
  			$(this).triggerLayerEvent(parent, 'handlecancel');
  		}
  	});
  	$canvas.draw(handle);
  	// Add handle to parent layer's list of handles
  	parent._handles.push($canvas.getLayer(-1));
  }