SVG 모션 경로: 직접 만든 아이콘을 곡선 따라 이동하기
animateMotion과 mpath로 SVG 그림을 곡선 따라 이동하세요. 중심이 어긋난 아이콘을 수정하고 자동 회전을 선택하며 동작 줄이기용 정적 버전을 제공합니다.
목차
animateMotion으로 SVG 요소를 경로 따라 이동하고 내부 mpath로 기존 경로를 참조하세요. rotate="auto"는 경로 방향에 맞춰 그림을 돌립니다. 그림의 로컬 원점이 경로를 따라가는 지점이므로 가져온 아이콘에는 의도한 기준점이 필요합니다.
직접 만든 화살표, 문양이나 작은 일러스트가 모양 변경 없이 이동해야 할 때 유용합니다. 스스로 그려지는 선에는 스트로크 애니메이션을, 다른 실루엣으로 바뀌는 모양에는 경로 모핑을 쓰세요. 서로 다른 시각 작업을 해결합니다.
이동 경로와 그림 분리하기
이동 경로는 아이콘의 위치, 아이콘은 독자가 보는 것을 정의합니다. MDN의 animateMotion 참고 문서는 모션 요소를, mpath 참고 문서는 참조로 경로를 재사용하는 방법을 설명합니다.
아래 원본 예제에는 청록색 화살표와 금색 점이 있습니다. 화살표는 양의 X 방향이라 자동 회전을 확인하기 쉽습니다. 큰 내보내기 캔버스 멀리 있지 않고 (0, 0) 주위에 그렸습니다.
motion.html로 저장하고 브라우저에서 여세요. 정적 문양이 먼저 표시됩니다. Play를 누르면 4초 이동 한 번이 실행되고 Show static은 시작 그림을 복원합니다.
<!doctype html>
<meta charset="utf-8">
<title>Arrow following a curve</title>
<style>
svg { display: block; width: min(100%, 800px); }
.moving { display: none; }
.playing .moving { display: inline; }
.playing .still { display: none; }
</style>
<svg id="scene" viewBox="0 0 480 240"
xmlns="http://www.w3.org/2000/svg"
role="img" aria-label="An arrow emblem follows a curved route">
<defs>
<path id="route" d="M60 180 C160 20 300 20 420 180" />
<g id="emblem">
<path fill="#147d78"
d="M-18-12 H4 V-22 L30 0 L4 22 V12 H-18 Z" />
<circle cx="-7" cy="0" r="4" fill="#e5a340" />
</g>
</defs>
<use href="#route" fill="none" stroke="#a9bab6" stroke-width="2" />
<use class="still" href="#emblem" transform="translate(60 180)" />
<g class="moving">
<use href="#emblem" />
<animateMotion id="motion" dur="4s" begin="indefinite"
fill="freeze" rotate="auto">
<mpath href="#route" />
</animateMotion>
</g>
</svg>
<button id="play" type="button">Play</button>
<button id="stop" type="button">Show static</button>
<script>
const scene = document.querySelector("#scene");
const motion = document.querySelector("#motion");
const preference = matchMedia("(prefers-reduced-motion: reduce)");
function showStatic() {
scene.pauseAnimations();
scene.classList.remove("playing");
}
document.querySelector("#play").addEventListener("click", () => {
if (preference.matches) return;
scene.pauseAnimations();
scene.setCurrentTime(0);
scene.classList.add("playing");
motion.beginElement();
scene.unpauseAnimations();
});
document.querySelector("#stop").addEventListener("click", showStatic);
preference.addEventListener("change", showStatic);
showStatic();
</script>보이는 회색 곡선은 경로의 별도 use입니다. 경로를 숨기려면 그 use를 제거하되 애니메이션이 참조하도록 defs의 정의는 유지하세요. 모션 요소는 화살표·점이 함께 움직일 그룹 안에 둡니다.
fill="freeze"는 최종 애니메이션 상태를 유지합니다. 화살표의 청록색 페인트와 무관합니다. 예제는 한 번 실행해 무한 반복보다 최종 위치를 확인하기 쉽습니다.

