진행 중인 회사 프로젝트에서 서명을 그리는 기능을 넣기로 했다.
어떻게 구현을 할 수 있을까 생각하던 중, javascript + canvas로 그림판을 만드는 내용의 노마드코더의 강의가 생각이 나서 해당 강의를 먼저 들었다.
강의에서 본 내용으로 구현을 하던 중, react 라이브러리 중에 react-signature-canvas라는 것을 우연히 알게 되었고, 바로 써먹었다.
간단해서 써먹기 매우 편했다. (React + Typescript)
1) 라이브러리 설치
npm install react-signature-canvas
2) types 설치 (typescript 사용 시)
npm install -D @types/react-signature-canvas
아래 구조로 파일 및 디렉토리 생성한다.
// App.tsx
import React, { useRef } from 'react';
import SignatureCanvas from 'react-signature-canvas'; // 라이브러리 import
import './Styles/style.css';
function App(): JSX.Element {
// useRef로 DOM에 접근 (SignatureCanvas 라는 캔버스 태그에 접근)
const signCanvas = useRef() as React.MutableRefObject<any>;
return (
<>
<div className="container">
<div className="canvasContainer">
<SignatureCanvas // canvas element
ref={signCanvas}
canvasProps={{ className: 'sigCanvas canvasStyle' }}
backgroundColor="rgb(230, 230, 230)"
/>
</div>
<button>clear</button>
<button>save</button>
</div>
</>
);
}
export default App;
(참고) SignatureCanvas 태그의 props로 설정 값을 넣을 수 있다. (npm react-signature-canvas)
Style 작성
.canvasContainer 가 canvas 태그를 감싸고 있고,
.canvasStyle 가 canvas 태그를 가리키고 있는데 너비,높이가 부모의 넓이를 따라가도록 했다.
// style.css
.container {
width: 500px;
height: 500px;
border: 3px solid #000;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.canvasContainer {
width: 70%;
height: 70%;
}
.canvasStyle {
width: 100%;
height: 100%;
}
button {
display: flex;
margin-top: 20px;
width: 80px;
height: 30px;
justify-content: center;
align-items: center;
}
결과는 다음 화면과 같다. (서명은 내가 그냥 그린거)
react-signature-canvas 라이브러리의 API를 사용한다.
clear 함수를 App 컴포넌트 안에 선언한다.
const clear = () => {
signCanvas.current.clear(); // clear() 사용해서 캔버스 clear
};
save 함수를 App 컴포넌트 안에 선언한다
const save = () => {
const image = signCanvas.current.getTrimmedCanvas().toDataURL('image/png'); // image 변수에 이미지 다운로드 링크 할당, png를 jpg등의 다른 확장자로 변경 가능
const link = document.createElement('a'); // 다운로드 구현을 위한 임의의 a 태그 생성
link.href = image; // a 태그의 href 속성으로 이미지 다운로드 링크
link.download = 'sign_image.png'; // 다운로드 파일의 기본 이름 설정
link.click(); // 임의의 a 태그를 클릭하여 다운로드 실행
};
완성된 App.tsx 코드이다.
import React, { useRef } from 'react';
import SignatureCanvas from 'react-signature-canvas'; // 라이브러리 import
import './Styles/style.css';
function App(): JSX.Element {
// useRef로 DOM에 접근 (SignatureCanvas 라는 캔버스 태그에 접근)
const signCanvas = useRef() as React.MutableRefObject<any>;
// 캔버스 지우기
const clear = () => {
signCanvas.current.clear();
};
// 이미지 저장
const save = () => {
const image = signCanvas.current.getTrimmedCanvas().toDataURL('image/png');
const link = document.createElement('a');
link.href = image;
link.download = 'sign_image.png';
link.click();
};
return (
<>
<div className="container">
<div className="canvasContainer">
<SignatureCanvas // canvas element
ref={signCanvas}
canvasProps={{ className: 'sigCanvas canvasStyle' }}
backgroundColor="rgb(230, 230, 230)"
/>
</div>
<button onClick={clear}>clear</button>
<button onClick={save}>save</button>
</div>
</>
);
}
export default App;
clear 및 save가 작동하는 것을 확인한다.
매우 기본적인 기능만 살펴봤다.
공식 문서에 여러 기능들이 있을테니 참고 (npm react-signature-canvas)