etc

SVG viewbox, viewport, preserveAspectRatio 개념 이해하기

 


 

 

나를 이해시키기 위해서 적어보는 SVG 개념 이해하기 😵

 

 

 

01. 벡터 이미지 

 

일차적으로 svg의 viewbox를 이해하기 위해서는 svg가 vector 이미지라는 것을 알아야한다. 웹에서 이미지를 표현할때는 크게 래스터와 벡터 이미지로 구분시킬 수 있는데 흔히 우리가 많이 사용하는 확장자인 PNG, JPG가 바로 여기에 해당한다. 래스터 이미지는 무수히 많은 점으로 이미지를 구현하는데 백터이미지보다 더 다양한 색상을 표현하고 유연한 색상편집을 지원하고 세밀하게 빛과 음영을 보여주기에 많은 이들이 많이 사용하는 확장자이지만 이미지를 확대할시 픽셀화 현상이 나타난다는 단점이 존재한다. 

 

그렇다면 벡터(vector)이미지는? SVG(scalable vector graphics)이름에서도 알 수 있듯이 벡터 이미지는 해상도의 문제가 없다. 그리드에 점을 설정하는 수학공식과 선, 곡선을 사용하여 이미지를 만든다. 수학공식에 따라 크기를 변경하기 때문에 확대하거나 축소해도 이미지의 품질에는 영향이 가지 않는다. 

cf) 일반적으로 벡터이미지는 래스터이미지보다 용량이 작지만 이건 간단한 벡터이미지일 경우 그렇고 다소 복잡한 path로 이루어져 있을 경우 래스터이미지들보다 용량이 커질 수도 있다. (보통 로고와 같은 작업을 할때 사용한다.)

(출저 : https://www.adobe.com/kr/creativecloud/file-types/image/comparison/raster-vs-vector.html)

 

그렇기 때문에 png와 jpg파일의 크기를 조절할 때에는 width, height값을 사용하게 되며 픽셀화 현상을 없애기 위해서 사용한 파일의 적절한 크기가 width:1000px, height: 500px의 값을 가진다면 그 width값을 임의로 1200px로 늘리지 않아야 한다.

 

 

 

02. Viewbox ?  viewport? 

 

 

svg가 수학공식에 의해서 표현되는 벡터이미지라는 것을 알아냈다. 그렇기 때문에 png, jpg 래스터 이미지와 다르게 viewbox와 viewport라는 개념이 나타난다. 위의 이미지와 같이 svg code를 들고오면 자동으로 viewbox가 설정되어 있는 것을 볼 수 있다. 

 

viewBox="min-x min-y width height"

 

수학공식에 의해서 표현되는 이미지이기 때문에 viewbox가 존재하는 좌표값(min-x, min-y)과 viewbox의 width, height값으로 구성된다. 위의 코드에서는 viewBox가 0  0 500 450이라고 나와있는데 해석하자면 x값과 y값이 0에 놓여진 500*450사이즈를 가지는 viewbox가 있다는 소리이다. 여기서 viewbox의 width, height값은 viewport(보여지는 부분)를 기준으로 한다. 즉, 정해져있는 크기값이 아니라 상대적인 개념이다. 

 

svg를 위와 같이 코드로 그냥 들고와서 html에 넣을 경우 크기값이 내가 작업했던 파일보다 확대되어 보이는 경험을 해봤을 것이다. 이는 viewport를 설정하지 않았기에 일반적인 웹 해상도인 1920*1080을 기준으로 하여 이미지가 확대되었기 때문이다. 

 

정리하자면 아래와 같다. 
viewport = 실제적으로 보여지는 부분
viewbox = viewport를 기준으로 보여지게 될 부분을 결정할 박스 값 

 

 

 

예를 들어보자. 먼저 viewport크기를 설정해보자.

 

  svg{
	width: 800px;
    height: 400px;
  }

 

일반적인 래스터이미지의 경우 이미지의 비율에 맞는 height값을 주지 않으면 찌그러지거나 늘어지는 모습을 볼 수 있다. 하지만 비율에 맞지 않는 크기를 줬음에도 불구하고 svg는 찌그러지거나 늘어나지 않는다.  (알아서 원래의 비율이 깨지지 않는 최소의 width값이나 height값에 맞게 커지는 것을 볼 수 있다. 왜? preserveAspectRatio 때문) 

 

그럼 viewbox의 min-x, min-y 값인 위치값을 한번 바꿔보자. 

 

현재는 0 0 500 450으로 설정되어 있는데 이 값을 100 100 500 450으로 min-x, min-y값을 변경하면 어떻게 될까? 실제로 뷰박스는 뷰포트를 기준으로 원래 있던 위치에서 x, y만큼 더 이동했다. svg는 가만히 있었지만 실제적으로 우리는 svg가 왼쪽으로 -100, 위쪽으로 -100 이동했다고 느낀다.

여기서 우리는 viewport는 사용자에게 보여지게 될 크기값을 결정하고, viewbox는 실질적으로 svg그림이 보여지게 될 부분을 viewport의 기준으로 위치값과 크기값을 설정하여 보여주는 것을 알 수 있다. 

 

다시 min-x, min-y의 값을 0 0 으로 바꾼다음 이번에는 viewbox의 width값과 height값을 바꿔보자. 0 0 300 250으로 바꾸면 svg 파일이 확대되어 보인다. 값을 줄였다라는 실제적으로 보이는 숫자값때문에 축소되어야 한다고 착각하기 쉽지만 확대되는 것이 맞다. 

 

다시 돌아와서 viewport와 viewbox를 동일한 값을 줘보자. 

 

viewbox = " 0 0 500 450"으로 설정되어있으니 svg{     width: 500px;     height : 450px;}으로 같은 비율로 줬다고 해보자. 

 

아래의 왼쪽 이미지처럼 viewport와 viewbox가 동일한 크기일때는 위와 같이 보인다. 

하지만 아까처럼 viewbox의 크기를 줄인다면? viewbox의 크기는 viewport에 의한 상대적인 크기값이다. viewport보다 작은 값을 가지게 된 viewbox는 저만큼의 크기를 보여주게되지만 우리가 보게 될 viewport의 값이 줄어든 것이 아니고 viewbox만이 줄어든 것이기 때문에 실제적으로 우리가 느끼는 것은 '이미지가 확대되었다'고 느끼게 된다. 

 

😭 아 뭔소린지 모르겠어... 라고 느낀다면 그냥 애초에 svg파일을 작업할때 margin값을 두지말고 이미지를 꽉차게 만들어서 viewport값을 설정해버리자...... 🙄ㅎ....

 

 

 

03. preserveAspectRatio는 또 뭔데..? 

preserveAspectRatio (고정종회비)라고 한다. svg의 비율이 기본값으로 고정되어 있다는 소리이다. 그렇기 때문에 위에서 viewport의 width값과 height값을 원래 만들었던 svg의 비율에 깨지게 설정하여도 그 비율이 깨지지 않고 viewport의 최소값에 맞춰서 알아서 설정되어 커지거나 줄어든다. 

이 고정되어져있는 비율을 래스터이미지에서 width값과 height값을 주듯이 깨고 싶다면 svg태그 안에 preserveAspectRatio = "none"으로 처리하고 viewport의 비율을 viewbox와 다르게 설정하면 svg이미지가 래스터이미지처럼 비율이 깨진채로 보여지게 된다. 

 

<svg version="1.1" id="Layer_2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
    y="0px" viewBox="0 0 500 450" style="enable-background:new 0 0 500 450;" xml:space="preserve" preserveAspectRatio="none">