[React] 서명패드 만들기
본문 바로가기
더 알아보기/기능

[React] 서명패드 만들기

by 은돌1113 2022. 7. 22.
 

리액트에서 signature-pad로 서명하기, react-signature-canvas에 placeholder 넣기

 회사에서 설문 제작 시 선택할 수 있는 새로운 문항 종류로 `서명 입력`을 받을 수 있는 모듈을 구현하게 됐다. 서명 입력 받는 라이브러리 중 가장 대표적으로 사용되고 있는 signature-pad를 리액

jiyoon-park.tistory.com

 

REACT에서 서명 패드를 만드는 방법 - 블로그

개발자가 버그 및 문제에 대한 주제를 토론하고 지식을 작성 및 공유하며 전 세계 수백만 개발자와 연결할 수 있는 소셜 네트워크입니다.

ko.quish.tv


 

reactjs-popup

React Popup Component - Modals,Tooltips and Menus —  All in one. Latest version: 2.0.5, last published: a year ago. Start using reactjs-popup in your project by running `npm i reactjs-popup`. There are 119 other projects in the npm registry using rea

www.npmjs.com

 

react-signature-canvas

A React wrapper component around signature_pad. Unopinionated and heavily updated fork of react-signature-pad. Latest version: 1.0.6, last published: a month ago. Start using react-signature-canvas in your project by running `npm i react-signature-canvas`.

www.npmjs.com


현재 진행 중인 프로젝트에 추후 추가 해야 하는 기능애 대한 테스트 코드이기 때문에 자세한 설명은 나중에 ✌️😎✌️

 

서명패트.. 결과물? ㅎㅎㅎㅎㅎㅎ


SignPad.js

import { useState, useRef } from "react";

import Popup from "reactjs-popup";
// 출처 : https://www.npmjs.com/package/reactjs-popup
import SignaturePad from "react-signature-canvas";
// 출처 : https://www.npmjs.com/package/react-signature-canvas

/*
  [코드 출처]
   - https://jiyoon-park.tistory.com/entry/%EB%A6%AC%EC%95%A1%ED%8A%B8%EC%97%90%EC%84%9C-signature-pad%EB%A1%9C-%EC%84%9C%EB%AA%85%ED%95%98%EA%B8%B0-react-signature-canvas%EC%97%90-placeholder-%EB%84%A3%EA%B8%B0
   - https://ko.quish.tv/how-create-signature-pad-react
 */

//? react-signature-canvas 라이브러리에 CSS를 변경 할 때는 styled 라이브러리를 사용하지 못합니다.
//? 이유는 모르겠지만 적용이 안되서 /styles/signaturePad.css에 커스텀 했습니다.

const SignPad = () => {
  const [imageURL, setImageURL] = useState([]); // 이미지를 하나만 저장하고 싶은 경우 []을 null로 바꾸면 됩니다.
  const [isSigned, setIsSigned] = useState(false);

  const sigCanvas = useRef({});

  // 초기화
  const clear = () => {
    sigCanvas.current.clear();
    setIsSigned(false);
  };

  // 저장
  const save = () => {
    setImageURL([
      ...imageURL,
      sigCanvas.current.getTrimmedCanvas().toDataURL("image/png"),
    ]);
    clear();
  };

  return (
    <>
      <Popup modal trigger={<button>열기</button>} closeOnDocumentClick={false}>
        {(close) => (
          <div className="canvasWrapper">
            {!isSigned && (
              <div className="canvasPlaceholder">여기에 서명을 해주세요.</div>
            )}
            <SignaturePad
              ref={sigCanvas}
              canvasProps={{ className: "signatureCanvas" }}
              onBegin={() => {
                setIsSigned(true);
              }}
            />
            <button disabled={!isSigned} onClick={save}>
              저장
            </button>
            <button onClick={clear}>초기화</button>
            <button onClick={close}>닫기</button>
          </div>
        )}
      </Popup>
      <br />
      <br />
      <section className="signatures">
        {imageURL ? (
          <>
            {imageURL.map((item, i) => {
              return (
                <img
                  key={i}
                  className="signatureImage"
                  src={item}
                  alt="my signature"
                />
              );
            })}
          </>
        ) : null}
      </section>
    </>
  );
};

export default SignPad;

signPad.css

.signatureCanvas {
  width: 100%;
  height: 100%;
  background: #eeeeee;
  border: 1px solid #e1e1e1;
  aspect-ratio: auto;
}

.signatures {
  width: 1000px;
  display: grid;
  grid-template-columns: 300px 300px 300px;
  grid-template-rows: 200px 200px;
}
/* 줄바꿈 후 왼쪽 정렬 > 출처 : https://nykim.work/59 */

.canvasWrapper {
  display: relative;
  width: 600px;
  height: 400px;
}

.canvasPlaceholder {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  color: black;
}

.signatureImage {
  display: block;
  margin: 0 auto;
  border: 1px solid black;
  width: 300px;
  height: 200px;
  background: #eeeeee;
}

댓글