Last active
March 25, 2021 17:05
-
-
Save EthanBonsignori/cba0c8ca2623279c4a169e223bfb0bff to your computer and use it in GitHub Desktop.
Second revision of CropModal - adding react-image-crop and configuring the crop
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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; |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
For the tutorial found here: https://ethanbon.com/blog/uploading-cropped-profile-images-to-digital-ocean-spaces-1