A responsive image cropping tool for React.
- Responsive
- Touch enabled
- Free-form or fixed aspect crops
- Keyboard support for nudging selection
- Min/max crop size
Include the main js module, e.g.:
var ReactCrop = require('react-image-crop');
// or es6:
import ReactCrop from 'react-image-crop';
Include either dist/ReactCrop.css
or ReactCrop.scss
.
<ReactCrop src='path/to/image.jpg' />
You can of course pass a blob path or base64 data.
All crop values are in percentages, and are relative to the image. All crop params are optional.
var crop = {
x: 20,
y: 10,
width: 30,
height: 10
}
<ReactCrop src='path/to/image.jpg' crop={crop} />
If you want a fixed aspect you only need to specify a width or a height:
var crop = {
width: 30,
aspect: 16/9
}
..Or you can omit both and only specify the aspect.
Please note that the values will be adjusted if the cropping area is outside of the image boundaries.
A minimum crop width.
A minimum crop height.
If true is passed then selection can't be disabled if the user clicks outside the selection area.
If true then the user cannot modify or draw a new crop. A class of ReactCrop--disabled
is also added to the container for user styling.
A callback which happens for every change of the crop (i.e. many times as you are dragging/resizing). Passes the current crop state object.
A callback which happens after a resize, drag, or nudge. Passes the current crop state object.
A callback which happens when the image is loaded. Passes the current crop state object and the image DOM element.
If true, the selection will have an ellipse shape rather than a rectangular one. If a fixed aspect ratio is also specified, the shape will be strictly circular.
I wanted to keep this component focused so I didn't provide this. Normally a cropped image will be rendered and cached by a backend. However here are some tips for client-side crop previews:
- You can fake a crop in pure CSS, but in order to do this you need to know the maximum width & height of the crop preview and then perform the calc again if the container size changes (since this technique is only possible using pixels). It's advantage is that it's instantaneous:
- The other technique is to map the cropped image to a canvas, and then get the base64 of the canvas via toDataURL and set this as an image source. The advantage is that the preview behaves like a proper image and is responsive. Now this is important:
-
toDataURL is synchronous and will block the main thread, for large images this could be for as long as a couple of seconds. Always use
toDataURL('image/jpeg')
otherwise it will default toimage/png
and the conversion will be significantly slower. -
Keep an eye out for toBlob when this lands on more browsers, as it will be both faster and asynchronous.
-
Another option to make the conversion faster is to scale the image down before converting it to a base64 (see example in gist).
To develop run npm start
, this will recompile your JS and SCSS on changes.
You can test your changes by opening demo/index.html
in a browser (you don't need to be running a server).
A commit hook will ensure that npm run release
is ran for you, or you can do it yourself so you have a single commit.
## Browser compatibility
Should work on any modern browser, however the darkened non-selected part of the image will not work in IE11 or IE Edge due to a lack of clipPath support.