최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday

티스토리 뷰

■ 프론트엔드 ■/SVG

path

serpiko 2013. 11. 29. 11:23

Path

지난시간에는 SVG에서 사용할 수 있는 기본적인 도형들을 살펴보았다. 하지만 정형화된 도형을 쓰는 경우보단 정형화되지 않은 도형을 만들어서 써야 할 경우가 많다. 이때 사용할 수 있는 것은 path 이다. 사실 path 하나만으로도 지난시간에 살펴본 모든 도형들을 대체가 가능하다.

M 과 L

path 는 그 이름에서 알 수 있듯이 몇개의 좌표를 지정하고 그 좌표를 지나가도록 하여 도형을 그리는 element 이다. 아래의 예제를 보자.

<path stroke="#000000" d="M 50 50 L 100 50 100 100 M 150 150 L 200 150 150 200" />

d 속성에 그리고자 하는 위치의 좌표값을 설정하면 된다. 좌표는 “M x y” 혹은 “L x y”로 표현이 되는데 여기서 M 은 Move를 L 은 Line을 의미한다. 즉 M 으로 시작하는 좌표로는 눈에 보이는 선을 그리지 않고 L 로 이동하는 좌표일때 선을 그리게 된다. 마치 종이에 그림을 그릴때 펜을 종이 닿은 상태에서 이동하느냐 뗀 상태에서 이동하느냐의 차이와 같다. 그래서 위의 예제에서는 하나의 path element 를 이용해 서로 닿지 않는 두개의 삼각형을 그릴 수 있었다.

fill(채우기)

<path d="M 50,100 150,200 50,150"/>
<path d="M 100 50 L 200 150 100 100" fill="none" stroke="black"/>

위의 예제에서 첫번째 path 에는 fill 속성이 없음에도 자동으로 검은색으로 채워졌다는 걸 볼 수 있다. 반면 fill 속성을 주지 않고 stroke 만 속성만 준 두번째 path 는 선만 두개 그어졌을뿐 자동으로 close되지 않았음을 볼 수 있다. 그리고 ,(comma) 를 삽입하던 삽입하지 않던 좌표에는 문제가 없음을 유의하자.

만약 두번째 path 와 같은 상황에서 도형을 완전히 close 시키고 싶다면? d 속성 마지막 값에 "z"를 추가하면 된다.
open:
<path d="M 100,50 200,150 100,100" fill="none" stroke="black"/>
closed:
<path d="M 100,50 200,150 100,100 z" fill="none" stroke="black"/>
fill-rule

만약 채움이 있는 두개의 도형이 겹쳐지면 어떻게 될까? fill-rule 을 이용해서 겹쳐질때의 채움상태를 결정할 수 있다. 아래의 예제는 여러개의 삼각형으로 이루어져있는 것처럼 보이지만 사실은 두개의 삼각형을 겹쳐놓았을 뿐이다. 겹쳐지는 영역을 어떻게 채울 것인지에 대해 결정하는 속성이 fill-rule 이다. "evenodd" , 와 "noezero" 가 있다.

<path fill="orange"
d="M 10,215 210,215 110, 42 z
M 10,100 210,100 110,273 z"
stroke="purple" stroke-width="3" fill-rule="evenodd"/>

Q 와 C

