SVG 스트로크 애니메이션: 하나의 그리기 경로 준비하기
dasharray와 dashoffset으로 SVG 선이 그려지는 효과를 만드세요. 열린 경로와 채워진 외곽선을 비교하고 방향을 확인하며 동작 줄이기를 위한 정적 결과를 제공하세요.
목차
SVG 스트로크 애니메이션은 경로를 따라 대시를 이동하여 선을 드러낼 수 있습니다. stroke-dasharray로 대시와 간격을 정의한 뒤 스트로크가 보일 때까지 stroke-dashoffset을 애니메이션하세요. MDN은 이를 스트로크 칠 속성으로 설명합니다.
무엇이 그려지는 것처럼 보일지는 소스 경로가 결정합니다. 열린 경로는 마크의 중심을 통과하는 펜 경로를 따를 수 있습니다. 채워진 외곽선은 마크의 경계를 정의합니다. 이 외곽선에 스트로크를 추가하면 애니메이션은 가장자리를 따라갑니다. 대시 설정만으로 채우기를 드러내지는 않습니다.
전체 로고의 타이밍을 정하기 전에 작은 도형 하나로 시작하세요. 아래의 직접 작성한 예제는 그리기 경로, 채워진 아트워크, 둘레를 분리하므로 애니메이션에 필요한 도형을 선택할 수 있습니다.
아이콘 전체를 곡선을 따라 이동하려면 이동 경로와 아트워크를 분리하는 SVG 모션 경로 작업 흐름을 사용하세요.
열린 스트로크 경로로 시작하기
이 직접 만든 경로는 오른쪽으로 이동한 뒤 위로 올라갑니다. fill이 비활성화되어 보이는 도형은 전적으로 스트로크에서 나옵니다.
<div class="playing">
<svg viewBox="0 0 140 130" role="img" aria-label="Open bent line">
<path class="reveal route" pathLength="100" d="M30 90H100V30" />
</svg>
</div>2초 동안 드러나는 효과에는 다음 CSS를 사용하세요.
.reveal {
stroke-dasharray: 100;
stroke-dashoffset: 0;
}
.route {
fill: none;
stroke: #147d78;
stroke-width: 16;
stroke-linecap: butt;
}
.playing .reveal {
animation: draw 2s linear forwards;
}
@keyframes draw {
from { stroke-dashoffset: 100; }
to { stroke-dashoffset: 0; }
}
@media (prefers-reduced-motion: reduce) {
.playing .reveal {
animation: none;
stroke-dashoffset: 0;
}
}pathLength="100"은 거리 기반 연산을 작성된 길이 100에 맞춥니다. pathLength 참조는 이 정규화를 설명합니다. 대시 배열 값 하나는 대시와 간격으로 반복되므로 100은 전체 길이의 대시 뒤에 같은 길이의 간격을 제공합니다. 이 예제에서 패턴을 100만큼 이동하면 스트로크가 숨겨지고 오프셋을 0으로 옮기면 드러납니다.
여기서는 단위 없는 숫자를 사용하세요. stroke-dashoffset: 100%는 정규화된 경로 단위 100을 대신하지 않습니다. MDN의 대시 오프셋 참조는 백분율 값이 경로의 전체 길이가 아니라 SVG 뷰포트의 정규화된 대각선을 사용한다고 설명합니다.
이 예제는 일시 정지한 시작 상태를 쉽게 확인하도록 butt 캡을 사용합니다. 다른 캡 스타일은 대시 끝의 모양을 바꿀 수 있습니다. 아트워크에 맞는 캡을 선택한 뒤 아이콘이 실제로 표시될 크기에서 첫 프레임과 마지막 프레임을 확인하세요. 장식용 반복 패턴은 대시와 간격 길이를 정하기 전에 점선 외곽선과 캡 간격을 비교하세요.
그리기 경로와 채워진 외곽선 비교하기
두꺼운 꺾인 띠는 앞의 스트로크 선과 비슷해 보여도 다른 도형을 담을 수 있습니다. 직접 작성한 이 두 번째 경로는 띠의 경계를 돌아 Z로 닫힙니다.
<path class="reveal filled" pathLength="100"
d="M30 82H92V30H108V98H30Z" />다음 칠을 적용하면 대시 오프셋을 바꿔도 눈에 보이는 변화가 없습니다.
.filled {
fill: #ef8067;
stroke: none;
}대시를 적용할 스트로크가 없으므로 띠는 계속 채워져 있습니다. W3C의 SVG 칠 명세는 도형 내부를 칠하는 것과 스트로크를 칠하는 것을 구분합니다.
대신 fill: none을 설정하고 스트로크를 추가한 뒤 닫힌 경로를 애니메이션하면 스트로크는 둘레를 따릅니다. 한쪽 가장자리를 지나 끝을 건넌 다음 반대쪽 가장자리를 돌아옵니다. 띠의 중심을 통과하는 하나의 경로가 되지는 않습니다.

