-
이미지 원하는 만큼 자르기 + 코드 이미지로 만들기Front-end/Javascript 2024. 9. 6. 09:45반응형
정해진 이미지 위에 코드를 이용해서 그래프를 만들고, 클릭하면 전체화면으로 볼 수 있도록 만들어야 했다.
이 때 필요한 것이 clipping, 그리고 DOM node를 이미지화 시키는 것이다.
1. 이미지 위에 그래프 그리기
웹 디자이너가 없는 상황에서 포토샵으로 이미지를 만들어주면 그 위에 코드로 그래프를 그려야하는 일이 생겼다.
숫자나 문자 같은 경우에는 위치만 잡아서 올리면 되지만 그래프나 수분량을 나타내는 경우 수분량에 따라서 신체에 수분이 차오르는 정도를 표현해야했다.
내가 생각한 방법은 모든 그래프를 꽉차 있는 상태의 이미지로 받아서 그 위에 사용자의 정보에 따라 계산을 해서 바탕색을 채우는 방식으로 진행했다.
2. 사용자의 수분량에 따라 신체 이미지에서 수분량 나타내기
백오피스에서 내부적으로 상담을 위해 사용하는 툴이다 보니 전체적인 이미지 공개는 어렵지만 신체모양은 아래와 같다.
이런 식으로 수분량에 따라서 색상이 아래에서 위로 차오르는 모습을 보여주는 것이 목표이다.
이를 위해서 clip-path를 사용했다.
clip-path는 어렵지 않게 내가 원하는 모양을 만들어낼 수 있기에 프론트엔드 개발자라면 경험해봤을 수 있을 것이다.
문제는 이미지화 시키는데 있었다.
3. 코드를 이미지화 시키기
클릭하면 전체화면으로 보여줘야한다.
그러나 모든 것들은 코드로 이루어져 있기에 javascript를 screenshot 찍어서 일시적으로 이미지화 시켜야한다고 생각했다.
그래서 canvas를 이용해서 만들자! 라고 생각하고 검색을 해봤는데 html2canvas라는 것이 있었다.
애초에 canvas로 만들어야겠다 라고 생각했기에 딱 적당하다고 생각하여 문서를 보고 만들었는데 굉장히 쉬웠다.
3-1. HTML2CANVAS
이름 그대로 DOM을 기반으로 하며 실제 스크린샷을 만드는게 아니라 HTML 문서를 캡처하여 canvas요소로 변환하는 라이브러리이다.
이미지화 시키는 것 뿐 아니라 PDF로 파일을 변환시키는 등 다양하게 사용할 수 있다.
React 혹은 Next.JS를 사용하고 있다면 useRef를 이용해서 DOM 요소를 가져오고, 데이터 URL 형식으로 만들 수 있는데 이를 state에 저장하던 즉시 사용하면서 원하는대로 구현이 가능하다.
모든 것이 완벽해 보였건만... 딱 하나 문제가 있었다.
신체모양의 수분량 즉, clip-path가 적용이 되지 않았고, 아마 html2canvas에서 clip-path css를 지원하지 않는 듯 했다.
stack overflow에도 3년 전에 같은 질문이 올라와 있었는데 그 답변에는 Using dom-to-image works for me 였다.
새로운 라이브러리로 바꿔야한다...
3-2. DOM to Image
이 또한 html2canvas와 크게 다르진 않았다.
DOM node를 Javascript로 작성된 svg, png, jpeg 이미지로 변환 시킬 수 있는 라이브러리이다.
비동기 방식으로 동작하여 성능에 미치는 영향이 적고, html2canvas보다 더 다양한 css 스타일이 적용된다.
그리고 나의 경우 이미지를 클릭했을 때 전체 화면으로 나오도록 해야하는데 그럴려면 가능한 화질이 좋은 svg로 뽑고 싶었다.
html2canvas의 경우 지원하지 않았지만 dom-to-image는 SVG 포맷을 지원한다는 장점이 있었고, 필터링도 되는 등 커스터마이징이 가능했다.
그리고 clip-path 역시 사용이 가능했다!
4. 이미지를 자르는 방법은 clip-path 밖에 없을까?
내가 사용하진 않았지만 사용할 뻔 했던 방법은 바로 svg 이미지 마스크를 사용하는 것이었다.
만약 dom-to-image 라이브러리를 찾지 못했다면 clip-path가 html2canvas에 적용되지 않으니 SVG 이미지 마스크로 사용하는 방법을 택했을 것이다.
프론트엔드 개발에서 해상도 신경을 많이 쓰게 되는데 모니터 사이즈가 아닌 TV 사이즈에서 꽉 찬 화면으로 깨끗하게 보려고 한다면 아무래도 SVG를 고려하지 않을 수 없을 것이다.
5. SVG mask
SVG 마스크는 HTML 요소나 이미지를 특정 모양으로 잘라내는데 사용된다. 즉, clip-path처럼 사용할 수 있는 것이다.
SVG 마스크는 svg 태그 안에서 <mask> 태그를 사요하게 되는데 주로 이미지, 텍스트, HTML element 등에 적용할 수 있다.
예시를 보면 아래와 같다.
<svg width="500" height="500"> <mask id="rectMask"> <!-- 흰색 부분은 보이고, 검은색 부분은 가려짐 --> <rect x="10" y="10" width="100" height="100" fill="white" /> <rect x="110" y="10" width="100" height="100" fill="black" /> </mask> </svg> <!-- 마스크를 적용할 이미지 --> <img src="your-image.jpg" style="width: 200px; height: 200px; mask: url(#rectMask);">
중요한건 mask id를 지정해주고 img 태그에 url(#[id])를 넣어주면 된다.
그러면 내가 원하는 만큼 자르는 용도로 사용할 수 있다.
추가적으로 필요한 svg가 있다면 svgrepo.com에서 사용하면 다양한 것들을 구할 수 있다.
반응형'Front-end > Javascript' 카테고리의 다른 글
Web worker(웹워커)에 대해서 알아보자 (0) 2023.08.14 uuid 설치 없이 unique ID 만들기 (crypto.randomUUID) (0) 2023.02.05 [json-server] 프론트엔드 연습용 백엔드 데이터가 필요하다면! (0) 2021.10.04 ES6에 추가 된 Map 객체 (0) 2021.09.26 자바스크립트 원시 값(Primitives values) : index[ ]로 string을 바꿀 수 없다! (0) 2021.07.21