Skip to main content

Image Crop with Javascript

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 clumbsy 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 flexiable as possible for your own use.

  • Completely customizable CSS styling
  • Detects and handles multiple CSS box models
  • Allows for masking to be toggled
  • Ability to hide resize handles during drag
  • Custom events for your own modification
  • Relative based postioning rather then absolute (should handle overflow properly)
  • Works and retains layouts on floating images.
  • Resize from 8 different directions
  • Ability to set minimium size limit
  • Cleans up nicely, leaving your DOM in its original state when removed.
  • Fast!

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 detatches 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:

  • Core: Moo, Utility, Common
  • Native: Array, String, Function, Element, Event, Dom
  • Element: Element.Dimensions, Element.Events
  • Plugins: Hash

For your convenience:

Examples/Usage

Include mootools and MooCrop in your page header

 

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;
});

Contact

Nathan White: < nw at nwhite.net>

Comments

Popular posts from this blog

Financial Engineering

Financial Engineering: Key Concepts Financial engineering is a multidisciplinary field that combines financial theory, mathematics, and computer science to design and develop innovative financial products and solutions. Here's an in-depth look at the key concepts you mentioned: 1. Statistical Analysis Statistical analysis is a crucial component of financial engineering. It involves using statistical techniques to analyze and interpret financial data, such as: Hypothesis testing : to validate assumptions about financial data Regression analysis : to model relationships between variables Time series analysis : to forecast future values based on historical data Probability distributions : to model and analyze risk Statistical analysis helps financial engineers to identify trends, patterns, and correlations in financial data, which informs decision-making and risk management. 2. Machine Learning Machine learning is a subset of artificial intelligence that involves training algorithms t...

Wholesale Customer Solution with Magento Commerce

The client want to have a shop where regular customers to be able to see products with their retail price, while Wholesale partners to see the prices with ? discount. The extra condition: retail and wholesale prices hasn’t mathematical dependency. So, a product could be $100 for retail and $50 for whole sale and another one could be $60 retail and $50 wholesale. And of course retail users should not be able to see wholesale prices at all. Basically, I will explain what I did step-by-step, but in order to understand what I mean, you should be familiar with the basics of Magento. 1. Creating two magento websites, stores and views (Magento meaning of website of course) It’s done from from System->Manage Stores. The result is: Website | Store | View ———————————————— Retail->Retail->Default Wholesale->Wholesale->Default Both sites using the same category/product tree 2. Setting the price scope in System->Configuration->Catalog->Catalog->Price set drop-down to...

How to Prepare for AI Driven Career

  Introduction We are all living in our "ChatGPT moment" now. It happened when I asked ChatGPT to plan a 10-day holiday in rural India. Within seconds, I had a detailed list of activities and places to explore. The speed and usefulness of the response left me stunned, and I realized instantly that life would never be the same again. ChatGPT felt like a bombshell—years of hype about Artificial Intelligence had finally materialized into something tangible and accessible. Suddenly, AI wasn’t just theoretical; it was writing limericks, crafting decent marketing content, and even generating code. The world is still adjusting to this rapid shift. We’re in the middle of a technological revolution—one so fast and transformative that it’s hard to fully comprehend. This revolution brings both exciting opportunities and inevitable challenges. On the one hand, AI is enabling remarkable breakthroughs. It can detect anomalies in MRI scans that even seasoned doctors might miss. It can trans...