Skip to content

Instantly share code, notes, and snippets.

@EthanBonsignori
Last active March 25, 2021 17:05
Show Gist options
  • Select an option

  • Save EthanBonsignori/cba0c8ca2623279c4a169e223bfb0bff to your computer and use it in GitHub Desktop.

Select an option

Save EthanBonsignori/cba0c8ca2623279c4a169e223bfb0bff to your computer and use it in GitHub Desktop.
Second revision of CropModal - adding react-image-crop and configuring the crop
import { useCallback, useEffect, useRef, useState } from 'react';
import Modal from 'react-modal';
import ReactCrop from 'react-image-crop';
import 'react-image-crop/dist/ReactCrop.css';
// For accessibility (http://reactcommunity.org/react-modal/accessibility/)
Modal.setAppElement('#root');
function CropModal(props) {
const {
isOpen,
toggleModal,
imageBase64,
} = props;
const imgRef = useRef(null);
const previewCanvasRef = useRef(null);
const [crop, setCrop] = useState({ unit: '%', width: 50, aspect: 1 / 1 });
const [completedCrop, setCompletedCrop] = useState(null);
const onLoad = useCallback(img => {
imgRef.current = img;
}, []);
useEffect(() => {
if (!completedCrop || !previewCanvasRef.current || !imgRef.current) {
return;
}
const image = imgRef.current;
const canvas = previewCanvasRef.current;
const crop = completedCrop;
const scaleX = image.naturalWidth / image.width;
const scaleY = image.naturalHeight / image.height;
const ctx = canvas.getContext("2d");
const pixelRatio = window.devicePixelRatio;
canvas.width = crop.width * pixelRatio;
canvas.height = crop.height * pixelRatio;
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,
crop.height
);
}, [completedCrop]);
return (
<Modal
className="modal"
isOpen={isOpen}
onRequestClose={toggleModal}
>
<h3>Crop Your Image</h3>
<ReactCrop
src={imageBase64}
onImageLoaded={onLoad}
crop={crop}
onChange={(c) => setCrop(c)}
onComplete={(c) => setCompletedCrop(c)}
minHeight={100} // change to your desired minimum crop height/width
minWidth={100}
ruleOfThirds // shows a grid pattern for centering
circularCrop // remove this if your profile images are square
keepSelection // crop won't reset on click
imageStyle={{ maxHeight: '75vh'}} // prevents image from pushing modal off-screen
/>
</Modal>
);
};
export default CropModal;
@EthanBonsignori
Copy link
Author

EthanBonsignori commented Mar 25, 2021

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment