Logo

SVG로 HTML 문서에 그림 그리기

웹에서 SVG가 사용되기 시작한지가 꽤 되어 가는 것 같죠? 개발자로서 주로 이미 만들어진 SVG 코드를 복사해서 붙여넣기만 하지 제대로 SVG에 대해서 깊이 알아볼 기회는 많지 않은 것 같습니다.

이번 포스팅에서는 HTML 문서 안에 SVG로 직접 간단한 그림을 그려보면서 그려보면서 전반적으로 SVG를 어떻게 사용하는지 가볍게 알아보겠습니다.

SVG 란?

SVG(Scalable Vector Graphics)는 HTML 문서에 백터(vector) 기반 그래픽을 그리기 위해서 사용되는 XML 기반 웹 기술입니다. 백터 기반 그래픽은 아무리 확대하더라도 기존에 많이 사용되던 래스터(raster)/비트맵(bitmap) 기반 그래픽처럼 계단 현상이 발생하지 않기 때문에 요즘과 같이 다양한 크기의 화면을 지원해야하는 상황에서 큰 이점이 있습니다.

HTML이 제목(h1/h2/…), 단락(p), 목록(ul/ol), 표(table)과 같은 어떤 문서를 이루는 요소를 마크업하기 위해서 사용된다라고 하면, SVG는 점, 직선, 곡선, 원, 사각형, 다각형 등과 같은 하나의 그래픽 영역을 이루는 요소를 마크업하기 위해서 사용된다고 생각하시면 이해가 쉬우실 것입니다.

SVG 그래픽은 HTML 문서 안에 다른 HTML 요소처럼 바로 마크업이 가능하며 외부 파일에 작성하여 <object>, <img>, <iframe> 요소를 통해서 불러올 수 있는데요. 본 포스팅에서는 HTML 문서 안에 SVG 코드를 직접 작성하는 방식으로 진행해보도록 하겠습니다.

svg 요소

SVG 스팩에서 최상위 요소인 <svg>는 그래픽 영역을 전체를 마크업하기 위해서 사용합니다.

SVG 그래픽은 기본적으로 무한대의 캔버스(canvas)에 그려진다고 생각하면 좋은데요. 따라서 HTML 문서에 삽입할 때는 이 무한의 캔버스에서 정확히 어디를 얼마 만큼을 보여줄지를 설정해줘야 합니다. (참고로 이 캔버스 좌표계에서는 x 좌표가 커질수록 오른쪽 방향으로, y 좌표가 커질수록 아래쪽 방향으로 위치가 이동하게 됩니다.)

viewBox 속성은 이 캔버스를 들여다 볼 창문의 위치와 크기를 결정하는데요. 속성값을 창문의 좌측 상단 x 좌표와 y 좌표, 너비, 높이 순으로 띄어쓰기하여 나열합니다. 대부분의 경우에는 시작 xy 좌표는 0 0으로 잡고, 너비와 높이를 내부에 그릴 도형의 크기를 고려하여 결정합니다.

그래픽 영역이 HTML 문서 상에서 실제로 얼마만큼의 크기로 나타낼지는 widthheight 속성을 통해 제어하는데요. viewBox 속성과 width, height 속성 함계 잘 사용하면 그래픽을 축소하거나 확대하는 효과를 얻을 수 있습니다.

예를 들어, 다음과 같이 viewBoxwidth, height 속성을 동일하게 맞춰주면 그래픽이 본래 크기대로 표시됩니다.

<svg viewBox="0 0 300 300" width="300" height="300"><!-- 1x --></svg>

하지만 width, height 속성을 viewBox의 절반으로 설정해주면 2배 축소된 효과가 납니다.

<svg viewBox="0 0 300 300" width="150" height="150"><!-- 0.5x --></svg>

반면에 width, height 속성을 viewBox의 두배로 설정해주면 2배 확대된 효과가 납니다.

<svg viewBox="0 0 300 300" width="600" height="600"><!-- 2x --></svg>

이렇게 자유롭게 그래픽을 축소하고 확대할 수 있다는 것이 웹에서 SVG와 같은 백터 그래픽을 사용할 때 가장 큰 장점으로 여겨집니다.

공통 속성

어떤 도형을 그리던지 면색, 선색, 선두께 등 공통적으로 지정해줘야하는 부분이 있는데요. 이러한 공통 속성은 최상위 요소인 <svg>에서 일괄 지정이 가능하며, 하위 도형 요소에서 개별적으로 덮어쓰기도 가능합니다.

대표적인 공통 속성으로는 면색을 지정하는 fill 속성, 선색을 지정하는 stroke 속성, 선두께를 지정하는 stroke-width 속성이 있으며, 그 밖에도 다양한 속성을 사용할 수 있습니다.

rect 요소

사각형을 그릴 때는 <rect> 요소를 사용합니다. xy 속성으로 사각형의 좌측 상단 모서리의 위치를 지정하고, widthheight 속성으로 너비와 높이를 지정할 수 있습니다.

예를 들어, 300px x 300px의 캔버스의 좌측 상단에서 아래로 100px 우측으로 100px 떨어진 위치에서 높이와 너비가 100px인 정사각형을 그려보겠습니다.

<svg width="300" height="300" fill="green">
  <rect x="100" y="100" width="100" height="100" />
</svg>

당연히 width 속성값과 height 속성값을 다르게 주면 직사각형이 되겠죠?

<svg width="300" height="300" fill="green">
  <rect x="50" y="100" width="200" height="100" />
</svg>

circle 요소

원은 <circle> 요소를 사용하여 그릴 수 있습니다.

cxcy 속성으로 원의 정중앙 위치를 지정하고, r 속성로 반지름을 지정하면 됩니다.

<svg width="300" height="300" fill="green">
  <circle cx="150" cy="150" r="100" />
</svg>

ellipse 요소

타원을 그릴 때는 <ellipse> 요소를 사용할 수 있습니다.

rx 속성으로 수평 방향 반지름, ry 속성으로 수직 방향 반지름을 지정합니다.

<svg width="300" height="300" fill="green">
  <ellipse cx="150" cy="150" rx="100" ry="50" />
</svg>

rx 속성값과 ry 속성값을 동일하게 주면 그냥 원도 그릴 수 있겠죠?

<svg width="300" height="300" fill="green">
  <ellipse cx="150" cy="150" rx="100" ry="100" />
</svg>

line 요소

<line> 요소는 직선을 그릴 때 사용할 수 있습니다.

x1y1 속성으로 시작 위치를 지정하고, x2y2 속성으로 끝 위치를 지정하면 됩니다.

<svg width="300" height="300" stroke="green" stroke-width="10">
  <line x1="100" y1="150" x2="200" y2="150" />
</svg>

선을 그릴 때는 fill 속성이 의미가 없어지고, 대신에 선의 굵기를 지정하는 stroke-width 속성이 더 중요해집니다.

이번에는 직선을 두 개 사용해서 십자가를 한 번 그려볼까요? ➕

<svg width="300" height="300" stroke="green" stroke-width="10">
  <line x1="150" y1="100" x2="150" y2="200" />
  <line x1="100" y1="150" x2="200" y2="150" />
</svg>

polyline 요소

여러 지점으로 이루어진 선을 그리고 싶다면 <polyline> 요소를 사용하면 되는데요.

points 속성에 여러 좌표를 나열해주면 됩니다.

예를 들어, 체크 마크를 그려볼까요? ✔️

<svg width="300" height="300" stroke="green" stroke-width="10" fill="none">
  <polyline points="80,160 120,200 200,110" />
</svg>

polygon 요소

<polygon> 요소로는 다각형을 그릴 수 있습니다.

마찬가지로 points 속성에 여러 좌표를 나열해주면 됩니다.

예를 들어, 삼각형을 그려보겠습니다. 🔺

<svg width="300" height="300" fill="green">
  <polygon points="50,250 150,50 250,250" />
</svg>

사각형도 엄밀히 얘기하면 다각형에 속하니 <rect> 요소 대신에 <polygon> 요소를 사용할 수 도 있겠죠?

<svg width="300" height="300" fill="green">
  <polygon points="100,100 200,100 200,200 100,200" />
</svg>

path 요소

<path> 요소는 지금까지 다룬 요소를 모두 대체할 수 있을 정도로 상상할 수 있는 모든 것을 그릴 수 있는 요소인데요.

주로 여러 직선과 곡선을 조합하여 복잡한 형태의 도형을 그리기 위해서 사용되며, 사람이 직접 코딩하거나 해석해야 할 일은 거의 없다고 보셔도 됩니다.

<svg width="300" height="300" fill="green">
  <path d="M 50 50 L 250 250 V 150 H 50 L 50 50" />
</svg>

사실 <path> 요소가 필요할 정도에 왔다면 어도비 일러스트레이터(Adobe Illustrator)와 같은 백터 기반 그래픽 제작 소프트웨어에서 그린 후에 svg 코드로 내려받기를 추천드리며 본 포스팅에서는 깊게 다루지 않도록 하겠습니다.

마치면서

SVG를 이용해서 HTML 문서에 직접 그림을 그려보니 어떠신가요? <path> 요소를 제외하면 의외로 생각보다 어렵지 않죠? 😁

실제 프로젝트에서 이렇게 직접 SVG 요소를 이용해서 HTML 문서에 그래픽을 넣을 일은 많지 않겠지만 그래도 SVG 코드를 어느 정도 직접 읽고 이해할 수 있다면 도움이 될 것 같아서 한 번 다루어보았습니다.