인생네컷 만들기 프로젝트 2 - 이미지 크롭창 만들기 (실패 기록)

동화·2023년 4월 18일
1

Toy-project

목록 보기
3/4
post-thumbnail

지난 번에 이미지 사이즈를 지정했더니
불러온 사진들이 비율 상관없이 찌부가 되는 것들을 막고자
새로운 기능을 공부해보았따.

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한 데이터를 받아오고 싶었는데 내내 머리 쓰다가 결국엔 실패했다 ㅠ.ㅠ
너무 여기에 매달릴 수가 없어서 차차 생각해보기로 했음.. ㅠ ㅠ

0개의 댓글