
์ง๋ ๋ฒ์ ์ด๋ฏธ์ง ์ฌ์ด์ฆ๋ฅผ ์ง์ ํ๋๋
๋ถ๋ฌ์จ ์ฌ์ง๋ค์ด ๋น์จ ์๊ด์์ด ์ฐ๋ถ๊ฐ ๋๋ ๊ฒ๋ค์ ๋ง๊ณ ์
์๋ก์ด ๊ธฐ๋ฅ์ ๊ณต๋ถํด๋ณด์๋ฐ.
react-easy-crop
๊ณต์ github: https://github.com/ricardo-ch/react-easy-crop
npm install react-easy-crop --save
react-cropper
๋๋ ๋๊ฐ์ง ์ค์ react-cropper๋ฅผ ์ด์ฉํ๋ค.
https://github.com/react-cropper/react-cropper
ImageCrop.js
import { useState, createRef } from "react";
import Cropper from "react-cropper";
import "cropperjs/dist/cropper.css";
import "./App.css";
import CropModal from "./CropModal";
function ImageCrop() {
const [image, setImage] = useState(process.env.PUBLIC_URL + "blank.jpg");
const [cropData, setCropData] = useState(null);
const cropperRef = createRef();
const onChange = (e) => {
e.preventDefault();
let files;
if (e.dataTransfer) {
files = e.dataTransfer.files;
} else if (e.target) {
files = e.target.files;
}
const reader = new FileReader();
reader.onload = () => {
setImage(reader.result);
};
reader.readAsDataURL(files[0]);
};
const getCropData = () => {
if (typeof cropperRef.current?.cropper !== "undefined") {
setCropData(cropperRef.current?.cropper.getCroppedCanvas().toDataURL());
}
};
return (
<div>
<div>
<div style={{ width: "100%" }}>
<input type="file" onChange={onChange} />
<button>Use default img</button>
<br />
<br />
<Cropper
ref={cropperRef}
style={{ height: "200px", width: "450px" }}
zoomTo={0.5}
initialAspectRatio={1}
preview=".img-preview"
src={image}
viewMode={1}
minCropBoxHeight={150}
minCropBoxWidth={250}
background={false}
responsive={true}
autoCropArea={1}
checkOrientation={false} // https://github.com/fengyuanchen/cropperjs/issues/671
guides={true}
/>
</div>
<div>
<div className="box" style={{ width: "50%", float: "right" }}>
<h1>Preview</h1>
<div
className="img-preview"
style={{ width: "250px", float: "left" }}
/>
</div>
<div
className="box"
style={{ width: "50%", float: "right", height: "300px" }}
>
<h1>
<span>Crop</span>
<button
style={{ float: "right", width: "100px", height: "20px" }}
onClick={getCropData}
>
<p style={{ fontSize: "small" }}>Crop Image</p>
</button>
</h1>
<img style={{ width: "100%" }} src={cropData} alt="cropped" />
</div>
</div>
<br style={{ clear: "both" }} />
</div>
<CropModal cropData={cropData} setCropData={setCropData} />
</div>
);
}
export default ImageCrop;
CropModal.js
import "bootstrap/dist/css/bootstrap.min.css";
import React, { useState } from "react";
import Button from "react-bootstrap/Button";
import Modal from "react-bootstrap/Modal";
import ImageCrop from "./ImageCrop";
const CropModal = ({ cropData, setCropData }) => {
const [show, setShow] = useState(false);
const reader = new FileReader();
const handleClose = () => setShow(false);
const handleShow = () => setShow(true);
const handleSave = () => {
setShow(false);
if (cropData) {
reader.readAsDataURL(cropData);
reader.onload = () => {
setCropData(reader);
};
}
new Promise((resolve) => {
reader.onload = () => {
setCropData(reader.result);
resolve();
};
});
};
return (
<>
<Modal show={show} onHide={handleClose}>
<Modal.Header closeButton>
<Modal.Title>Modal heading</Modal.Title>
</Modal.Header>
<Modal.Body>
<ImageCrop cropData={cropData} setCropData={setCropData} />
</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={handleClose}>
Close
</Button>
<Button variant="primary" onClick={handleSave}>
Save Changes
</Button>
</Modal.Footer>
</Modal>
<img
style={{
width: "250px",
height: "150px",
margin: "10px 20px",
cursor: "pointer",
}}
src={cropData ? cropData : process.env.PUBLIC_URL + "blank.jpg"}
// src={props.cropData}
alt=""
onClick={handleShow}
/>
</>
);
};
export default CropModal;
์ด๋ ๊ฒ ํ๋๋ฐ props์ ๋ฌ์ ์ ๋๋ก ๋ชปํด์ค์
cropํ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ค๊ณ ์ถ์๋๋ฐ ๋ด๋ด ๋จธ๋ฆฌ ์ฐ๋ค๊ฐ ๊ฒฐ๊ตญ์ ์คํจํ๋ค ใ
.ใ
๋๋ฌด ์ฌ๊ธฐ์ ๋งค๋ฌ๋ฆด ์๊ฐ ์์ด์ ์ฐจ์ฐจ ์๊ฐํด๋ณด๊ธฐ๋ก ํ์.. ใ
ใ
