빙고판을 이미지로 저장하는 기능을 추가했어요 [플랜 빙고 ver. 0.2.1]

Yoon Robin·2023년 7월 10일
0
post-thumbnail

프롤로그

때는 3월, 플랜 빙고를 막 배포했을 당시, 한 유저로부터 이런 피드백을 받았다.

나중에 이미지 저장 기능도 있으면 좋을 것 같아요...! 캡쳐도 되지만 이렇게 예쁜 디자인이 주소창이랑 찍히는게 아쉬워서요

유저의 피드백을 잘 기록해뒀다가 안 바쁜 시기인 7월에 드디어 빙고판을 이미지로 저장하는 기능을 만들었다!
(자축하는 의미로 박수👏👏👏)

⚠️ 다만 본격적인 포스팅에 앞서 미리 언급해야할 점이 있다.
Apple 기기에서는 이미지 다운로드 기능이 작동이 안 된다는 점이다. file-saver를 사용하면 해당 문제가 없어질 줄 알았는데, 이상하게도 해결할 수 없었다.

나는 현재 맥북이 없어서 Apple 기기와 관련된 에러를 확인할 방법이 없다. 그래서 이 버그는 추후에 기회가 되면 고치겠다. (이 점에 관해 아시는 분이 있다면 댓글 환영합니다.💚)

기능 구현 전 디자인 투표

기능을 구현하기 전 고민이 있었다. 이미지의 형태를 어떻게 할지 고민이었다.

그래서 트위터에 투표를 올렸다.

투표 결과 주변 여백이 보이게 이미지를 생성하는 것이 제일 많이 득표를 받았다. 나는 투표 결과대로 진행하기로 했다.

화면 캡처 및 이미지 저장 기능 추가

ℹ️ 기술 스택
React.js, Next.js, JavaScript

나는 이 기능을 추가하기 위해 html2canvasfile-saver를 사용했다.

html2canvas

html2canvas는 javascript 브라우저 화면 캡처 라이브러리이다.
이 라이브러리를 사용하면 캡처할 영역을 지정하고 해당 영역에 관한 스크린샷을 찍을 수 있다.

공식문서: https://html2canvas.hertzen.com/

특징

  • SVG 및 canvas 요소 등 다양한 요소에 확하여 캡처가 가능하다.
  • 비슷한 기능을 하는 라이브러리 중 압도적으로 가장 많이 사용되는 라이브러리이다.

html2canvas 설치 방법

npm install --save html2canvas
or
yarn add html2canvas

file-saver

file-saver는 클라이언트에서 파일 저장을 도와주는 라이브러리다.

공식 문서: https://www.npmjs.com/package/file-saver

설치 방법

npm install file-saver --save
or
yarn add file-saver

(추가로, 타입스크립트를 이용하는 경우에는 타입 정의도 다운로드 되어야 한다.)

# Additional typescript definitions 
npm install @types/file-saver --save-dev
or
yarn add @types/file-saver -D

지원되는 브라우저
https://www.npmjs.com/package/file-saver#supported-browsers

내가 html2canvas + file-saver 활용하여 기능을 구현한 방법

  1. useRefdiv태그를 사용하여 캡처하고 싶은 영역을 감싸주기.
    💚React에서는 DOM 요소를 다룰 때 일반적으로 useRef를 쓴다.
import { useRef } from "react";
const divRef = useRef(null);
        <div ref={divRef} className={styles.canvasDiv}>
          <ShareBoard
            bingoData={bingoData}
            main={data.main}
            title={data.title}
            value1={data.value1}
            value2={data.value2}
            value3={data.value3}
            value4={data.value4}
            value5={data.value5}
            value6={data.value6}
            value7={data.value7}
            value8={data.value8}
            value9={data.value9}
            bgColor={data.bgColor}
            cubeColor={data.cubeColor}
            bingoCount={data.bingoCount}
            patternArray={data.patternArray}
          />
        </div>
  1. 터미널에서 html2canvasfile-saver를 설치.

  2. import

import html2canvas from "html2canvas";
import saveAs from "file-saver";
  1. 버튼과 메서드 만들기
  • 버튼
          <button
            className={[btnStyles.button, styles.btnColor].join(" ")}
            onClick={downloadCanvasDiv}
          >
            <Image
              src={"/download.svg"}
              alt={"download an image"}
              width={30}
              height={30}
            />{" "}
            <p>이미지로 저장하기</p>
          </button>
  • downloadCanvasDiv
  const downloadCanvasDiv = async () => {
    const div = divRef.current;

    if (!div) {
      return;
    }

    try {
      const canvas = await html2canvas(div);

      canvas.toBlob((blob) => {
        if (blob != null) {
          saveAs(blob, `${data.title}.png`);
        }
      });
    } catch (error) {
      console.error("Error converting div to image:", error);
    }
  };

이렇게 특정 영역을 캡처하여 이미지로 저장하는 기능을 구현했다.
(아래는 이미지로 저장된 나의 플랜 빙고이다.)


마무리

오랜만에 플랜빙고에 기능을 추가해서 뿌듯했다.
다만 Apple 기기에서는 작동이 안 된다는 점이 매우 아쉽다.
언젠가 꼭 고치겠어!


참고 자료
[React] 화면(DOM) 캡쳐 및 저장 기능 구현하기 (feat. html2canvas, file-saver)

profile
신입 프론트엔드 개발자

0개의 댓글