[Dev Log] html-to-image, DOM 요소를 이미지로 저장하기

Alex J. Lee·2022년 2월 16일
2

Dev Log

목록 보기
1/2
post-thumbnail

WeGreen 프로젝트에 마이페이지에 있는 일러스트를 다운로드 받을 수 있는 기능을 추가하기로 했다. WeGreen 일러스트에 들어간 요소가 많고 복잡해서 제대로 각 SVG 이미지가 원하는 위치에서 캡쳐됐는지 확인할 수 있도록 좀 더 단순한 일러스트로 테스트용 웹앱을 만들었다.

Calm Scenery

SVG 일러스트를 바로 다운로드 할 수 없으니 일단 canvas로 변환한 뒤에 canvas를 다운로드해야겠다고 생각했다. 그래서 svg to canvas parser를 찾아보다가 전체 일러스트를 '스크린샷'한다가 원하는 기능에 더 적합한 것 같아서 검색어를 screenshot div로 바꾸었다. html2canvas가 검색 결과에 가장 많이 나와서 먼저 이 라이브러리로 시도해보았다.

아래는 html2canvas 라이브러리를 사용해 캡쳐할 DOM 요소(el)와 저장할 파일의 이름(filename)을 인자로 받아 캡쳐된 이미지를 PNG로 기기에 다운로드하는 함수다. 다운로드 버튼에 onClick 이벤트가 발생하면 해당 함수가 실행된다.

// ./utils/exportElementAsPNG

import html2canvas from 'html2canvas';

const exportElementAsPNG = (el, filename) => {
	html2canvas(el).then((canvas) => {
		const image = canvas.toDataURL('image/png', 1);
		const link = window.document.createElement('a');
		link.style = 'display:none;';
		link.download = filename + '.png';
		link.href = image;
		link.click();
	});
};

export default exportElementAsPNG;

이미지가 다운로드 되긴 했는데 문제가 있었다. 구름의 위치가 실제 화면에 보여지는것과 달랐다. 구름에 애니메이션이 적용되어 그런가 하고 애니메이션을 꺼 봤지만 그래도 위치가 다르게 나왔다. 왜 다른건 다 제자리에 있는데 구름만 위치가 틀리게 나온걸까? 구름과 다른 SVG 이미지의 다른 점은 구름에는 styled-components로 transform: translate 속성을 적용했다는 점이었다. 구글에 검색해보니 라이브러리 자체의 문제인 것 같았다. 해당 속성이 제대로 적용되지 않는 이슈가 있다는 글이 여럿 있었다. 그래서 다른 라이브러리를 찾아보았다.

html2canvas 대신 html-to-image를 사용할 것을 추천하는 블로그 글을 발견했다.

Here's Why I'm Replacing html2canvas With html-to-image in Our React App

요약하자면 html-to-image는 DOM 요소를 canvas가 아닌 이미지로 바로 전환하는 기능을 제공할 뿐 아니라 html2canvas보다 가볍고 빠르다는 글이었다.

CSS transform: translate이 제대로 적용되는지는 검색 결과만으로는 알 수 없어서 직접 시도해보기로 했다.

아래는 위의 exportElementAsPNG 함수를 html-to-image 라이브러리를 사용하도록 수정한 코드다.

import { toPng } from 'html-to-image';

const exportElementAsPNG = (el, filename) => {
  toPng(el).then((image) => {
    const link = window.document.createElement('a');
    link.style = 'display:none;';
    link.download = filename + '.png';
    link.href = image;
    link.click();
  });
};

export default exportElementAsPNG;

빙고! 이번에는 transform: translate이 제대로 적용된 이미지가 다운로드 되었다.


한줄요약

특정 DOM 요소를 캡쳐한 이미지 파일이 필요하다면 html-to-image 라이브러리를 추천한다. html2canvas는 svg에 적용된 transfrom: translate 속성을 인지하지 못하는 이슈가 있다.

profile
🦄✨글 잘 쓰는 개발자가 되기 위해 꾸준히 기록합니다 ✨🦄

0개의 댓글