A flexible, customizable React component for cropping profile pictures with real-time preview.
- 🖼️ Circular, square, or rectangular crop shapes
- 🔄 Real-time preview
- 📱 Responsive and mobile-friendly with touch support
- 🎚️ Zoom and drag controls
- 🎨 Fully customizable theming
- 📤 Multiple output formats (PNG, JPEG, WebP)
- ⚙️ Configurable aspect ratio
- 🔍 Error handling for file types and size
npm install react-profile-cropper
# or
yarn add react-profile-cropper
import React from "react";
import { ProfileCropper } from "react-profile-cropper";
function App() {
return (
<div className="app">
<ProfileCropper
onSave={(imageData) => {
console.log("Cropped image:", imageData);
// Save to server or state
}}
/>
</div>
);
}
export default App;
import React, { useState } from "react";
import { ProfileCropper } from "react-profile-cropper";
function ProfileEditor() {
const [profileImage, setProfileImage] = useState(null);
const [showCropper, setShowCropper] = useState(false);
const handleSave = (imageData) => {
setProfileImage(imageData);
setShowCropper(false);
// Upload to server
};
return (
<div className="profile-editor">
{profileImage ? (
<div className="current-profile">
<img src={profileImage} alt="Profile" className="profile-image" />
<button onClick={() => setShowCropper(true)}>Change Picture</button>
</div>
) : (
<button onClick={() => setShowCropper(true)}>
Add Profile Picture
</button>
)}
{showCropper && (
<div className="cropper-modal">
<ProfileCropper
initialImage={profileImage}
onSave={handleSave}
onCancel={() => setShowCropper(false)}
cropShape="circle"
outputFormat="png"
maxFileSizeMB={2}
theme={{
accentColor: "#4a90e2",
buttonBackgroundColor: "#4a90e2",
}}
/>
</div>
)}
</div>
);
}
export default ProfileEditor;
import { ProfileCropper } from "react-profile-cropper";
const customTheme = {
backgroundColor: "#ffffff",
overlayColor: "rgba(0, 0, 0, 0.7)",
borderColor: "#cccccc",
accentColor: "#ff5722",
textColor: "#333333",
buttonBackgroundColor: "#ff5722",
buttonTextColor: "white",
};
function App() {
return (
<ProfileCropper
theme={customTheme}
// other props...
/>
);
}
Prop |
Type |
Default |
Description |
initialImage |
string |
undefined |
Base64 or URL of initial image to crop |
onSave |
(imageData: string) => void |
undefined |
Callback when save button is clicked |
onCancel |
() => void |
undefined |
Callback when cancel button is clicked |
cropShape |
'circle' | 'square' | 'rectangle' |
'circle' |
Shape of the crop area |
aspectRatio |
number |
undefined |
Aspect ratio of crop area (width/height) |
outputFormat |
'png' | 'jpeg' | 'webp' |
'png' |
Output image format |
outputQuality |
number |
0.9 |
Output image quality (0-1) |
Prop |
Type |
Default |
Description |
theme |
ThemeOptions |
See below |
Theme customization object |
size |
number |
250 |
Size of the crop area (width in px) |
className |
string |
'' |
Class name for the container element |
style |
React.CSSProperties |
{} |
Inline styles for the container |
containerHeight |
number |
350 |
Height of the container (px) |
Prop |
Type |
Default |
Description |
maxZoom |
number |
4 |
Maximum zoom level |
minZoom |
number |
0 |
Minimum zoom level |
zoomStep |
number |
0.1 |
Step size for zoom controls |
allowZoom |
boolean |
true |
Enable zoom controls |
allowDrag |
boolean |
true |
Enable image dragging |
showPreview |
boolean |
true |
Show preview of cropped image |
previewSize |
number |
120 |
Size of preview image (px) |
showZoomControls |
boolean |
true |
Show zoom slider |
showChangeButton |
boolean |
true |
Show button to change image |
Prop |
Type |
Default |
Description |
headerText |
string |
'Profile Picture Cropper' |
Header text |
previewText |
string |
'Preview' |
Text below preview image |
saveButtonText |
string |
'Save Profile Picture' |
Save button text |
cancelButtonText |
string |
'Cancel' |
Cancel button text |
loadingText |
string |
'Saving...' |
Text shown when saving |
uploadText |
string |
'Click to upload image' |
Upload area main text |
uploadSubtext |
string |
'JPG, PNG or GIF. Max 5MB.' |
Upload area subtext |
zoomLabel |
string |
'Zoom:' |
Label for zoom control |
changeButtonText |
string |
'Change Image' |
Change image button text |
Prop |
Type |
Default |
Description |
acceptedFileTypes |
string |
'image/*' |
Accepted file types for upload |
maxFileSizeMB |
number |
5 |
Maximum file size in MB |
Prop |
Type |
Default |
Description |
containerClassName |
string |
'' |
Class for the outer container |
headerClassName |
string |
'' |
Class for the header text |
previewContainerClassName |
string |
'' |
Class for preview container |
buttonContainerClassName |
string |
'' |
Class for button container |
saveButtonClassName |
string |
'' |
Class for save button |
cancelButtonClassName |
string |
'' |
Class for cancel button |
errorContainerClassname |
string |
'' |
Class for error container |
errorTextClassname |
string |
'' |
Class for error text |
Prop |
Type |
Default |
Description |
onError |
(error: string) => void |
undefined |
Callback when an error occurs |
{
backgroundColor: "#f3f2ef",
overlayColor: "rgba(0, 0, 0, 0.6)",
borderColor: "#e0e0e0",
accentColor: "#0077B5",
textColor: "#333333",
buttonBackgroundColor: "#0077B5",
buttonTextColor: "white"
}
The package includes TypeScript definitions. You can import the types:
import {
ProfileCropperProps,
CropArea,
ThemeOptions,
CropShape,
OutputImageType,
} from "react-profile-cropper";
MIT © ydixit007(https://github.com/ydixit007)