Preview:
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);
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