이 차이는 추적 결과에 이중 커팅 선이 생길 수 있는 이유도 설명합니다. 애니메이션에서는 펜 자국의 바깥을 도는 선이 원치 않는 결과가 될 수 있습니다. 원하는 효과에 중심 경로가 필요하다면 단일 선 SVG 안내로 해당 도형을 확인하거나 준비하세요.
시작, 중간, 완료 상태 확인하기
예제를 일시 정지하여 확인하려면 애니메이션을 비활성화하고 stroke-dashoffset을 100, 50, 0으로 설정하세요. 이 값들은 정규화된 경로의 시작, 절반이 드러난 상태, 최종 상태에 해당합니다. CSS 속성에 백분율로 입력하는 값이 아닙니다.
| 일시 정지 설정 | 열린 스트로크 경로 | 채워진 띠 | 채우기 없는 스트로크 둘레 |
|---|---|---|---|
| 오프셋 100 | 스트로크 숨김 | 전체 채우기 표시 | 스트로크 숨김 |
| 오프셋 50 | 열린 경로 일부 표시 | 전체 채우기 표시 | 경계 일부 표시 |
| 오프셋 0 | 완전한 꺾인 선 | 전체 채우기 표시 | 완전한 닫힌 경계 |
이 상태들을 선택하는 버튼과 함께 작은 테스트 페이지에 세 버전을 모두 두세요. 중간 설정은 특히 유용합니다. 완성된 도형은 비슷해 보여도 드러나는 도중에는 그리기 경로가 분명해집니다.
직접 작성한 경로들을 브라우저에서 오프셋 100, 50, 0으로 확인했고 2초 애니메이션을 한 번 실행했습니다. 채워진 띠는 계속 보였지만 경로와 둘레는 서로 다르게 드러났습니다. 이 테스트는 해당 원본 경로를 보여 주며 PerfectVector 추적이나 모든 브라우저를 대상으로 한 테스트가 아닙니다.
결과가 다르다면 실제 요소의 칠과 계산된 스타일을 살펴보세요. CSS 규칙은 프레젠테이션 속성을 덮어쓸 수 있으며 보이는 스트로크가 없는 경로는 대시 드러내기 효과를 보여 줄 수 없습니다. 스트로크 누락 확인 목록은 애니메이션 타이밍을 조정하기 전에 칠 및 표시 문제를 구분하는 데 도움이 됩니다.
시작점과 경로 순서 결정하기
첫 경로는 M30 90에서 시작해 x=100까지 가로로 이동한 뒤 y=30까지 세로로 이동합니다. 이 순서가 드러나는 방향을 결정합니다. 위쪽 끝에서 그리기 시작해야 한다면 애니메이션이 원하는 펜 움직임을 안다고 가정하지 말고 그 방향으로 경로를 준비하세요.
분리된 도형으로 구성된 로고는 어느 경로가 먼저 나타나고 어느 경로가 뒤따를지 결정하세요. 모든 경로에서 같은 애니메이션을 시작하면 동시에 드러납니다. 순차 효과에는 명시적 지연이나 다른 타임라인 구성이 필요합니다. 나중 도형이 아직 그려지는 스트로크를 가릴 수 있으므로 일시 정지 상태에서 교차와 겹침을 확인하세요.
여러 떨어진 하위 경로로 구성된 그림은 유용한 타이밍 제어를 위해 요소를 분리해야 할 수 있습니다. 시각적 디자인과 애니메이션 경로 결정을 구분하세요. 하나의 경로를 얻기 위해 관련 없는 조각을 합치면 작가가 의도하지 않은 연결이 생길 수 있습니다.
애니메이션 라이브러리는 순서 제어를 도울 수 있지만 입력에는 여전히 올바른 도형이 필요합니다. Motion의 SVG 애니메이션 문서는 애니메이션되는 pathLength 값으로 선 그리기를 제공합니다. 이 라이브러리 제어는 여기서 사용한 네이티브 SVG의 pathLength="100" 보정과 별도 API입니다. API를 확인하지 않고 한 예제의 값을 다른 예제에 복사하지 마세요.
움직임 없이도 완성된 아트워크 제공하기
CSS 예제의 기본 오프셋은 0이며 애니메이션 실행 중에만 바뀝니다. 동작 줄이기 미디어 쿼리는 드러내기 효과를 비활성화하고 완성된 선을 표시합니다. MDN의 prefers-reduced-motion 안내는 쿼리가 사용자의 선호를 감지하는 방식을 설명합니다.
상호작용 데모에는 다시 재생하는 버튼뿐 아니라 정적 결과 컨트롤도 제공하세요. 인터페이스 아이콘에는 동작을 설명하는 보이는 텍스트 라벨이나 접근성 이름을 유지하세요. 애니메이션이 그래픽의 의미를 파악하는 유일한 수단이 되어서는 안 됩니다.
실제 배치에서 초기, 중단, 완료 상태를 테스트하세요. 애니메이션이 실행되지 않을 때 필수 아이콘이 계속 보이지 않는다면 효과를 전체 인터페이스로 확장하기 전에 기본 스타일을 고치세요. 독립된 데모의 성공이 모든 브라우저, 보조 기술, 성능 결과를 입증하지는 않습니다.
펜 경로를 보장하지 않고 래스터 아트워크 준비하기
벡터 마스터가 없고 단일 이미지로 된 PNG나 JPG 마크를 편집 가능한 아트워크로 만들어야 한다면 PerfectVector의 이미지 벡터화 작업 흐름으로 SVG 후보 파일을 준비할 수 있습니다. 실루엣, 구멍, 분리된 영역을 원본과 비교하고 편집기에서 다운로드한 경로를 살펴보세요. 애니메이션을 계획하기 전에 그 도형을 검토할 아트워크로 사용하세요.
벡터화는 원래 펜 순서를 확정하거나 타임라인을 만들거나 단일 중심선 경로를 보장하지 않습니다. 효과에 스트로크를 통과하는 하나의 경로가 필요하다면 그 경로를 의도적으로 그리거나 준비하세요. 기존 벡터 마스터가 있다면 유지하세요. 래스터 이미지만 포함한 SVG도 보이는 마크가 편집 가능한 경로 도형이라고 가정하기 전에 포함된 이미지 확인이 필요합니다.
먼저 정적 아트워크를 확인한 뒤 그려지는 순서를 확인하세요. 블로그의 편집 안내는 애니메이션 단계 이전의 소스 정리를 다룹니다.
FAQ
스트로크 애니메이션 시작 시 SVG가 계속 보이는 이유는 무엇인가요? 보이는 부분이 채우기인지 확인하세요. 대시 배열과 대시 오프셋 설정은 스트로크에 영향을 주므로 스트로크가 숨겨져도 채워진 영역은 계속 보일 수 있습니다.
애니메이션이 선의 양쪽을 따라 그려지는 이유는 무엇인가요? 경로가 두꺼운 마크를 둘러싼 닫힌 외곽선을 정의할 수 있습니다. 이 경로에 스트로크를 적용하면 둘레를 따릅니다. 중심을 통과하는 단일 선이 필요한 효과에는 열린 그리기 경로를 준비하세요.
전체 경로 길이에 100%를 사용할 수 있나요? stroke-dashoffset에서 일반적인 대체값으로는 사용할 수 없습니다. 백분율은 뷰포트의 정규화된 대각선을 기준으로 합니다. 예제는 네이티브 pathLength="100"과 단위 없는 대시 값을 사용합니다.
PNG를 SVG로 변환하면 손글씨 애니메이션에 바로 사용할 수 있나요? 벡터화만으로 펜 순서나 중심선이 자동 보장되지는 않습니다. 결과 도형을 살펴보고 그리기 경로와 타이밍을 별도로 준비하세요.
Sources
- MDN — stroke-dasharray — 스트로크 칠에서 번갈아 나오는 대시와 간격 길이를 정의합니다.
- MDN — stroke-dashoffset — 패턴 오프셋과 백분율이 사용하는 기준을 설명합니다.
- MDN — pathLength — 경로와 스트로크의 네이티브 거리 보정을 설명합니다.
- W3C — SVG 칠하기 — 채우기와 스트로크 동작을 구분합니다.
- MDN — prefers-reduced-motion — 정적 결과에 사용하는 사용자 선호를 설명합니다.
- Motion — SVG 애니메이션 — 라이브러리의 별도 선 그리기 API를 설명합니다.
전체 아트워크에 순서를 적용하기 전에 한 경로의 시작, 중간, 완료 상태를 테스트하세요. 래스터 마크가 소스라면 편집 가능한 SVG 후보 파일을 준비하고 도형을 살펴본 뒤 그리기 경로를 별도로 계획하세요.

