Cropper
A powerful image and video cropper with zoom, rotation, and customizable crop areas.
Installation
pnpm dlx shadcn@latest add @diceui/cropper
Layout
Import the parts, and compose them together.
import {
Cropper,
CropperArea,
CropperImage,
CropperVideo,
} from "@/components/ui/cropper";
return (
<Cropper>
<CropperImage src="/image.jpg" alt="Image to crop" />
<CropperArea />
</Cropper>
)Examples
Controlled State
A cropper with external controls for zoom, rotation, and crop position.
With File Upload
A cropper integrated with the FileUpload component for uploading and cropping images.
Different Shapes
A cropper with different shapes and configuration options.
Video Cropping
A cropper that works with video content.
API Reference
Cropper
The root container for the cropper component.
Prop
Type
CropperImage
The image element to be cropped.
Prop
Type
CropperVideo
The video element to be cropped.
Prop
Type
CropperArea
The crop area overlay that shows the selected region.
Prop
Type
Accessibility
Keyboard Interactions
| Key | Description |
|---|---|
| Tab | Moves focus to the cropper content. |
| ArrowUp | Moves the crop area up by the keyboard step amount. |
| ArrowDown | Moves the crop area down by the keyboard step amount. |
| ArrowLeft | Moves the crop area left by the keyboard step amount. |
| ArrowRight | Moves the crop area right by the keyboard step amount. |
| Shift + Arrow Keys | Moves the crop area with finer precision (20% of keyboard step). |
Mouse and Touch Interactions
- Drag: Pan the media within the crop area
- Scroll/Wheel: Zoom in and out (can be disabled with
preventScrollZoom) - Pinch: Zoom and rotate on touch devices
- Two-finger drag: Pan while maintaining pinch zoom
Advanced Usage
Custom Crop Calculations
You can use the crop data from onCropComplete to perform server-side cropping:
const onCropComplete = (croppedArea, croppedAreaPixels) => {
// croppedArea contains percentages (0-100)
// croppedAreaPixels contains actual pixel coordinates
// Send to server for processing
cropImage({
x: croppedAreaPixels.x,
y: croppedAreaPixels.y,
width: croppedAreaPixels.width,
height: croppedAreaPixels.height,
});
};Performance Optimization
The cropper includes several performance optimizations:
- LRU Caching: Frequently used calculations are cached
- RAF Throttling: UI updates are throttled using requestAnimationFrame
- Quantization: Values are quantized to reduce cache misses
- Lazy Computation: Expensive calculations are deferred when possible
Object Fit Modes
The cropper supports different object fit modes:
- contain: Media fits entirely within the container (default)
- cover: Media covers the entire container, may be cropped
- horizontal-cover: Media width matches container width
- vertical-cover: Media height matches container height
Browser Support
Core Features
All core cropping features work in modern browsers:
- Chrome/Edge: Full support
- Firefox: Full support
- Safari: Full support (iOS 13+)
Touch Gestures
Multi-touch gestures require modern touch APIs:
- iOS Safari: Supported from iOS 13+
- Chrome Mobile: Full support
- Firefox Mobile: Basic touch support
Video Support
Video cropping requires modern video APIs:
- Chrome/Edge: Full support for all video formats
- Firefox: Full support with some codec limitations
- Safari: Full support with H.264/HEVC
Troubleshooting
CORS Issues
When cropping images from external domains, ensure proper CORS headers:
<CropperImage
src="https://example.com/image.jpg"
crossOrigin="anonymous"
alt="External image"
/>Performance with Large Media
For large images or videos, consider:
- Pre-processing media to reasonable sizes
- Using
snapPixelsfor crisp rendering - Limiting zoom range with
minZoomandmaxZoom - Reducing
keyboardStepfor smoother interactions
Mobile Considerations
On mobile devices:
- Use appropriate viewport meta tags
- Consider touch target sizes for controls
- Test pinch-to-zoom interactions
- Ensure adequate spacing around interactive elements
Credits
- Unsplash - For the photos used in examples.
- Blender Foundation - For the video used in examples.