[javascript] Draft.js를 이용한 텍스트 에디터의 스케치(Sketch) 기능 구현하기

이번 포스트에서는 Draft.js를 사용하여 텍스트 에디터에 스케치 기능을 구현하는 방법을 알아보겠습니다. 스케치 기능은 사용자가 마우스 또는 터치를 이용하여 자유롭게 그림을 그릴 수 있는 기능을 말합니다.

Draft.js란?

Draft.js는 Facebook에서 개발한 React 기반의 웹 텍스트 편집기 라이브러리입니다. Rich Text Editor를 구현하기 위한 다양한 기능과 커스터마이징이 가능하다는 장점을 가지고 있습니다.

스케치 기능 구현하기

  1. 프로젝트 설정 및 Draft.js 설치

먼저 프로젝트를 생성하고 Draft.js를 설치합니다. 다음 명령어를 터미널에서 실행하세요.

npm create-react-app sketch-app
cd sketch-app
npm install draft-js
  1. 에디터 컴포넌트 생성

‘Editor’라는 이름의 컴포넌트를 생성하여 텍스트 에디터를 구현합니다. 필요한 패키지를 임포트하고, Draft.js의 Editor 컴포넌트를 래핑하여 기본 에디터를 생성합니다. 코드는 다음과 같습니다.

import React, { useState } from 'react';
import { Editor, EditorState, RichUtils } from 'draft-js';

const CustomEditor = () => {
  const [editorState, setEditorState] = useState(EditorState.createEmpty());

  const onChange = (newEditorState) => {
    setEditorState(newEditorState);
  };

  const handleKeyCommand = (command) => {
    const newState = RichUtils.handleKeyCommand(editorState, command);
    if (newState) {
      onChange(newState);
      return 'handled';
    }
    return 'not-handled';
  };

  return (
    <div>
      <Editor
        editorState={editorState}
        onChange={onChange}
        handleKeyCommand={handleKeyCommand}
      />
    </div>
  );
};

export default CustomEditor;
  1. 스케치 기능 추가하기

이제 스케치 기능을 추가해보겠습니다. 마우스 이벤트를 이용하여 원하는 위치에 마우스를 클릭하고 드래그하면 그림을 그릴 수 있도록 작업을 해보겠습니다. 코드는 다음과 같습니다.

import React, { useState, useRef, useEffect } from 'react';
import { Editor, EditorState, RichUtils, Modifier } from 'draft-js';

const CustomEditor = () => {
  const [editorState, setEditorState] = useState(EditorState.createEmpty());
  const [isDrawing, setIsDrawing] = useState(false);
  const canvasRef = useRef(null);

  useEffect(() => {
    const canvas = canvasRef.current;
    const context = canvas.getContext('2d');

    const handleMouseDown = (event) => {
      setIsDrawing(true);
    };

    const handleMouseMove = (event) => {
      if (!isDrawing) return;

      const { offsetX, offsetY } = event.nativeEvent;
      context.lineTo(offsetX, offsetY);
      context.stroke();
    };

    const handleMouseUp = () => {
      setIsDrawing(false);
    };

    const handleMouseLeave = () => {
      setIsDrawing(false);
    };

    context.strokeStyle = 'black';
    context.lineWidth = 2;
    context.lineCap = 'round';
    context.lineJoin = 'round';

    canvas.addEventListener('mousedown', handleMouseDown);
    canvas.addEventListener('mousemove', handleMouseMove);
    canvas.addEventListener('mouseup', handleMouseUp);
    canvas.addEventListener('mouseleave', handleMouseLeave);

    return () => {
      canvas.removeEventListener('mousedown', handleMouseDown);
      canvas.removeEventListener('mousemove', handleMouseMove);
      canvas.removeEventListener('mouseup', handleMouseUp);
      canvas.removeEventListener('mouseleave', handleMouseLeave);
    };
  }, [isDrawing]);

  const onChange = (newEditorState) => {
    setEditorState(newEditorState);
  };

  const handleKeyCommand = (command) => {
    const newState = RichUtils.handleKeyCommand(editorState, command);
    if (newState) {
      onChange(newState);
      return 'handled';
    }
    return 'not-handled';
  };

  const handleSketchButtonClick = () => {
    // 에디터에서 스케치 모드로 전환
    const contentState = Modifier.setBlockType(
      editorState.getCurrentContent(),
      editorState.getSelection(),
      'unstyled'
    );
    onChange(EditorState.push(editorState, contentState, 'change-block-type'));
  };

  return (
    <div>
      <button onClick={handleSketchButtonClick}>스케치</button>
      <Editor
        editorState={editorState}
        onChange={onChange}
        handleKeyCommand={handleKeyCommand}
      />
      <canvas ref={canvasRef} width="600" height="300" />
    </div>
  );
};

export default CustomEditor;
  1. 사용하기

컴포넌트를 사용하여 텍스트 에디터를 만들고, 스케치 기능을 테스트해보세요.

import React from 'react';
import CustomEditor from './CustomEditor';

const App = () => {
  return (
    <div>
      <h1>스케치 에디터</h1>
      <CustomEditor />
    </div>
  );
};

export default App;

위의 코드를 사용하여 에디터를 렌더링하고 실행해보세요. ‘스케치’ 버튼을 클릭하고 마우스로 그림을 그려보면 텍스트 에디터에 스케치 기능이 구현된 것을 확인할 수 있습니다.

마무리

이번 포스트에서는 Draft.js를 사용하여 텍스트 에디터에 스케치 기능을 구현하는 방법을 알아보았습니다. 스케치 기능은 사용자가 마우스 또는 터치를 이용하여 자유롭게 그림을 그릴 수 있는 기능으로, 다양한 용도로 활용할 수 있습니다.