Documentation keyboard_arrow_right Plugins keyboard_arrow_right Image cropper
JavaScript Image Cropper
A lightweight, powerful JavaScript image cropper and photo editor component built with LemonadeJS. Crop, resize, rotate, and adjust images directly in your web browser with this modern, reactive image editing solution.
The LemonadeJS cropper is based on jSuites image cropper component. For spreadsheet integration, see Jspreadsheet CE Images (free) or Jspreadsheet Pro with advanced Media Integration.
Key Features
-
Image Cropping: Intuitive drag-and-drop interface for precise image cropping
-
Image Rotation: Rotate images with smooth, real-time preview
-
Zoom Control: Fine-grained zoom functionality from 0.1x to 5.45x
-
Image Adjustments: Brightness and contrast controls for professional results
-
Responsive Design: Automatically adapts to mobile and desktop screens
-
Modal Interface: Clean, user-friendly modal dialog for editing
-
Blob Output: Generates cropped images as blobs for easy upload
-
Original Image Preservation: Optionally keep the original image alongside the cropped version
-
TypeScript Support: Full TypeScript definitions included
-
Framework Integration: Works with vanilla JavaScript, React, Vue, and any modern framework
Documentation
Installation
NPM Installation
npm install @lemonadejs/cropper
CDN Installation
<!-- LemonadeJS Core -->
<script src="https://cdn.jsdelivr.net/npm/lemonadejs/dist/lemonade.min.js"></script>
<!-- jSuites Cropper (dependency) -->
<script src="https://cdn.jsdelivr.net/npm/@jsuites/cropper/cropper.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@jsuites/cropper/cropper.min.css" />
<!-- LemonadeJS Cropper Plugin -->
<script src="https://cdn.jsdelivr.net/npm/@lemonadejs/cropper/dist/index.min.js"></script>
Options
| Property |
Type |
Default |
Description |
width |
number |
300 |
Width of the crop area in pixels |
height |
number |
240 |
Height of the crop area in pixels |
original |
boolean |
false |
Whether to preserve the original image |
name |
string |
undefined |
Name attribute for form integration |
value |
ImageData |
null |
Initial image data |
Methods
| Method |
Description |
| getValue() |
Retrieve the current cropped image data and metadata |
| setValue(data) |
Set or update the image in the cropper (accepts URL, ImageData, or null) |
| open() |
Programmatically open the cropper modal interface |
| uploadPhoto() |
Launch the file picker modal to select a new photo |
| deletePhoto() |
Remove the current image from the cropper container |
| setControls(state) |
Enable or disable the editing controls (zoom, rotate, brightness, contrast) |
Properties
| Property |
Type |
Description |
brightness |
number |
Current brightness adjustment value (-1 to 1) |
contrast |
number |
Current contrast adjustment value (-1 to 1) |
greyscale |
number |
Current greyscale value (0 to 1) |
cropperArea |
HTMLElement |
Reference to the cropper area DOM element |
ImageData Interface
interface ImageData {
file: string; // URL or blob URL to the image
content?: string; // Base64 or data URL content
extension?: string; // File extension (e.g., 'jpg', 'png')
original?: string; // Original image URL (if preserved)
guid?: string;
}
Examples
Basic Image Cropper
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/lemonadejs/dist/lemonade.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@jsuites/cropper/cropper.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@jsuites/cropper/cropper.min.css" />
<script src="https://cdn.jsdelivr.net/npm/@lemonadejs/cropper/dist/index.min.js"></script>
</head>
<body>
<div id="root"></div>
<script>
const root = document.getElementById('root');
const cropper = Cropper(root, {
width: 300,
height: 240
});
</script>
</body>
</html>
Using with LemonadeJS Component
import lemonade from 'lemonadejs';
import Cropper from '@lemonadejs/cropper';
export default function MyApp() {
const self = this;
return `<div>
<h1>Profile Picture Editor</h1>
<Cropper
width="400"
height="300"
:ref="self.cropper"
original="true" />
<button onclick="self.cropper.open()">Edit Photo</button>
</div>`;
}
React Integration
import React, { useRef, useEffect } from 'react';
import Cropper from '@lemonadejs/cropper';
function PhotoEditor() {
const cropperRef = useRef(null);
const containerRef = useRef(null);
useEffect(() => {
if (containerRef.current) {
cropperRef.current = Cropper(containerRef.current, {
width: 400,
height: 300,
original: true
});
}
return () => {
// Cleanup if needed
};
}, []);
const handleGetImage = () => {
if (cropperRef.current) {
const imageData = cropperRef.current.getValue();
console.log('Image data:', imageData);
}
};
return (
<div>
<div ref={containerRef}></div>
<button onClick={handleGetImage}>Get Image Data</button>
</div>
);
}
export default PhotoEditor;
Advanced Configuration
const cropper = Cropper(document.getElementById('root'), {
width: 500, // Crop area width
height: 400, // Crop area height
original: true, // Preserve original image
name: 'profile_pic' // Form field name
});
// Set an image programmatically
cropper.setValue({
file: 'https://example.com/image.jpg'
});
// Get cropped image data
const imageData = cropper.getValue();
console.log(imageData);
// Output: { file: 'blob:...', content: 'data:image/png;base64,...', extension: 'png' }
Profile Picture Upload
const profileCropper = Cropper(document.getElementById('profile-editor'), {
width: 200,
height: 200,
original: true
});
// After user crops the image
async function uploadProfilePicture() {
const data = profileCropper.getValue();
if (data && data.content) {
const formData = new FormData();
const response = await fetch(data.content);
const blob = await response.blob();
formData.append('profile_picture', blob, 'profile.png');
// Upload to server
await fetch('/api/upload', {
method: 'POST',
body: formData
});
}
}
E-commerce Product Image Editor
const productCropper = Cropper(document.getElementById('product-images'), {
width: 800,
height: 600,
original: true, // Keep original for zoom functionality
name: 'product_image'
});
// Handle multiple product images
function addProductImage(imageUrl) {
productCropper.setValue({
file: imageUrl,
original: imageUrl
});
}
Responsive Mobile-Friendly Cropper
// Automatically adjusts for mobile devices
const responsiveCropper = Cropper(document.getElementById('mobile-editor'), {
width: window.innerWidth < 640 ? window.innerWidth - 40 : 600,
height: window.innerWidth < 640 ? window.innerWidth - 40 : 450
});
// The cropper automatically adapts its interface for screens < 800px