React Quill Editor Image 처리

밍글·2023년 5월 7일
1
post-thumbnail

⌨️서론

저번 커스텀 toolBar 이후로 1달이 넘는 기간이 지났었다 🥲 여러 참고사이트를 활용하여 만들어두긴 했었지만 API연결까지 하는데 있어 예상보다 더 많은 기간이 지나서 이제서야 포스팅을 하게 되었다. 이번에는 Image Resize와 서버와 직접 연결짓는 ImageHandler기능을 다뤄보도록 하겠다.🙇‍♂️


1. Image Resize

먼저 이 기능을 사용하기 위해서는 다음과 같은 모듈을 설치해야 한다.

npm install quill-image-resize
필자의 경우는 tsx를 사용하기 때문에 혹시 몰라 아래와 같은 모듈을 설치하였다.
npm intall quill-image-resize-module-ts

그런 다음에 필자의 경우 toolbar부분과 quill 부분을 나누었기 때문에 각각 다음과 같은 코드를 추가해주었다.

//EditorToolBar.tsx
import { ImageResize } from "quill-image-resize-module-ts";
Quill.register("modules/ImageResize", ImageResize);
//ReactQuill.tsx
//modules부분에 다음과 같은 코드를 추가해준다.
  const modules = useMemo(() => {
    return {
      toolbar: {
        container: "#toolbar",
      },
      //추가된 부분
      ImageResize: {
        parchment: Quill.import("parchment"),
        modules: ["Resize", "DisplaySize"],
      },
      history: {
        delay: 500,
        maxStack: 100,
        userOnly: true,
      },
    };
  }, []);

이렇게 적용하면 다음과 같이 이미지 크기를 조절할 수 있다.
(이미지 크기가 quill크기보다 커서 이미지 크기 줄이는게 다소 어색해보일 수 있다😱)

2. Image Handler

처음에는 작성할 생각이 없었지만 서버에 이미지를 저장하기 위해서는 이미지를 따로 처리하는 방식을 만들어야 했다.. 그래서 다음과 같이 작성하게 되었다.

//ReactQuill.tsx
  const modules = useMemo(() => {
    return {
      toolbar: {
        container: "#toolbar",
        //추가된 부분 이미지를 ImageHandler라는 함수로 직접 처리한다는 의미이다.
        handlers: {
          image: ImageHandler,
        },
      },
      ImageResize: {
        parchment: Quill.import("parchment"),
        modules: ["Resize", "DisplaySize"],
      },
      history: {
        delay: 500,
        maxStack: 100,
        userOnly: true,
      },
    };
  }, []);

그런 다음 ImageHandler함수는 다음과 같이 나타낼 수 있다.

  //image를 서버로 전달하는 과정
  const ImageHandler = () => {
    //input type= file DOM을 만든다.
    const input = document.createElement("input");
    input.setAttribute("type", "file");
    input.setAttribute("accept", "image/*");
    input.click(); //toolbar 이미지를 누르게 되면 이 부분이 실행된다.
    /*이미지를 선택하게 될 시*/
    input.onchange = async () => {
      /*이미지 선택에 따른 조건을 다시 한번 하게 된다.*/
      const file: any = input.files ? input.files[0] : null;
      /*선택을 안하면 취소버튼처럼 수행하게 된다.*/
      if (!file) return;
      /*서버에서 FormData형식으로 받기 때문에 이에 맞는 데이터형식으로 만들어준다.*/
      const formData = new FormData();
      formData.append("profile", file);
      /*에디터 정보를 가져온다.*/
      let quillObj = quillRef.current?.getEditor();
      /*에디터 커서 위치를 가져온다.*/
      const range = quillObj?.getSelection()!;
      try {
        /*서버에다가 정보를 보내준 다음 서버에서 보낸 url을 imgUrl로 받는다.*/
        const res = await axios.post(
          "api주소",
          formData
        );
        const imgUrl = res.data;
        /*에디터의 커서 위치에 이미지 요소를 넣어준다.*/
        quillObj?.insertEmbed(range.index, "image", `${imgUrl}`);
      } catch (error) {
        console.log(error);
      }
    };
  };

3. 전체 결과 화면

영상으로 할 시에는 큰 차이가 없기 때문에 api가 잘 받아진 모습을 보여주도록 하겠다. 참고로 이미지는 s3 bucket에다 담기기 때문에 성공적으로 담긴 모습을 보여주고 있다.여러개의 이미지를 해도 잘 된다.


이렇게 Quill부분은 수정파트를 제외하고는 완료가 되었다. 처음에는 건들 부분이 없을 줄 알고 편하게 사용하려고 했었지만 toolbar를 custom하고 imagehandler를 작성하면서 마냥 편하게는 사용할 수 없었다. 그래도 완성된 모습을 보니 기분이 좋았다😆 이제 이 프로젝트의 끝이 오고 있기 때문에 다음에는 모달창 안에 또 다른 모달 띄우는 파트를 다루도록 하겠다. 그 다음은 프로젝트 카테고리에 넣지는 않겠지만 react query에 대해서도 포스팅 하도록 하겠다.

📚참고자료
이미지 리사이즈 부분 : https://r-0o0-j.tistory.com/160
이미지 핸들러 부분 : https://12ahn22.tistory.com/entry/Quill-에디터-이미지-처리하기

profile
예비 초보 개발자의 프로젝트와 공부 기록일지

0개의 댓글