Update! New cropping tool released with more features. Checkout the preview of Lasso.Crop.
MooCrop has been updated to be compatible with Mootools 1.2. For more information visit: http://www.nwhite.net/

MooCrop

About

MooCrop is an Image Cropping utility using the amazingly powerful mootools javascript framework. Alone it serves no practical purpose but used in conjuction with a server side script becomes a powerful image manipulation tool.

Why

Looking for a mootools solution, I searched and came up with a few existing implementations. Everything I came across were only partial implementations. Those that were more polished seemed to be sluggish and effecting the DOM needlessly in some places. I wanted a class that had a very intuitive interface and played nicely with the existing DOM and more importantly I wanted it to be fast. I came to the conclusion that developing my own would give me a better understanding of mootools and broaden my understanding of drag and drop inside the DOM.

Initially I tried using the Drag.Base class found within mootools but found this to be clumsy for this highly specialized form of dragging. With default options a single drag is moving/resizing not one but 13 DOM elements. The dragging functionality has been optimized with this sole purpose in mind.

Features

MooCrop goal is to do only one thing (image crop ) but to do it well. With this in mind I tried to make the class as flexible as possible for your own use.

Documentation

Arguments

element the image element you want to attach MooCrop to.

options an object. see options below

Options

maskColor css valid color value for the mask background color. default: 'black'

maskOpacity opacity value (0-1) for the masking areas. default: '.4'

handleColor css valid color value for the handle background color. default: 'blue'

handleWidth width of handles. default: '8px'

handleHeight height of handles. default: '8px'

cropBorder css valid border value for the crop area border. default: '1px dashed blue'

min an object representing the minimum size the crop box can be. default: { 'width' : 50, 'height' : 50 }

showMask a boolean flag to show or hide the masking area. default: true

showHandles a boolean flag to show or hide handles during drag. default: false

Methods

getCropInfo returns an object with the current relative coordinates of the crop area in relation to the image top left corner. object properties ( 'width','height','top','left','right','bottom' ).

removeOverlay detaches MooCrop from image and return the image to its pre MooCrop state.

Events

onBegin fired just before dragging or resizing occurs. returns [ image src, croparea, bounds, handle ] image src is the complete path of the image being cropped. croparea see getCropInfo(). bounds is a coordinates object defining the image bounds for the crop area, useful for labels ( see example below ). handle is the name of the current drag/resize event [NW,N,NE,E,SE,S,SW,W] if drag = NESW

onCrop fired during drag. returns [ image src, croparea, bounds, handle ]

onComplete fired after the drag or resize event. returns [ image src, croparea, bounds, handle ]

onDblClk fired when the crop area is double clicked. returns [image src, croparea, bounds ]

Additional Notes

MooCrop does not rely on any css within the document its all set through object initialization. In preventing issues from arising from padding and margins the target image is hidden and a div is inject before it in the DOM tree. The image is used as a background image. The box is adjusted and the offset of the background image is based on the box model.

If IE box model is being used and a border has been defined for the crop area the border will be included in the px width and height. The traditional box model will not include the border.

When using MooCrop you must attach during or after the window load event. Using domready doesn't work because the image hasn't been rendered yet.

Requirements

MooCrop has been tested with IE 6 & 7, FF 2+, Opera 9.2 and Safari 2 & 3.

Download mootools, required dependancies:

For your convenience:

Examples/Usage

Include mootools and MooCrop in your page header

 <script type="text/javascript" src="mootools.js"></script>
 <script type="text/javascript" src="MooCrop.js"></script>

Default

 new MooCrop('crop_example1');

Changing the mask

 new MooCrop('crop_example2',{
 	'maskColor' : '#96743f',
 	'maskOpacity' : '.8'
 });

Changing the handles

 new MooCrop('crop_example3',{
 	'handleColor' : '#333333',
 	'handleWidth' : '10px',
 	'handleHeight' : '10px',
 	'showHandles' : true
 });

Adding labels with events

 var crop4 = new MooCrop('crop_example4');
 
 // create a container for a label
 // wrapper is the container that all 
 //MooCrop operations are performed
 var indicator = new Element('span',{
	'styles' : {
		'position' : 'absolute',
		'display' : 'none',
		'padding' : '4px',
		'opacity' : '.7',
		'background' : '#ffffff',
		'border' : '1px solid #525252',
		'font-size' : '11px'
	}
 }).injectInside(crop4.wrapper);
 
 // when dragging/resizing begins show indicator
 crop4.addEvent( 'onBegin' , 
 	function(imgsrc,crop,bound,handle){
		indicator.setStyle('display' , 'block');
 });

 // during the event update label
 crop4.addEvent('onCrop' , 
 	function(imgsrc,crop,bound,handle){
		indicator.setStyles({
			'top' : crop.bottom + 10,
			'left' : crop.left
		}).setText("w: "+crop.width+
			  " h: "+crop.height);
  });

 // once event is done hide label 
 crop4.addEvent('onComplete' , function(){
		indicator.setStyle('display','none');
 });

Server handling example (double click on crop area)

 var crop5 = new MooCrop('crop_example5');
 
 crop5.addEvent('onDblClk', function(img,crop,bound){
 	$('cropped').src = "crop.php?w="+crop.width+"&h="+crop.height+
 				   "&x="+crop.left+"&y="+crop.top;
 });	

Upcoming Features

This is still very much a work in progress, I have additional features I am planning on adding in the near future. If there is anything you would like to see added please contact me.

Other implementations on the internet use a moving marquee. While it has a nice visual effect I have been hesitant to go this route. It adds 4 more elements that need to be resized or moved. It requires images. I wanted customization with as little hassle as possiblee. Drop the script in and go. If enough people think this is a worth while feature I will look into including it as an option.

Contact

Nathan White: < nw at nwhite.net >