블록 코딩 사이트를 만드는 팀 프로젝트를 진행하면서 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>