블록 코딩 사이트를 만드는 팀 프로젝트를 진행하면서 blockly라는 블록 조립 라이브러리를 사용하게 되었다. 기획대로 UI를 수정하려고 보니 라이브러리의 많은 UI 요소들이 SVG로 만들어져 있었다. 이를 제대로 다루기 위해서는 SVG에 대한 이해가 선행되어야 된다고 생각했고 그래서 이 글에서 svg에 대해 알아보기로 했다.
**SVG(Scalable Vector Graphics)**는 이름에서 알 수 있듯이 벡터 기반의 그래픽 파일 포맷이다. **JPEG**와 같은 픽셀 기반의 래스터 파일과는 달리, SVG는 점과 선 등 기하학적 요소에 수학 공식을 적용해 이미지를 생성한다. 그래서 그래픽의 크기를 마음대로 조절해도 화질이 깨지지 않아 특히 아이콘이나 로고 같은 단순한 그래픽을 표현하는 데 매우 유용하다. 또한, SVG는 1999년 W3C에 채택된 이후 꾸준히 발전해와서 현재는 대부분의 모던 브라우저에서 지원된다.

작은 용량: 단순한 그래픽의 경우 래스터 이미지보다 파일 크기가 작다.
SEO 친화적: XML 코드로 작성되어 모양을 텍스트 정보로 저장하게 된다. 그래서 검색 엔진이 그래픽의 키워드(TEXT 태그 등)를 읽을 수 있다.
<svg width="300" height="200" xmlns="<http://www.w3.org/2000/svg>">
<rect width="100%" height="100%" fill="red" />
<circle cx="150" cy="100" r="80" fill="green" />
<text x="150" y="125" font-size="60" text-anchor="middle" fill="white">SVG</text>
</svg>
<aside> 👉
SVG의 xmlns 속성은 무엇일까?
xmlns는 XML Namespace를 정의하는 속성이다. 마크업 내의 내용을 어떤 규칙으로 해석해야 하는지 알려주는 용도다.
예를 들어, 서로 다른 XML 스키마를 병합할 때 같은 이름이 존재해 충돌이 발생할 수 있다. 이런 상황을 방지하기 위해 xmlns 속성에 namespace 값을 주어 이를 구분하는 것이다.
그러나 인라인 svg의 경우 웹 브라우저에서 렌더링을 할 때 xmlns과 version 옵션을 필요로 하지 않는다.
</aside>
SVG는 고품질 디지털 사진을 표현하기에는 적합하지 않다. 고품질 사진은 SVG로 만들면 용량이 어마어마하게 늘어나기 때문에 디테일이 많다면 JPEG를 사용하는 것이 좋다.
<aside> 🚨
잠깐! SVG 작성 시 주의할 점
SVG는 XML 코드로 작성되는데, XML의 경우 대소문자를 구분하기 때문에 요소를 작성할 때 대소문자 구분에 주의해야 한다. 또한, 속성 값은 반드시 따옴표로 둘러싸야 한다.
</aside>
Canvas and Viewport
Canvas는 svg 콘텐츠가 렌더링되는 공간이다. 그래서 공간 내에서 무한한 좌표를 사용할 수 있다. Viewport는 너비와 높이를 설정해 이 svg가 실제로 화면에 보여지는 공간을 의미한다.
<svg width="512" height="512">
...
</svg>
Viewbox
viewBox는 viewport 내에서 svg 요소의 크기를 확대/축소 또는 위치 변경을 할 수 있게 도와주는 속성이다. min-x min-y width height와 같은 형태로 값을 전달 받는다.
<svg width="100" height="100" viewBox="0 0 100 100" style="background-color: green">
<circle cx="50" cy="50" r="50" />
</svg>
사실 정확히 어떤 역할을 하는지 이해가 안 가서 직접 viewBox 값을 조절하며 테스트했다. viewBox 값을 아래와 같이 조절하면 처음에 그려졌던 도형을 svg 태그에 주었던 width="100" height="100"에 맞춰서 그린 후 viewport를 min-x min-y 으로 이동하고 width height로 사이즈를 변경하는 것 같다.

사각형, 원, 타원, 직선, 폴리라인, 다각형과 같은 기본 도형을 그릴 수 있다. 속성 값이 간단해서 금방 보고 따라 그릴 수 있다.
<svg>
<rect width="너비" height="높이" />
<circle cx="원의 중심 X 좌표" cy="원의 중심 Y 좌표" r="반지름" />
<ellipse cx="원의 중심 X 좌표" cy="원의 중심 Y 좌표" rx="X축 반지름" ry="Y축 반지름" />
<line x1="시작점" y1="시작점" x2="끝점" y2="끝점" />
<polyline points="x점,y점 x점,y점 x점,y점 x점,y점" />
<polygon points="x점,y점 x점,y점 x점,y점 x점,y점" />
</svg>