L 과 M 으로는 직선밖에 표현할 수가 없다. 곡선이나 타원을 표현하려면? Q 와 C 를 이용해 곡선을 나타낼 수 있다. Q} }와 {{C 는 Bézier curves를 그 기초로 하고 있다.

Bézier curves
베지에 곡선은(Bezier curve) n개의 점을 통해 곡선을 그리는 식이다. 폰트나 그래픽툴 등에서 부드러운 곡선을 생성하는데 이용되고 있다. cubic bezier curve 는 네개의 점(p0,p1,p2,p3)을 통해 3차 곡선을 만들며 Quadratic Bézier curves는 세개의 점을 통해 곡선을 만들어낸다. 
.... 

아래의 예제는 같은 좌표값을 이용해 직선과 곡선을 그린 예제이다.

<path d="M 100 200 Q 200,400 300,200" fill="none" stroke="blue" />
<path d="M 100 200 Q 300,400 300,200" fill="none" stroke="yellow" />
<path d="M 100 200 Q 100,400 300,200" fill="none" stroke="black" />
<path d="M 100 200 L 200,400 300,200" fill="none" stroke="red"/>

Quadratic curve는 세개의 인자가 필요하다. 시작점과 끝점 그리고 중간점이다. 중간점의 위치에 따라 곡선의 모양이 달라진다.(다소 혼란스러워보이지만) 위의 예제에서 나타는 세개의 곡선은 중간점만 다르고 이에 따라 변곡점의 위치도 달라짐을 볼 수 있다.

transformations

지금까지는 도형을 어떻게 그리는지에 대해서 알아보았다. 이제는 그려진 도형들을 변형시켜보도록 하자.

translation

가장 기본적인 transformation은 그려진 도형을 이동시키는 translation 이다. transform 속성을 이이용해서 이동시킬 수 있다.

<path fill="#bbb" fill-rule="evenodd"
d="M 70,140 150,0 200,100 40,100 100,0 170,140 z"/>

<path fill="#bbb" fill-rule="evenodd" 
transform="translate(200,0)"
d="M 70,140 150,0 200,100 40,100 100,0 170,140 z"/>

위의 코드는 같은 좌표값을 사용하여 똑같은 모양의 도형을 두쌍 그린 후 하나를 다른 위치로 옮긴것이다. 만약translation 을 쓰지 않고 같은 효과를 내려고 한다면 이동후의 좌표값을 일일히 계산해서 도형을 따로 그려줘야 할 것이다.

rotation

이런 그대로 회전을 시키는 transformation이다.
아래의 예제는 두개의 타원을 그린 후 하나의 타원을 30도 만큼 rotation 시킨 예제이다. rotate(a,b,c) 코드로 회전을 시키는 첫번째 인자는 회전시킬 각도(radian이 아니라 degree)값이며 두번째 세번째 인자는 회전시킬 기준 좌표(x,y)이다. 기준 좌표가 타원의 중심과 같기 때문에 타원의 중심은 변하지 않은 상태로 회전하게 된다.

<ellipse cx="200" cy="200" rx="20" ry="100" 
opacity=".6" fill="#faa" stroke="#806" stroke-width="4"/>
<ellipse cx="200" cy="200" rx="20" ry="100" transform="rotate(30,200,200)"
opacity=".6" fill="#faa" stroke="#806" stroke-width="4"/>

만약 rotate시 기준좌표를 바꾼다면? 기준 좌표를 중심으로 돌테니 아래의 예제와 같이 도형의 위치또한 바뀔 것이다.

<ellipse cx="100" cy="100" rx="20" ry="100" 
opacity=".6" fill="#faa" stroke="#806" stroke-width="4"/>
<ellipse cx="100" cy="100" rx="20" ry="100" transform="rotate(45,200,200)"
opacity=".6" fill="#faa" stroke="#806" stroke-width="4"/>

scaling

scale 은 단순히 크기를 변화시키는 것이 아니다. 정확히 말하면 각 x,y좌표값들에 scale 값을 곱해준다. 이럴경우 중심의 좌표 역시 상대적으로 이동할 수 밖에 없다. 아래의 예제를 보자.

<ellipse cx="100" cy="50" rx="40" ry="20" 
fill="grey" stroke="black" stroke-width="12" stroke-dasharray="3,5,2"/>
<ellipse cx="100" cy="50" rx="40" ry="20" 
fill="grey" stroke="black" stroke-width="12" stroke-dasharray="3,5,2"
transform="scale(2.5)" />

여기서 주의깊에 보아야 할점은 두 타원의 중심좌표를 포함한 모든 속성값이 같고 scale 값만 다르지만 타원의 위치가 바뀌었다는 것이다. scale값이 제 자리에서 도형을 확대시키는 것이 아니라는 점이다.


source : http://rockmkd.tistory.com/entry/SVG-%EB%A7%9B%EB%B3%B4%EA%B8%B0-2-5




댓글