react quill 이미지 드롭

안녕하세요·2024년 5월 27일
0

react

목록 보기
29/32

Quill 에디터에서 이미지 드롭 및 복사 붙여넣기 기능을 구현하기 위해 quill-image-drop-and-paste 라이브러리를 사용하였는데, 기존 이미지 처리 함수는 제대로 작동하지 않았습니다.

기존코드

  const insertImage = async (file) => {
    try {
      const IMG_URL = await imageUpload(file);
      const editor = quillRef.current.getEditor();
      const range = editor.getSelection();
      editor.insertEmbed(range.index, 'image', `${process.env.REACT_APP_SERVER_URL}${IMG_URL}`);
    } catch (error) {
      console.error('Image upload failed:', error);
    }
  };

  const imageHandler = () => {
    const input = document.createElement('input');
    input.setAttribute('type', 'file');
    input.setAttribute('accept', 'image/*');
    input.click();

    input.addEventListener('change', async () => {
      const file = input.files[0];
      await insertImage(file);
    });
  };
  
  
  const modules = useMemo(() => ({
    toolbar: {
      container: [
        ['bold', 'italic', 'underline', 'strike'],
        ['blockquote', 'code-block'],
        [{ 'header': 1 }, { 'header': 2 }],
        [{ 'list': 'ordered' }, { 'list': 'bullet' }],
        [{ 'script': 'sub' }, { 'script': 'super' }],
        [{ 'indent': '-1' }, { 'indent': '+1' }],
        [{ 'direction': 'rtl' }],
        [{ 'size': ['small', false, 'large', 'huge'] }],
        [{ 'header': [1, 2, 3, 4, 5, 6, false] }],
        [{ 'color': [] }, { 'background': [] }],
        [{ 'font': [] }],
        [{ 'align': [] }],
        ['image', 'video', 'link', 'clean']
      ],
      handlers: { image: imageHandler },
    },
    imageDropAndPaste: { handler: imageHandler },
    imageResize: {
      parchment: Quill.import('parchment'),
      modules: ['Resize', 'DisplaySize'],
    },
  }), []);

문제의 원인

imageHandler

툴바 버튼을 클릭하여 이미지를 업로드하고 삽입하는 기능입니다. 사용자가 파일 선택 창을 통해 파일을 선택하면 이를 업로드하고 에디터에 삽입합니다.

imageDropAndPaste

이미지를 드래그 앤 드롭하거나 클립보드에서 이미지를 붙여넣을 때 호출됩니다. 이 경우 데이터 URL 형식으로 이미지를 처리해야 합니다.

해결 방법

각 상황에 맞는 핸들러를 구현하여 문제를 해결할 수 있습니다. 이를 위해 드래그 앤 드롭 및 복사 붙여넣기 기능을 처리하는 핸들러를 추가합니다.

  const imageHandler = () => {
    const input = document.createElement('input');
    input.setAttribute('type', 'file');
    input.setAttribute('accept', 'image/*');
    input.click();

    input.addEventListener('change', async () => {
      const file = input.files[0];
      await insertImage(file);
    });
  };

  const handleDropAndPaste = async (dataUrl, type) => {
    if (type.includes('image')) {
      try {
        const blob = await fetch(dataUrl).then(res => res.blob());
        const file = new File([blob], 'image.png', { type: 'image/png' });
        await insertImage(file);
      } catch (error) {
        console.error('Image upload failed:', error);
      }
    }
  };
  
   const modules = useMemo(() => ({
    toolbar: {
      container: [
        ['bold', 'italic', 'underline', 'strike'],
        ['blockquote', 'code-block'],
        [{ 'header': 1 }, { 'header': 2 }],
        [{ 'list': 'ordered' }, { 'list': 'bullet' }],
        [{ 'script': 'sub' }, { 'script': 'super' }],
        [{ 'indent': '-1' }, { 'indent': '+1' }],
        [{ 'direction': 'rtl' }],
        [{ 'size': ['small', false, 'large', 'huge'] }],
        [{ 'header': [1, 2, 3, 4, 5, 6, false] }],
        [{ 'color': [] }, { 'background': [] }],
        [{ 'font': [] }],
        [{ 'align': [] }],
        ['image', 'video', 'link', 'clean']
      ],
      handlers: { image: imageHandler },
    },
    imageDropAndPaste: { handler: handleDropAndPaste },
    imageResize: {
      parchment: Quill.import('parchment'),
      modules: ['Resize', 'DisplaySize'],
    },
  }), []);

0개의 댓글