[HTML] Canvas 2개로 레이어 기능 구현하기

배고픈메꾸리·2021년 8월 23일
2

HTML / CSS

목록 보기
3/15

방법만 보고 싶으면 해결방안으로!!

개요

교육지원금 서명 생성기를 만드는데 캔버스에 이미지를 삽입해서 입력받은 글자를 토대로 적절한 위치에 텍스트를 넣어주는 기능을 구현하고 있었다.

아직 미완성이지만 대략 설명하자면

이렇게 입력하면


요로코롬 나온다.

근데 만약 오기입한 경우나(제일 중요) 두번 클릭한 경우 하나의 캔버스에 두번 텍스트가 그려지고 결과적으로 캔버스가 더러워진다. (텍스트가 두꺼워지는건 덤)
이는 사용자 관점에서도 굉장히 좋지 않기 때문에 해결방안을 생각해보았다. canvas 태그는 찾아봐도 자료가 잘 안나와서 직접 해결해보기로 하였다.

글자가 써지는 곳부터 입력한 픽셀만큼의 캔버스를 clear 해주는 메서드가 있기는 한데 하나의 캔버스에 사진과 글자가 같이 있다보니 사진까지 지워지는 현상이 발생했다

해결방안

포토샵의 레이어기능이 바로 떠올랐다. 같은 크기의 캔버스 2개를 생성해서 position : absolute style 을 사용해서 두 개의 캔버스를 합친다.

<div style={{ position: 'relative', width: '1039px', height: '990px' }}>
        <canvas
          id="canvasTop"
          ref={canvasRef}
          width={1039}
          height={990}
        />
  
        <canvas
          id="canvasBottom"
          ref={canvasRefFont}
          width={1039}
          height={990}
        />
</div>

* ref 는 React의 useRef를 사용하기 위한 것이고 부모 태그의 relative는 부모div의 위치로 자식 캔버스들의 위치를 쉽게 조정하기 위해서 사용하였다.
#canvasBottom,
#canvasTop {
  position: absolute;
  top: 0;
  left: 0;
}

이렇게 분리되어있던 캔버스들이


하나로 합쳐진다.

번외 - 합쳐서 다운로드하기

 <canvas
    style={{ display: 'none' }}
    id="canvasSubmit"
    ref={canvasRefSubmit}
    width={1039}
    height={990}
/>

합치기 위한 캔버스를 하나 만든다

  function downloadCanvas() {
    canvas = canvasRef.current;
    canvasFont = canvasRefFont.current;
    canvasSubmit = canvasRefSubmit.current;
    ctx = canvas.getContext('2d')
    ctxFont = canvasFont.getContext('2d')
    ctxSubmit = canvasSubmit.getContext('2d')

    // 두 캔버스를 저장용 캔버스에 그린다 (먼저 그린쪽이 아래에 있는 레이어가 된다)
    ctxSubmit.drawImage(canvas, 0, 0);
    ctxSubmit.drawImage(canvasFont, 0, 0);
    
    //a태그를 만들고 다운로드한뒤 갖다 버린다
    let link = document.createElement('a');
    link.download = "sign.png";
    link.href = canvasSubmit.toDataURL();
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
  }

저장용 캔버스에 다 때려박고 저장!

성공적으로 저장된 모습 (14번의 시도는 덤)

profile
FE 개발자가 되자

0개의 댓글