SVG 벡터 경로(Path)를 따라 이동하는 CSS 애니메이션 만들기

CSS 애니메이션을 만들어 사용할 때 대부분의 애니메이션은 직선 이동, 또는 크기 변경입니다.

전문적인 애니메이션이 아닌 이상 요소의 이동은 직선이 대부분입니다. 직선이 아닌 경우에도 직선을 여러개 이어 붙여서 표현하면 어색하지 않게 방향이 변하는 이동 경로를 만들 수도 있습니다.

예를 들어 다음처럼 여러 개의 직선 이동을 하나의 키프레임 애니메이션으로 표현할 수 있습니다.

div.box{
    position: absolute;
    left: 70px;
    top: 70px;
    width: 60px;
    height: 60px;
    background-color: #a00;
    border: 5px solid pink;
    box-shadow: 0 0 15px -5px rgba(0,0,0,0.4);
    border-radius: 35px;
    animation: moveto 1s infinite alternate ease;
}
@keyframes moveto{
    25% {
        transform: translate(100px, 0px);
    }
    50%{
        transform: translate(100px, 100px);
    }
    75%{
        transform: translate(0px, 100px);
    }
    100%{
        transform: translate(0px, 0px);
    }
}

조금 더 복잡한 경로나 부정형 경로를 이동하는 애니메이션을 만들고 싶을 때는 이 방법으로는 애니메이션 경로를 만들기가 어렵습니다. 만들 수 있다고 해도, 원하는 결과를 얻을 때까지 무수히 많은 반복과 디버깅을 해야 합니다.

부정형 경로를 따라 움직이는 애니메이션을 만드려면 "offset" 속성을 이용해야 합니다.

"offset" 속성을 이용하면 원하는 어떤 형태의 애니메이션 경로도 만들어낼 수 있습니다.

"offset" 속성의 호환성 문제

"offset" 속성은 인터넷 익스플로러와 사파리에서는 지원이 되지 않습니다.

인터넷 익스플로러는 퇴출 수순을 밟고 있으므로 가까운 시점에는 문제가 되지 않겠지만, 사파리의 경우 아직 미지원 상태입니다. "offset" 속성이 비교적 최신 속성이기 때문에 가까운 미래에는 사파리도 지원을 할 가능성이 높습니다.

offset 속성의 지원 상태

한가지 더해서 "offset" 속성 값들을 개별 속성 값으로 풀어서 표현하는 확장 속성 중 "offset-path"와 같은 일부 확장 속성은 파이어폭스 웹브라우저에서는 지원되지 않습니다.

"offset" 속성을 사용할 때는 웹브라우저 호환성 문제를 주의해서 사용해야 합니다.

벡터 애니메이션 경로 만들기

벡터 그래픽 프로그램에서 원하는 경로를 라인으로 그린 후, "SVG" 포맷으로 익스포트 합니다.

벡터 드로잉 라인을 SVG 포맷으로 익스포트

저장한 SVG 이미지 파일을 텍스트 편집기에서 엽니다.

SVG 벡터 파일 포맷은 텍스트 파일(XML 포맷)이기 때문에 텍스트 편집기에서 열어서 그 내용을 확인할 수 있습니다.

SVG 파일 데이터를 텍스트 편집기에서 연 화면

SVG 소스의 태그 중 "<path d="" ... >" 를 찾아 d="" 의 쌍따옴표 안의 경로 데이터만 복사합니다.

복사한 경로는 다음과 같습니다. 경로를 따라 움직이는 요소는 경로의 축을 따라 이동하기 때문에 경로의 방향과 각도에 맞춰 요소도 함께 회전을 합니다.

SVG 벡터 경로 적용하기

앞서 만들었던 애니메이션을 수정해서 벡터 경로를 적용해 보겠습니다.

"offset" 속성을 이용해 다음처럼 경로를 만듭니다. 앞서 복사한 경로 데이터는 "path('붙여넣을경로');" 처럼 path() 함수를 사용해서 속성 값을 붙여 넣습니다.

이때 붙여 넣은 경로 경로 데이터의 시작 부분에 있는 "M"+"X좌표" + 쉼표 + "Y좌표" 를 초기화 해야 합니다.

아래 예제에 사용한 좌표 값인 "M0,100" 은 경로의 시작 지점 좌표를 표시하는 것입니다. "M0,0"은 ".box" 클래스를 가진 요소의 왼쪽 위 모서리 위치를 가리킵니다.

잘 모르겠으면 "M0,0" 으로 변경한 후 애니메이션을 적용해보면 바로 알 수 있습니다.

키프레임은 다음처럼 "0%" 와 "100%" 만 만들고 "offset-distance" 속성 값을 정의합니다. 0%는 없어도 됩니다. 벡터 경로를 적용할 경우 키프레임 애니메이션은 기본 틀만 사용하기 때문에 그대로 복사&붙여넣기를 해서 사용하면 됩니다.

.box{
    position: absolute;
    left: 70px;
    top: 70px;
    width: 60px;
    height: 60px;
    background-color: #a00;
    border: 5px solid pink;
    box-shadow: 0 0 15px -5px rgba(0,0,0,0.4);
    border-radius: 35px;
    offset: path('M0,100c10,-50 82.095,-82.507 127.089,0c19.734,-79.314 119.195,-102.241 151.559,0c5.526,-77.735 101.322,-104.262 149.192,-52.888') auto;
    animation: moveto 5s ease;
}
@keyframes moveto{
    0%{
        offset-distance: 0%
    }
    100%{
        offset-distance: 100%;
    }
}
벡터 경로가 적용된 애니메이션

백터 그래픽을 애니메이션 하기

애니메이션을 가볍게 동작시키려면 비트맵 그래픽 보다는 벡터 그래픽을 사용하는 것이 좋습니다.

데이터량도 작고 가볍기 때문에 애니메이션을 동작시키는데 부담이 없고, 컴퓨터 리소스도 덜 먹기 때문입니다.

웹 브라우저의 성능 한계상 그래픽 카드 가속을 지원 하더라도 큰 비트맵을 애니메이션에 사용하면 프레임이 떨여지거나 애니메이션이 매끄럽지 않게 재생될 가느성이 높아집니다.

특히나 반응형 웹페이지를 만드는 경우 애니메이션을 적용할 때는 성능 문제를 항상 염두해 두어야 합니다.

앞서의 예에서 ".box" 클래스의 원형 CSS 디자인을 삭제한 후, 가상 요소를 하나 추가합니다.

가상 요소 "content" 속성으로 벡터 이미지 URL을 연결합니다.

.box{
    position: absolute;
    left: 70px;
    top: 70px;
    width: 60px;
    height: 60px;
    background-color: transparent; /* 벡터 이미지 배경이 투명하게 되도록 배경색 지움 */
    offset: path('M0,100c10,-50 82.095,-82.507 127.089,0c19.734,-79.314 119.195,-102.241 151.559,0c5.526,-77.735 101.322,-104.262 149.192,-52.888') auto;
    animation: moveto 5s ease;
}
.box::after{
    content: url(./backup/885/img/twitter_logo_original.svg); /* 애니메이션 되는 벡터 이미지 */
    display: block;
}
@keyframes moveto{
    0%{
        offset-distance: 0%
    }
    100%{
        offset-distance: 100%;
    }
}
벡터 경로를 따라 애니메이션되는 SVG 벡터 이미지

완성된 예제는 다음 링크를 클릭해 다운로드 할 수 있습니다.

animation7.zip0.00MB