cropit

a "customizable crop and zoom" jQuery plugin
Select new image
Download cropped image

What it is

  • A jQuery plugin for image cropping and zooming.
  • Loads images locally via FileReader, and crops them using canvas.
  • Designed to be extremely customizable via CSS.
  • Best for the cases where you want users to upload images of a specific size and aspect ratio.

Features

  • Works on desktop and mobile with touch support (except IE 9 and below).
  • Drag'n'drop image into cropper.
  • Extremely performant even with huge images.
  • Extensive options and APIs to give you full control.

Getting started

Install with Bower:

$ bower install cropit

Or with npm:

$ npm install cropit

Demos

Basic image cropper

Download cropped image
<!-- This wraps the whole cropper -->
<div id="image-cropper">
  <!-- This is where the preview image is displayed -->
  <div class="cropit-preview"></div>
  
  <!-- This range input controls zoom -->
  <!-- You can add additional elements here, e.g. the image icons -->
  <input type="range" class="cropit-image-zoom-input" />
  
  <!-- This is where user selects new image -->
  <input type="file" class="cropit-image-input" />
  
  <!-- The cropit- classes above are needed
       so cropit can identify these elements -->
</div>
$('#image-cropper').cropit();

// In the demos I'm passing in an imageState option
// so it renders an image by default:
// $('#image-cropper').cropit({ imageState: { src: { imageSrc } } });

// Exporting cropped image
$('.download-btn').click(function() {
  var imageData = $('#image-cropper').cropit('export');
  window.open(imageData);
});
.cropit-preview {
  /* You can specify preview size in CSS */
  width: 960px;
  height: 540px;
}

Custom select image button and zoom slider

Select new image
Download cropped image
<div id="image-cropper">
  <div class="cropit-preview"></div>
  
  <input type="range" class="cropit-image-zoom-input" />
  
  <!-- The actual file input will be hidden -->
  <input type="file" class="cropit-image-input" />
  <!-- And clicking on this button will open up select file dialog -->
  <div class="select-image-btn">Select new image</div>
</div>
$('#image-cropper').cropit();

// When user clicks select image button,
// open select file dialog programmatically
$('.select-image-btn').click(function() {
  $('.cropit-image-input').click();
});

// Handle rotation
$('.rotate-cw-btn').click(function() {
  $('#image-cropper').cropit('rotateCW');
});
$('.rotate-ccw-btn').click(function() {
  $('#image-cropper').cropit('rotateCCW');
});
/* Hide file input */
input.cropit-image-input {
  visibility: hidden;
}

/*
 * See http://www.htmllion.com/html5-range-input-with-css.html
 * for styling range input
 */
 

Image cropper with background

Select new image
Download cropped image
<div id="image-cropper">
  <div class="cropit-preview"></div>
  
  <input type="range" class="cropit-image-zoom-input" />
  
  <input type="file" class="cropit-image-input" />
  <div class="select-image-btn">Select new image</div>
</div>
$('#image-cropper').cropit({ imageBackground: true });
/* Translucent background image */
.cropit-preview-background {
  opacity: .2;
}

/*
 * If the slider or anything else is covered by the background image,
 * use relative or absolute position on it
 */
input.cropit-image-zoom-input {
  position: relative;
}

/* Limit the background image by adding overflow: hidden */
#image-cropper {
  overflow: hidden;
}

Image cropper with thin background border

Select new image
Download cropped image
<div id="image-cropper">
  <div class="cropit-preview"></div>
  
  <input type="range" class="cropit-image-zoom-input" />
  
  <input type="file" class="cropit-image-input" />
  <div class="select-image-btn">Select new image</div>
</div>
$('#image-cropper').cropit({
  imageBackground: true,
  imageBackgroundBorderWidth: 15 // Width of background border
});

Documentation

Initialization options

$imageCropper.cropit(options);
$preview
jQuery element

The HTML element that displays image preview.

$imageCropper.find('.cropit-preview')
$fileInput
jQuery element

File input element.

$imageCropper.find('input.cropit-image-input')
$zoomSlider
jQuery element

Range input element that controls image zoom.

$imageCropper.find('input.cropit-image-zoom-input')
width
number

Width of image preview in pixels. If set, it will override the CSS property.

null
height
number

Height of image preview in pixels. If set, it will override the CSS property.

null
imageBackground
boolean

Whether or not to display the background image beyond the preview area.

false
imageBackgroundBorderWidth
array or number

Width of background image border in pixels. The four array elements specify the width of background image width on the top, right, bottom, left side respectively. The background image beyond the width will be hidden. If specified as a number, border with uniform width on all sides will be applied.

[0,0,0,0]
exportZoom
number

The ratio between the desired image size to export and the preview size. For example, if the preview size is 300px * 200px, and exportZoom = 2, then the exported image size will be 600px * 400px. This also affects the maximum zoom level, since the exported image cannot be zoomed to larger than its original size.

1
allowDragNDrop
boolean

When set to true, you can load an image by dragging it from local file browser onto the preview area.

true
minZoom
string

This options decides the minimal zoom level of the image. If set to 'fill', the image has to fill the preview area, i.e. both width and height must not go smaller than the preview area. If set to 'fit', the image can shrink further to fit the preview area, i.e. at least one of its edges must not go smaller than the preview area.

'fill'
maxZoom
number

Determines how big the image can be zoomed. E.g. if set to 1.5, the image can be zoomed to 150% of its original size.

1
initialZoom
string

Determines the zoom when an image is loaded. When set to 'min', image is zoomed to the smallest when loaded. When set to 'image', image is zoomed to 100% when loaded.

