최근 작업 중인 프로젝트에서 SVG를 조작하고 사용할 일이 있는데, 아직 SVG에 대해 자세히 알지 못하는 부분들이 있다보니 꽤 어려움을 겪었던 내용이 있었다. 그래서 이번 기회에 SVG에 대해서 자세히 알아보면서 내용을 정리해두고자 한다.
1. SVG란
SVG를 그 전에도 많이 접하고 직접 많이 만들기도 했었는데, 정확한 용어의 정의는 이번에 알게 되었다. SVG는 Scalable Vector Graphic의 약자로, '크기 조작이 가능한 벡터 그래픽'이라는 의미이다. 말 그대로 벡터 그래픽이기 때문에 확대하거나 축소해도 래스터화(Rasterized) 된 비트맵(Bitmap) 이미지와 달리 계단 현상(Aliasing) 문제가 생기지 않는데, 그래픽 자산 자체가 선과 색상 정보 등을 좌표와 코드로 가지고 있다가 렌더링하는 방식이기 때문에 표시되는 크기에 맞춰 조정되기 때문이다. 때문에 너무 복잡한 이미지의 경우에는 렌더링에 많은 계산이 요구되어 오히려 비효율적인 문제가 있다.
사이즈 조정이 가능하고 깔끔하다는 점 때문에 좋게만 여겨질 수 있지만 사실 좀 활용이 어려운 경우가 많은 것이, 렌더링 결과물이 보장되지 않는다는 점 때문이다. 기기 환경이나 소프트웨어에 따라 지원하는 코드나 방식이 달라지기 때문인데 특히 그라데이션이나 마스킹과 같은 특수한 처리가 필요할 때 의도와 다르게 출력되는 경우가 많다. 해상도가 높은 환경, 그리고 해상도 변화가 많은 모바일 UI 등이 도입되면서부터 SVG의 중요도와 인지도가 높아지기 시작했지만, 이미지 산출물로서 다루는 경우가 대부분이라 그 편집에 있어서는 접할 수 있는 정보가 아주 많지는 않다.
2. 주요 문법
SVG는 기본적으로 XML 문법을 따르는데, 최상단에 SVG를 선언하며 시작하는 태그는 아래와 같다.
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
</svg>
주의할 점은 xmlns라는 속성이 꼭 들어가야 한다는 점인데, 처음에는 이 부분이 불필요한 속성인줄 알고 삭제했다가 SVG로 인식되지 않아 당황했던 기억이 있다. 네임스페이스(Namespace)라는 속성으로 이 문서의 유효성 검사를 위한 부분인데, HTML 등에서는 빠져있어도 아래의 내용으로 자동으로 인식되고 있는 것이지만 SVG의 경우 생략하면 안 된다.
<html xmlns="http://www.w3.org/1999/xhtml">
</html>
그 다음으로 주요하게 살펴볼만한 것이 viewBox라는 속성인데, 이 또한 처음 접할 때 개념의 혼동이 있어서 조금 어려웠다. viewBox는 SVG 전체의 크기와 위치를 결정하는데, 네 가지 숫자가 각각 min-x, min-y, width, height를 의미한다. 즉 0 0 100 100 이라는 viewBox는 (0,0)으로부터 시작하는 100*100 크기의 view를 의미한다. 그런데 이 width / height는 상대적인 크기로 이해하는 것이 좋은데, SVG는 서두에 이야기했듯이 Scalable하기 때문에 특별히 정해진 크기란 없기 때문이다. width와 height는 크기이기 때문에, 음수는 적용할 수 없다.
위의 <svg> 태그 및 속성 정의를 통해 전체적인 내용이 정의되면, 태그 내부에 하위요소들을 넣으며 그래픽을 정의할 수 있다. 주요 구성요소들은 아래와 같다.
- path
- symbol
- image
- view
- pattern
- marker
- text
- rect
- circle
- ellipse
- polygon
- line
- defs
- g
- mask
- linearGradient
- radialGradient
위의 요소들은 아래와 같이 적용하여 사용한다.
<svg viewBox="-10 -10 120 120">
<rect x="-10" y="-10" width="120" height="120" fill="blue" />
<mask id="myMask">
<!-- Everything under a white pixel will be visible -->
<rect x="0" y="0" width="100" height="100" fill="white" />
<!-- Everything under a black pixel will be invisible -->
<path
d="M10,35 A20,20,0,0,1,50,35 A20,20,0,0,1,90,35 Q90,65,50,95 Q10,65,10,35 Z"
fill="black" />
</mask>
<polygon points="-10,110 110,110 110,-10" fill="orange" />
<!-- with this mask applied, we "punch" a heart shape hole into the circle -->
<circle cx="50" cy="50" r="50" fill="purple" mask="url(#myMask)" />
</svg>
위의 코드를 적용하면 아래와 같이 표시된다.
각 주요 요소들에 대해서도 다뤄보면서 SVG를 전반적으로 이해해보고자 한다. 최근의 프로젝트에서 많이 접하고 있는 것은 <text>와 <path>, <g> 요소인데, 이해가 된 듯하면서도 렌더링 결과는 다른 경우가 많아 한번 정리해볼 필요가 있다고 본다. 특히 mask와 gradient 등 기존에 여러 차례 문제를 겪으며 골머리를 앓았던 사례들이 있는데, 정리해보면서 무엇이 문제였는지도 되짚어보면 좋을 것 같다.
'ETC' 카테고리의 다른 글
[Canvas] Canvas API에 대해 알아보자. (0) | 2024.11.27 |
---|