DocSpace-buildtools/packages/components/ImageEditor/ImageCropper/index.js

140 lines
3.6 KiB
JavaScript
Raw Normal View History

import React, { useEffect } from "react";
import { ReactSVG } from "react-svg";
import throttle from "lodash/throttle";
import AvatarEditor from "react-avatar-editor";
import ZoomMinusReactSvgUrl from "../../../../public/images/zoom-minus.react.svg?url";
import ZoomPlusReactSvgUrl from "../../../../public/images/zoom-plus.react.svg?url";
import Slider from "../../slider";
import IconButton from "../../icon-button";
import StyledImageCropper from "./StyledImageCropper";
const ImageCropper = ({
t,
image,
onChangeImage,
uploadedFile,
setUploadedFile,
setPreviewImage,
isDisabled,
}) => {
let editorRef = null;
const setEditorRef = (editor) => (editorRef = editor);
const handlePositionChange = (position) => {
if (isDisabled) return;
onChangeImage({ ...image, x: position.x, y: position.y });
};
const handleSliderChange = (e, newZoom = null) => {
if (isDisabled) return;
onChangeImage({ ...image, zoom: newZoom ? newZoom : +e.target.value });
};
const handleZoomInClick = () => {
if (isDisabled) return;
handleSliderChange({}, image.zoom <= 4.5 ? image.zoom + 0.5 : 5);
};
const handleZoomOutClick = () => {
if (isDisabled) return;
handleSliderChange({}, image.zoom >= 1.5 ? image.zoom - 0.5 : 1);
};
const handleDeleteImage = () => {
if (isDisabled) return;
setUploadedFile(null);
};
const handleImageChange = throttle(() => {
try {
if (!editorRef) return;
const newPreveiwImage = editorRef.getImageScaledToCanvas()?.toDataURL();
setPreviewImage(newPreveiwImage);
} catch (e) {
console.error(e);
}
}, 300);
useEffect(() => {
handleImageChange();
return () => {
setPreviewImage("");
};
}, [image]);
return (
<StyledImageCropper className="icon_cropper">
<div className="icon_cropper-crop_area">
<ReactSVG
className="icon_cropper-grid"
src="images/icon-cropper-grid.svg"
/>
<AvatarEditor
ref={setEditorRef}
image={uploadedFile}
width={216}
height={216}
position={{ x: image.x, y: image.y }}
scale={image.zoom}
color={[6, 22, 38, 0.2]}
border={0}
rotate={0}
borderRadius={108}
onPositionChange={handlePositionChange}
onImageReady={handleImageChange}
disableHiDPIScaling
crossOrigin="anonymous"
/>
</div>
<div
className="icon_cropper-delete_button"
onClick={handleDeleteImage}
title={t("Common:Delete")}
>
<ReactSVG src={"images/trash.react.svg"} />
<div className="icon_cropper-delete_button-text">
{t("Common:Delete")}
</div>
</div>
<div className="icon_cropper-zoom-container">
<IconButton
className="icon_cropper-zoom-container-button"
size="16"
onClick={handleZoomOutClick}
iconName={ZoomMinusReactSvgUrl}
isFill={true}
isClickable={false}
isDisabled={isDisabled}
/>
<Slider
className="icon_cropper-zoom-container-slider"
max={5}
min={1}
onChange={handleSliderChange}
step={0.01}
value={image.zoom}
isDisabled={isDisabled}
/>
<IconButton
className="icon_cropper-zoom-container-button"
size="16"
onClick={handleZoomInClick}
iconName={ZoomPlusReactSvgUrl}
isFill={true}
isClickable={false}
isDisabled={isDisabled}
/>
</div>
</StyledImageCropper>
);
};
export default ImageCropper;