I implemented react-image0crop in a project but after testing with different size of images(landscape & portrait)I spotted an issue with cropper frame handler - 3 handlers are working fine marked as green
Problem with red is I am using aspect ratio as aspect : 16/9 so when after I select an image from my computer then cropper frame is appearing with correct aspect ratio but when I drag cropper to bottom and then start resizing cropper frame using top left using crop frame's handler (marked as red in previous screenshot) it is resizing but aspect ration is not maintaining during this resizing process
code sand box link is here - https://codesandbox.io/s/72py4jlll6
here is complete code - `
import ReactDOM from 'react-dom';
import React, { PureComponent } from 'react';
import ReactCrop from 'react-image-crop';
import 'react-image-crop/dist/ReactCrop.css';
import './App.css';
class App extends PureComponent {
state = {
src: null,
crop: {
unit: '%',
width: 30,
aspect: 16 / 9
}
};
onSelectFile = (e) => {
if (e.target.files && e.target.files.length > 0) {
const reader = new FileReader();
reader.addEventListener('load', () =>
this.setState({ src: reader.result })
);
reader.readAsDataURL(e.target.files[0]);
}
};
// If you setState the crop in here you should return false.
onImageLoaded = (image) => {
this.imageRef = image;
};
onCropComplete = (crop) => {
this.makeClientCrop(crop);
};
onCropChange = (crop, percentCrop) => {
// You could also use percentCrop:
// this.setState({ crop: percentCrop });
this.setState({ crop });
};
async makeClientCrop(crop) {
if (this.imageRef && crop.width && crop.height) {
const croppedImageUrl = await this.getCroppedImg(
this.imageRef,
crop,
'newFile.jpeg'
);
this.setState({ croppedImageUrl });
}
}
getCroppedImg(image, crop, fileName) {
const canvas = document.createElement('canvas');
const pixelRatio = window.devicePixelRatio;
const scaleX = image.naturalWidth / image.width;
const scaleY = image.naturalHeight / image.height;
const ctx = canvas.getContext('2d');
canvas.width = crop.width * pixelRatio * scaleX;
canvas.height = crop.height * pixelRatio * scaleY;
ctx.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0);
ctx.imageSmoothingQuality = 'high';
ctx.drawImage(
image,
crop.x * scaleX,
crop.y * scaleY,
crop.width * scaleX,
crop.height * scaleY,
0,
0,
crop.width * scaleX,
crop.height * scaleY
);
return new Promise((resolve, reject) => {
canvas.toBlob(
(blob) => {
if (!blob) {
//reject(new Error('Canvas is empty'));
console.error('Canvas is empty');
return;
}
blob.name = fileName;
window.URL.revokeObjectURL(this.fileUrl);
this.fileUrl = window.URL.createObjectURL(blob);
resolve(this.fileUrl);
},
'image/jpeg',
1
);
});
}
render() { const { crop, croppedImageUrl, src } = this.state;
return (
<div className="App">
<div>
<input type="file" accept="image/*" onChange={this.onSelectFile} />
</div>
{src && (
<ReactCrop
src={src}
crop={crop}
ruleOfThirds
onImageLoaded={this.onImageLoaded}
onComplete={this.onCropComplete}
onChange={this.onCropChange}
/>
)}
{croppedImageUrl && (
<img alt="Crop" style={{ maxWidth: '100%' }} src={croppedImageUrl} />
)}
</div>
);
} }
ReactDOM.render(, document.getElementById('root')); `