2025-03-14T13:00:37
This commit is contained in:
155
doc/svg/06_SVG 애니메이션.md
Normal file
155
doc/svg/06_SVG 애니메이션.md
Normal file
@@ -0,0 +1,155 @@
|
||||
### SVG의 `<animate>`와 `<animateTransform>` 요소
|
||||
|
||||
SVG는 `<animate>`와 `<animateTransform>` 요소를 통해 애니메이션을 구현할 수 있는 강력한 기능을 제공합니다. 이들은 SMIL(Synchronized Multimedia Integration Language)을 기반으로 하며, 별도의 CSS나 JavaScript 없이도 동적인 효과를 만들 수 있습니다. 아래에서는 이 두 요소의 사용법과 실무에서 유용한 예제, 그리고 CSS와 JavaScript를 활용한 대체 방법을 설명합니다.
|
||||
|
||||
---
|
||||
|
||||
### `<animate>`: 속성 애니메이션
|
||||
|
||||
`<animate>`는 SVG 요소의 특정 속성을 시간에 따라 변화시키는 데 사용됩니다. 색상, 크기, 위치 등 다양한 속성을 애니메이션할 수 있습니다.
|
||||
|
||||
#### 주요 속성
|
||||
| 속성 | 설명 | 예시 값 |
|
||||
|-----------------|-------------------------------------------------------------------------------------|------------------------|
|
||||
| `attributeName` | 애니메이션 대상 속성. | `opacity`, `x`, `r` |
|
||||
| `from` | 시작 값. | `0`, `10` |
|
||||
| `to` | 종료 값. | `1`, `50` |
|
||||
| `dur` | 애니메이션 지속 시간. | `2s`, `500ms` |
|
||||
| `begin` | 시작 시점. | `0s`, `click` |
|
||||
| `repeatCount` | 반복 횟수. | `indefinite`, `3` |
|
||||
| `fill` | 애니메이션 종료 후 상태(`freeze`: 마지막 값 유지, `remove`: 원래 값으로 복귀). | `freeze`, `remove` |
|
||||
|
||||
#### 예시: 원의 반지름 변화
|
||||
```xml
|
||||
<svg width="200" height="200">
|
||||
<circle cx="100" cy="100" r="20" fill="red">
|
||||
<animate attributeName="r" from="20" to="50" dur="2s" repeatCount="indefinite" />
|
||||
</circle>
|
||||
</svg>
|
||||
```
|
||||
- 원의 반지름이 20에서 50으로 2초 동안 반복적으로 커짐.
|
||||
|
||||
---
|
||||
|
||||
### `<animateTransform>`: 변환 애니메이션
|
||||
|
||||
`<animateTransform>`는 `transform` 속성(회전, 이동, 크기 조정 등)을 애니메이션합니다.
|
||||
|
||||
#### 주요 속성
|
||||
| 속성 | 설명 | 예시 값 |
|
||||
|-----------------|-------------------------------------------------------------------------------------|------------------------|
|
||||
| `attributeName` | 항상 `transform`으로 설정. | `transform` |
|
||||
| `type` | 변환 유형. | `rotate`, `scale`, `translate` |
|
||||
| `from` | 시작 변환 값. | `0 100 100`, `1` |
|
||||
| `to` | 종료 변환 값. | `360 100 100`, `2` |
|
||||
| `dur` | 지속 시간. | `3s` |
|
||||
| `repeatCount` | 반복 횟수. | `indefinite` |
|
||||
|
||||
#### 예시: 회전 애니메이션
|
||||
```xml
|
||||
<svg width="200" height="200">
|
||||
<rect x="75" y="75" width="50" height="50" fill="blue">
|
||||
<animateTransform attributeName="transform" type="rotate"
|
||||
from="0 100 100" to="360 100 100" dur="3s" repeatCount="indefinite" />
|
||||
</rect>
|
||||
</svg>
|
||||
```
|
||||
- 사각형이 중심(100, 100)을 기준으로 360도 회전.
|
||||
|
||||
---
|
||||
|
||||
### 실무에서 유용한 SVG 애니메이션 예제
|
||||
|
||||
#### 1. 로딩 스피너
|
||||
```xml
|
||||
<svg width="100" height="100">
|
||||
<circle cx="50" cy="50" r="20" fill="none" stroke="gray" stroke-width="4" stroke-dasharray="31.4" >
|
||||
<animate attributeName="stroke-dashoffset" from="0" to="31.4" dur="1s" repeatCount="indefinite" />
|
||||
<animateTransform attributeName="transform" type="rotate" from="0 50 50" to="360 50 50"
|
||||
dur="1s" repeatCount="indefinite" />
|
||||
</circle>
|
||||
</svg>
|
||||
```
|
||||
- 점선이 회전하며 로딩 효과를 만듦.
|
||||
|
||||
#### 2. 펄스 효과 (Pulse)
|
||||
```xml
|
||||
<svg width="200" height="200">
|
||||
<circle cx="100" cy="100" r="30" fill="red">
|
||||
<animate attributeName="r" values="30;40;30" dur="1.5s" repeatCount="indefinite" />
|
||||
<animate attributeName="opacity" values="1;0.5;1" dur="1.5s" repeatCount="indefinite" />
|
||||
</circle>
|
||||
</svg>
|
||||
```
|
||||
- 원이 커졌다 작아지며 투명도가 변함.
|
||||
|
||||
---
|
||||
|
||||
### CSS를 활용한 SVG 애니메이션
|
||||
|
||||
CSS는 SVG 요소에 `@keyframes`와 `animation` 속성을 적용해 애니메이션을 구현할 수 있습니다. SMIL보다 브라우저 호환성이 좋습니다.
|
||||
|
||||
#### 예시: 회전 애니메이션
|
||||
```xml
|
||||
<svg width="200" height="200">
|
||||
<rect x="75" y="75" width="50" height="50" fill="blue" class="spin" />
|
||||
</svg>
|
||||
<style>
|
||||
.spin {
|
||||
transform-origin: 100px 100px;
|
||||
animation: rotate 3s infinite linear;
|
||||
}
|
||||
@keyframes rotate {
|
||||
from { transform: rotate(0deg); }
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
</style>
|
||||
```
|
||||
- 사각형이 3초마다 무한 회전.
|
||||
|
||||
#### 장점
|
||||
- CSS 변수로 동적 제어 가능.
|
||||
- 트랜지션과 결합해 부드러운 효과 구현.
|
||||
|
||||
---
|
||||
|
||||
### JavaScript를 활용한 SVG 애니메이션
|
||||
|
||||
JavaScript는 SVG 속성을 동적으로 변경하거나 복잡한 로직을 추가할 때 유용합니다. `setAttribute`나 DOM 조작을 사용합니다.
|
||||
|
||||
#### 예시: 클릭 시 크기 변화
|
||||
```xml
|
||||
<svg width="200" height="200">
|
||||
<circle id="myCircle" cx="100" cy="100" r="30" fill="green" onclick="animateCircle()" />
|
||||
</svg>
|
||||
<script>
|
||||
function animateCircle() {
|
||||
const circle = document.getElementById("myCircle");
|
||||
let r = 30;
|
||||
const animate = () => {
|
||||
r = r === 30 ? 50 : 30;
|
||||
circle.setAttribute("r", r);
|
||||
setTimeout(animate, 1000);
|
||||
};
|
||||
animate();
|
||||
}
|
||||
</script>
|
||||
```
|
||||
- 클릭하면 원의 반지름이 30과 50 사이를 1초 간격으로 전환.
|
||||
|
||||
#### 라이브러리 활용: GSAP
|
||||
복잡한 애니메이션은 GSAP(GreenSock Animation Platform) 같은 라이브러리로 더 쉽게 구현 가능:
|
||||
```javascript
|
||||
gsap.to("#myCircle", { duration: 1, attr: { r: 50 }, repeat: -1, yoyo: true });
|
||||
```
|
||||
- 원이 1초마다 커졌다 작아짐.
|
||||
|
||||
---
|
||||
|
||||
### 결론과 비교
|
||||
|
||||
- **`<animate>`와 `<animateTransform>`**: 간단한 애니메이션에 적합하지만, SMIL 지원이 Chrome에서 제한적(2023년 기준 중단 계획).
|
||||
- **CSS**: 직관적이고 호환성이 뛰어나며, 반응형 디자인에 유리.
|
||||
- **JavaScript**: 복잡한 상호작용이나 동적 제어가 필요할 때 강력. GSAP 같은 도구로 생산성 향상 가능.
|
||||
|
||||
실무에서는 로딩 스피너, 버튼 효과, 데이터 시각화 애니메이션 등에 SVG 애니메이션을 활용하며, 프로젝트 요구사항(호환성, 복잡도)에 따라 적절한 방법을 선택합니다. CSS와 JavaScript를 함께 사용하면 SMIL의 한계를 보완하면서도 풍부한 효과를 낼 수 있습니다.
|
||||
Reference in New Issue
Block a user