본문 바로가기

HTML&CSS

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(./img/twitter_logo_original.svg); /* 애니메이션 되는 벡터 이미지 */
    display: block;
}
@keyframes moveto{
    0%{
        offset-distance: 0%
    }
    100%{
        offset-distance: 100%;
    }
}

 

벡터 경로를 따라 애니메이션되는 SVG 벡터 이미지

 

 

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

 

animation7.zip
0.00MB

반응형
  • 비밀댓글입니다

  • questions 2021.07.12 21:15 댓글주소 수정/삭제 댓글쓰기

    만약에 저 화면을 폰이나 여러Device로 보게되면 각각 기기들의 display 화면비율이 차이가 있어서 보여지는 위치가 서로 다를 것 같은데
    모든 device들의 화면의 가운데 정렬된 위치에서 보게할 순 없나요?
    무조건 왼쪽상단이 0,0 좌표인가요?

    • 캔버스처럼 svg 영역 안에서 좌표 독립이기 때문에 디바이스와는 무관하게 동작합니다.
      옛날 플래시와 같다고 보시면 됩니다.

      svg는 좌상단이 0,0입니다.

      svg데이터를 웹브라우저에 뿌릴 때는 어차피 태그안에 영역을 잡아서 뿌리기 때문에 svg를 감싼 태그를 css로 가운데 정렬을 하면 됩니다.
      svg에서 뷰박스 영역을 설정한 크기만큼 영역이 표시되므로 뷰박스 영역만 태그안에서 크기나 위치를 잡아주면 됩니다.

      svg단에서 가운데 정렬을 따로 할 필요는 없습니다.


닫기