import React, { useState, useRef } from 'react'; import { Dialog, DialogActions, DialogContent, Typography, styled, Button, Slider, withStyles } from '@material-ui/core'; import Cropper from 'react-cropper'; import 'cropperjs/dist/cropper.css'; const Input = () => { const [open, setOpen] = useState(true); const cropperRef = useRef(null); const [croppedImage, setCroppedImage] = useState(null); const [cropBoxSize, setCropBoxSize] = useState(200); const [zoomLevel, setZoomLevel] = useState(1); const handleCrop = () => { const cropper = cropperRef.current.cropper; setCroppedImage(cropper.getCroppedCanvas({ width: cropBoxSize, height: cropBoxSize, }).toDataURL()); }; const handleApply = () => { handleCrop(); setOpen(false); }; const handleCancel = () => { setOpen(false); }; const handleZoomChange = (event, newValue) => { const cropper = cropperRef.current.cropper; setZoomLevel(newValue); cropper.zoomTo(newValue); }; return ( <div> <ProfileDialog open={open}> <ProfileTitle>Adjust position of photo</ProfileTitle> <DialogContent style={{ padding: '0px',background:'#eeeeee' }}> <CropperWrapper> <Cropper src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSzP-Y9jQiwYJRI8DqrnqxdI9UzLtkcYC9SRw&s" initialAspectRatio={1} // Set aspect ratio to 1 for a square crop box guides={true} ref={cropperRef} viewMode={1} dragMode="move" movable={true} zoomable={true} style={{ height: '100%', width: '100%'}} cropBoxResizable={false} cropBoxMovable={false} background={false} ready={() => { const cropper = cropperRef.current.cropper; const initialZoomLevel = cropper.getData().scaleX; setZoomLevel(initialZoomLevel); cropper.setCropBoxData({ width: cropBoxSize, height: cropBoxSize, left: (cropper.getContainerData().width - cropBoxSize) / 2, top: (cropper.getContainerData().height - cropBoxSize) / 2, }); }} cropend={() => { const cropper = cropperRef.current.cropper; cropper.cropBoxData = { ...cropper.cropBoxData, width: cropBoxSize, height: cropBoxSize, }; cropper.setCropBoxData(cropper.cropBoxData); }} /> <div style={{ display: 'flex', justifyContent: "center", alignItems: 'center',background:'#eeeeee' }}> <div style={{ width: '40%' }}> <div style={{display:'flex',flexDirection:'row',justifyContent:'space-between'}}> <p>Zoom</p> <p>{zoomLevel}</p> </div> <PrettoSlider style={{ zIndex: '999', marginTop: '-20px' }} value={zoomLevel} min={1} max={3} step={0.01} onChange={handleZoomChange} aria-labelledby="zoom-slider" // valueLabelDisplay="auto" /> </div> </div> </CropperWrapper> </DialogContent> <DialogActions style={{ justifyContent: 'center', alignItems: 'center' }}> <Button variant='outlined' onClick={handleApply}>Apply</Button> <Button variant='outlined' onClick={handleCancel}>Cancel</Button> </DialogActions> </ProfileDialog> {croppedImage && ( <div> <Typography variant="h6">Cropped Image:</Typography> <img src={croppedImage} alt="Cropped" style={{ maxWidth: '100%' }} /> </div> )} </div> ); }; export default Input; const ProfileDialog = styled(Dialog)({ '& .MuiPaper-rounded': { borderRadius: '10px', width: 'calc(45% - 100px)' } }); const ProfileTitle = styled(Typography)({ padding: '20px', fontWeight: 'bold', fontFamily: 'sans-serif' }); const CropperWrapper = styled('div')({ backgroundColor: '#ddd', position: 'relative', marginTop:'40px', // '& .cropper-view-box': { // borderRadius: '50%', // Make crop box a circle // }, // '& .cropper-face': { // borderRadius: '50%', // Make crop box a circle // clipPath: 'circle(50% at 50% 50%)', // Use clipPath to clip the content to a circle // }, '& .cropper-modal': { backgroundColor: 'white' } }); const PrettoSlider = withStyles({ root: { color: '#374f81', height: 4, }, thumb: { height: 12, width: 12, backgroundColor: '#fff', border: '4px solid currentColor', marginTop: -4, marginLeft: -6, '&:focus, &:hover, &$active': { boxShadow: 'inherit', }, }, active: {}, valueLabel: { left: '-30px', '& *': { background: 'white', color: '#000', transform: 'none', width: '80px', borderRadius: '4px', textAlign: 'center' }, }, track: { height: 4, borderRadius: 2, }, rail: { height: 4, borderRadius: 2, opacity: 1, backgroundColor: 'white', }, })(Slider);
Preview:
downloadDownload PNG
downloadDownload JPEG
downloadDownload SVG
Tip: You can change the style, width & colours of the snippet with the inspect tool before clicking Download!
Click to optimize width for Twitter