
Research
Security News
Malicious npm Package Wipes Codebases with Remote Trigger
A malicious npm typosquat uses remote commands to silently delete entire project directories after a single mistyped install.
react-photo-editor
Advanced tools
React component and hook for image editing, offering controls for brightness, contrast, saturation, and grayscale, along with features to rotate, flip, pan, draw, and zoom photos.
React component and hook for image editing with options to set brightness, contrast, saturation, and grayscale. Also with features to rotate, flip, pan, draw and zoom the photo.
usePhotoEditor
hookChoose your preferred package manager:
# Using npm
npm install react-photo-editor
# Using yarn
yarn add react-photo-editor
import { useState } from 'react';
import { ReactPhotoEditor } from 'react-photo-editor';
function App() {
const [file, setFile] = useState();
const [showModal, setShowModal] = useState(false);
// Show modal if file is selected
const showModalHandler = () => {
if (file) {
setShowModal(true);
}
};
// Hide modal
const hideModal = () => {
setShowModal(false);
};
// Save edited image
const handleSaveImage = (editedFile) => {
setFile(editedFile);
// Do something with the edited file
};
const setFileData = (e) => {
if (e?.target?.files && e.target.files.length > 0) {
setFile(e.target.files[0]);
}
};
return (
<>
<input type='file' onChange={(e) => setFileData(e)} multiple={false} />
<button onClick={showModalHandler}>Edit Photo</button>
<ReactPhotoEditor
open={showModal}
onClose={hideModal}
file={file}
onSaveImage={handleSaveImage}
/>
</>
);
}
export default App;
See it in action on Stackblitz
import 'react-photo-editor/dist/style.css'
) is no longer required'./node_modules/react-photo-editor/dist/*.js'
to your Tailwind configcanvas
to rpe-canvas
for better consistency with the rest of the project. Make sure to update your usage accordingly.The ReactPhotoEditor
component accepts the following props:
Prop | Type | Default | Description |
---|---|---|---|
file | File | undefined | Required | The input image file to be edited |
allowColorEditing | boolean | true | Whether to allow color editing options |
allowRotate | boolean | true | Whether to allow rotation of the image |
allowFlip | boolean | true | Whether to allow flipping of the image |
allowZoom | boolean | true | Whether to allow zooming of the image |
allowDrawing | boolean | true | Whether to enable drawing options |
downloadOnSave | boolean | false | Whether to enable downloading the edited image upon saving |
open | boolean | false | Whether the photo editor modal is open |
onClose | () => void | - | Function invoked when the modal is closed |
onSaveImage | (image: File) => void | Required | Function invoked when the edited image is saved |
modalHeight | number | string | '38rem' | Height of the photo editor modal |
modalWidth | number | string | '40rem' | Width of the photo editor modal |
canvasWidth | number | string | 'auto' | Width of the canvas element |
canvasHeight | number | string | 'auto' | Height of the canvas element |
maxCanvasHeight | number | string | '22rem' | Maximum height of the canvas element |
maxCanvasWidth | number | string | '36rem' | Maximum width of the canvas element |
labels | ReactPhotoEditorTranslations | - | Custom labels for UI elements |
usePhotoEditor
HookFor more control over the UI and functionality, you can use the usePhotoEditor
hook to build your own custom editor component.
For full examples, see the example folder.
import { usePhotoEditor } from 'react-photo-editor';
function CustomPhotoEditor({ file }) {
const {
canvasRef,
brightness,
contrast,
saturate,
grayscale,
setBrightness,
setContrast,
setSaturate,
setGrayscale,
handleZoomIn,
handleZoomOut,
generateEditedFile,
resetFilters,
} = usePhotoEditor({
file,
defaultBrightness: 100,
defaultContrast: 100,
defaultSaturate: 100,
defaultGrayscale: 0,
});
const handleSave = async () => {
const editedFile = await generateEditedFile();
// Do something with the edited file
};
return (
<div>
<canvas ref={canvasRef} />
<div>
<label>Brightness: {brightness}</label>
<input
type='range'
min='0'
max='200'
value={brightness}
onChange={(e) => setBrightness(Number(e.target.value))}
/>
</div>
{/* Add more controls for other parameters */}
<button onClick={handleZoomIn}>Zoom In</button>
<button onClick={handleZoomOut}>Zoom Out</button>
<button onClick={resetFilters}>Reset</button>
<button onClick={handleSave}>Save</button>
</div>
);
}
Parameter | Type | Default | Description |
---|---|---|---|
file | File | undefined | - | The image file to be edited |
defaultBrightness | number | 100 | Initial brightness level |
defaultContrast | number | 100 | Initial contrast level |
defaultSaturate | number | 100 | Initial saturation level |
defaultGrayscale | number | 0 | Initial grayscale level |
defaultFlipHorizontal | boolean | false | Initial horizontal flip state |
defaultFlipVertical | boolean | false | Initial vertical flip state |
defaultZoom | number | 1 | Initial zoom level |
defaultRotate | number | 0 | Initial rotation angle in degrees |
defaultLineColor | string | #000000 | Initial line color in hex code |
defaultLineWidth | number | 2 | Initial line/stroke width |
defaultMode | string | pan | Initial mode (draw or move ) |
The hook returns the following values and functions:
Name | Type | Description |
---|---|---|
canvasRef | RefObject<HTMLCanvasElement> | Reference to the canvas element |
imageSrc | string | The source of the loaded image |
State | Setter | Type | Description |
---|---|---|---|
brightness | setBrightness | number | Brightness level (default 100 ) |
contrast | setContrast | number | Contrast level (default 100 ) |
saturate | setSaturate | number | Saturation level (default 100 ) |
grayscale | setGrayscale | number | Grayscale level (default 0 ) |
rotate | setRotate | number | Rotation angle in degrees |
zoom | setZoom | number | Zoom level |
flipHorizontal | setFlipHorizontal | boolean | Flip horizontally |
flipVertical | setFlipVertical | boolean | Flip vertically |
mode | setMode | 'draw' | 'move' | Interaction mode (draw or move ) |
lineColor | setLineColor | string | Drawing line color |
lineWidth | setLineWidth | number | Drawing line width |
Function | Type | Description |
---|---|---|
handleZoomIn | () => void | Zoom in |
handleZoomOut | () => void | Zoom out |
resetFilters | () => void | Reset all filters and transformations |
downloadImage | () => void | Download current canvas as an image |
generateEditedFile | () => Promise<File> | Returns the edited canvas as a File object |
Function | Type | Description |
---|---|---|
handlePointerDown | PointerEventHandler | Used for drawing |
handlePointerUp | PointerEventHandler | Used for drawing |
handlePointerMove | PointerEventHandler | Used for drawing |
handleWheel | WheelEventHandler | Used for zooming |
Contributions to react-photo-editor
are welcome! If you have any issues, feature requests, or improvements, please open an issue or submit a pull request on the GitHub repository.
git checkout -b feature/amazing-feature
git commit -m 'Add some amazing feature'
git push origin feature/amazing-feature
When reporting issues, please provide:
This project is licensed under the MIT License - see the LICENSE file for details.
FAQs
React component and hook for image editing, offering controls for brightness, contrast, saturation, and grayscale, along with features to rotate, flip, pan, draw, and zoom photos.
We found that react-photo-editor demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
A malicious npm typosquat uses remote commands to silently delete entire project directories after a single mistyped install.
Research
Security News
Malicious PyPI package semantic-types steals Solana private keys via transitive dependency installs using monkey patching and blockchain exfiltration.
Security News
New CNA status enables OpenJS Foundation to assign CVEs for security vulnerabilities in projects like ESLint, Fastify, Electron, and others, while leaving disclosure responsibility with individual maintainers.