경로에서 벗어나 떠 있는 아이콘 고치기
모션은 요소 좌표계에 적용합니다. 로고의 시각적 중앙을 자동으로 찾지 않습니다. 가져온 경로가 (200, 120) 주위 좌표에 있으면 포함 그룹을 이동해도 그룹 내부 오프셋은 남습니다.
경로에 닿아야 하는 그림 지점을 고르고 움직이는 그룹 안에서 (0, 0)으로 옮기세요. 기준점이 (200, 120)이면 구조는 다음과 같습니다.
<g class="moving">
<g transform="translate(-200 -120)">
<!-- Place the original artwork paths here. -->
</g>
<animateMotion dur="4s" rotate="auto">
<mpath href="#route" />
</animateMotion>
</g>안쪽 이동은 그림을 준비하고 바깥 그룹이 모션을 받습니다. 배율·보정 회전 추가 때도 구분하세요. SVG 애니메이션 명세는 모션을 추가 변환으로 정의하므로 기존 변환도 최종 배치에 영향을 줍니다.
배지는 중앙이 적절한 기준점일 수 있습니다. 차량은 바퀴 접촉점, 포인터는 끝을 원할 수 있습니다. 바운딩 박스 중앙은 시작 추정일 뿐입니다. 경로 여러 위치에서 의도한 접촉점을 확인하세요.
제자리 회전에는 별도의 중심 문제가 있습니다. SVG transform-origin 가이드는 이동 경로 없이 설명합니다.
그림 회전 여부 선택하기
| 원하는 결과 | 모션 설정 | 그림 준비 |
|---|---|---|
| 화살표가 곡선 방향을 따름 | rotate="auto" | 전방을 양의 X 방향으로 지정 |
| 배지가 이동 중 똑바로 유지 | rotate="0" | 로컬 그림에 원하는 고정 방향 유지 |
| 그림이 경로 방향 반대로 향함 | rotate="auto-reverse" | 사용 전 원본 전방 확인 |
값은 MDN 모션 회전 참고 문서에 설명됩니다. auto-reverse는 바라보는 방향을 바꾸며 이동 순서를 뒤집지 않습니다.
원본이 위로 향하면 auto는 위쪽이 전방인지 모릅니다. 안쪽 그림 그룹을 양의 X로 향하게 돌리고 바깥 그룹에 모션을 적용하세요. 아이콘의 로컬 방향 수정만 하려고 이동 경로를 돌리지 마세요.
날카로운 경로 모서리는 갑작스러운 방향 변화를 만들 수 있습니다. 부드러운 회전에는 곡선 경로가 더 좋은 시작점입니다. 경로 주변 공간도 남기세요. 아이콘은 중심선 밖으로 뻗어 SVG 뷰포트 끝 근처에서 잘릴 수 있습니다.
시작, 중간과 끝 확인하기
Chrome에서 같은 경로·문양을 열고 작은 테스트 도구로 SVG 타임라인을 0, 2, 4초에 멈췄습니다. 아이콘은 왼쪽 아래에서 시작해 정점 가까이를 지나 오른쪽 아래에서 끝났습니다. auto에서는 방향이 곡선 따라 바뀌었습니다. 회전 0에서는 중간 위치는 같고 화살표는 수평을 유지했습니다.
한 브라우저의 해당 예제를 검사합니다. 디자인 도구의 애니메이션 가져오기 테스트나 모든 브라우저 삽입 모드 보장은 아닙니다.
자신의 그림에서는 다음을 확인하세요.
- 경로 시작의 접촉점을 확인하세요. 타이밍 전에 원본 오프셋을 고치세요.
- 굽은 곳 근처에서 멈춰 의도한 문양 부분이 선을 따르는지 확인하세요.
- 자동·고정 회전을 비교하세요. 특히 텍스트 포함 시 그림에 맞춰 고르세요.
- 끝 자세의 잘림과 올바른 재시작을 확인하세요.
- 실제 전달 문맥을 테스트하세요. 예제는 JavaScript 제어가 있는 HTML 페이지의 인라인 SVG입니다.
MDN 설명대로 animateMotion은 기본적으로 경로를 일정한 속도로 이동합니다. 따라서 지속 시간 절반은 대략 이동 거리 절반이며 제어점 사이 곡선 매개변수 절반은 아닐 수 있습니다. 비대칭 3차 경로의 2초 자세는 기하 정점보다 조금 오른쪽이었습니다.
유용한 정적 버전 제공하기
예제는 문양의 정적 use로 시작하고 Play 버튼을 누른 후에만 모션을 시작합니다. JavaScript가 실행되지 않으면 정적 그림은 남습니다. 동작 줄이기 선호가 켜져 있으면 핸들러가 그 상태를 유지합니다.
prefers-reduced-motion 미디어 기능은 페이지가 사용자 동작 선호에 반응하게 합니다. 여기서는 시작 전에 JavaScript가 선호를 읽고 변경되면 정적 버전을 복원합니다.
테스트 도구의 명시적 동작 줄이기 미리보기 스위치로 정적 분기도 테스트했습니다. 애니메이션 그룹을 숨기고 시작 위치에 문양을 표시했습니다. 대체 로직을 실행했으며 컴퓨터 접근성 설정은 바꾸지 않았습니다.
가능하면 의미는 애니메이션 밖에 두세요. 상태나 필수 지침을 알기 위해 움직이는 문양을 봐야 해서는 안 됩니다. 이미 설명하는 텍스트 옆의 장식 아이콘은 같은 내용을 두 번 안내하지 않도록 접근성 레이블을 조정하세요.
애니메이션 전에 자신의 모티프 준비하기
모티프가 PNG·JPG에만 있으면 PerfectVector가 모션 구성 전에 편집 가능한 SVG 그림을 복원할 수 있습니다. 복원 실루엣·작은 구멍을 확인하고 함께 이동할 부분을 그룹화해 기준점을 고르세요. PerfectVector는 원본 도형을 제공하고 경로·타이밍·모션 동작은 따로 작성합니다.
기존 SVG는 바로 그룹·기준점 준비로 진행하세요. 데모 같은 단순 화살표는 직접 그리는 것도 실용적입니다. 이미지 벡터화 개요는 래스터 추적이 유용한 때를 설명합니다.
래스터 형식의 직접 만든 표식은 PerfectVector에 이미지를 넣고 윤곽선·작은 세부를 확인하세요. 경로의 시작·중간·끝에서 SVG를 테스트하고 애니메이션과 정적 버전을 함께 유지하세요.
FAQ
아이콘이 경로 위가 아니라 옆으로 이동하는 이유는 무엇인가요? 그림이 로컬 원점에서 벗어나 있을 수 있습니다. 따라갈 지점을 골라 움직이는 그룹 안에서 0으로 옮기세요. 시작과 굽은 곳에서 결과를 확인하세요.
자동 회전이 아이콘 모양을 바꾸나요? 아닙니다. 모션은 위치·방향을 바꾸고 경로 도형을 모핑하지 않습니다. 예제의 자동 회전에는 원본 전방이 양의 X로 향해야 합니다.
보이는 안내선을 제거할 수 있나요? 네. 경로 정의와 ID는 유지하고 안내선을 그리는 별도 요소를 제거하세요. mpath를 통해 모션이 계속 경로를 참조할 수 있습니다.
Sources
- MDN animateMotion — 모션 경로, 회전 값과 기본 일정 속도 이동을 설명합니다.
- MDN mpath — 모션 요소 내부의 기존 경로 참조를 설명합니다.
- SVG 애니메이션 명세 — 모션 변환과 그림 좌표의 관계를 정의합니다.
- MDN rotate 속성 — 고정·자동·반대 방향 모션 자세를 설명합니다.
- MDN 동작 줄이기 선호 — 사용자 동작 선호 감지를 설명합니다.