'min'
freeMove
boolean

When set to true, you can freely move the image instead of being bound to the container borders

false
smallImage
string

When set to 'reject', onImageError would be called when cropit loads an image that is smaller than the container. When set to 'allow', images smaller than the container can be zoomed down to its original size, overiding minZoom option. When set to 'stretch', the minimum zoom of small images would follow minZoom option.

'reject'
onFileChange
function

Called when user selects a file in the select file input.

{object} event - File change event object

onFileReaderError
function

Called when FileReader encounters an error while loading the image file.

onImageLoading
function

Called when image starts to be loaded.

onImageLoaded
function

Called when image is loaded.

onImageError
function

Called when image cannot be loaded.

{object} error - Error object.

{number} error.code - Error code. 0 means generic image loading failure. 1 means image is too small.

{string} error.message - A message explaining the error.

onZoomEnabled
function

Called when image the zoom slider is enabled.

onZoomDisabled
function

Called when image the zoom slider is disabled.

onZoomChange
function

Called when zoom changes.

{number} zoom - New zoom.

onOffsetChange
function

Called when image offset changes.

{object} offset - New offset, with x and y values.

APIs

// Returns the cropped image in Data URI format.
// The second argument `options` takes the following keys:
// - [type='image/png'] exported image type.
// - [quality=.75] exported image quality, only works when type is
//     'image/jpeg' or 'image/webp'.
// - [originalSize=false] when set to true, export cropped part in
//     original size, overriding exportZoom.
// - [fillBg='#fff'] if `type` is 'image/jpeg', this color will be
//     filled as the background of the exported image.
$imageCropper.cropit('export', {
  type: 'image/jpeg',
  quality: .9,
  originalSize: true
});

// Rotates the image by 90 degrees in clockwise/counterclockwise.
// If, after rotated by 90 degrees, the image dimensions no longer meets
// the requirement, it would be rotated by 180 degrees instead.
$imageCropper.cropit('rotateCW');
$imageCropper.cropit('rotateCCW');

// Returns whether the current image is big enough to be zoomable.
// Note that an image cannot be zoomed to larger than its original size.
$imageCropper.cropit('isZoomable');

// Returns the source of current image.
// If the image is loaded through the file input, the image source will be
// in Data URI format.
$imageCropper.cropit('imageSrc');

// Sets image source.
$imageCropper.cropit('imageSrc', 'http://placekitten.com/g/1280/800');

// Returns the current image size.
// E.g. { width: 1920, height: 1080 }
$imageCropper.cropit('imageSize');

// Returns the current preview area size.
// E.g. { width: 600, height: 400 }
$imageCropper.cropit('previewSize');

// Sets preview area size.
$imageCropper.cropit('previewSize', { width: 800, height: 450 });

// Returns the image offset of the current cropping, with respect to the
// preview area.
// E.g. { x: -10, y: -15 }
$imageCropper.cropit('offset');

// Sets image offset.
$imageCropper.cropit('offset', { x: -18, y: -54 });

// Returns the current zoom.
$imageCropper.cropit('zoom');

// Sets image zoom.
$imageCropper.cropit('zoom', .75);

// Returns current initialZoom value.
$imageCropper.cropit('initialZoom');

// Sets initialZoom value.
$imageCropper.cropit('initialZoom', 'image');

// Returns current exportZoom value.
$imageCropper.cropit('exportZoom');

// Sets exportZoom value.
$imageCropper.cropit('exportZoom', 2);

// Returns current minZoom value.
$imageCropper.cropit('minZoom');

// Sets minZoom value.
$imageCropper.cropit('minZoom', 'fit');

// Returns current maxZoom value.
$imageCropper.cropit('maxZoom');

// Sets maxZoom value.
$imageCropper.cropit('maxZoom', 1.25);

// Disables the cropper.
// Unbinds event listeners from preview, zoom slider and file input, and
// adds `cropit-disabled` class to `$imageCropper`.
$imageCropper.cropit('disable');

// Re-enables the cropper.
// Does the opposite to `disable` method.
$imageCropper.cropit('reenable');

Styling with CSS

<!-- Preview is relative positioned -->
<!-- Add a wrapper if you need to absolute position it -->
<div class="cropit-preview">
  <!-- Background image container is absolute positioned -->
  <div class="cropit-preview-background-container">
    <img class="cropit-preview-background" />
  </div>
  <!-- Image container is also absolute positioned -->
  <div class="cropit-preview-image-container">
    <img class="cropit-preview-image" />
  </div>
</div>

<!-- Zoom slider -->
<input type="range" class="cropit-image-zoom-input" />

<!-- File selector ->
<!-- cropit will add accept="image/*" attribute to it -->
<input type="file" class="cropit-image-input" />
/* Show load indicator when image is being loaded */
.cropit-preview.cropit-image-loading .spinner {
  opacity: 1;
}

/* Show move cursor when image has been loaded */
.cropit-preview.cropit-image-loaded .cropit-preview-image-container {
  cursor: move;
}

/* Gray out zoom slider when the image cannot be zoomed */
.cropit-image-zoom-input[disabled] {
  opacity: .2;
}

/* Hide default file input button if you want to use a custom button */
input.cropit-image-input {
  visibility: hidden;
}

/* The following styles are only relevant to when background image is enabled */

/* Translucent background image */
.cropit-preview-background {
  opacity: .2;
}

/*
 * If the slider or anything else is covered by the background image,
 * use non-static position on it
 */
input.cropit-image-zoom-input {
  position: relative;
}

/* Limit the background image by adding overflow: hidden */
#image-cropper {
  overflow: hidden;
}