stroke-dasharray와 stroke-dashoffset은 svg를 가지고 animation을 만드는데 활용되곤 합니다.
여기서 다뤄볼 것은 css로만 하는 방법과 javascript로 하는 방법입니다.
먼저, stroke-dasharray와 stroke-dashoffset에 대한 개념부터 확인하고 가겠습니다.
- stroke-dasharray는 점선을 만들어주는 놈이고
- stroke-dashoffset은 어디부터 시작할 것인지 정해주는 놈입니다.
위 circle을 예로 봐보겠습니다.
원의 전체 길이(둘레)는 1359.7597... 입니다. 그리고 시작점은 시계방향 90도 지점부터 입니다.
그리고 이 원은 stroke-dasharray: 100 입니다.
그러므로 dasharray 값은 점선을 만드는 간격을 의미하고 그 간격대로 점선을 만들어주는 것입니다.
사이 간격을 따로 설정할 수도 있는데, 위 원은 stroke-dasharray: 100 20 으로 설정되었습니다.
뒤의 숫자(20)가 점선의 간격을 의미합니다.
이 원은 stroke-dasharray: 100, stroke-dashoffset: 100 입니다.
offset이 시작점을 정해주는 것이므로, 100만큼 띄운 이후에 100씩 간격을 두고 점선을 만듭니다.
그래서 두번째 원과 비교해보면 흰 부분과 파란부분이 뒤바뀌어 있는 것을 볼 수 있습니다.
그래서, 이것을 가지고 어떻게 animation을 만드는지 봐보겠습니다.
1. css로 animation 만들기
dasharray를 원 둘레로 설정해놓고
animation 속성을 적용하면 끝입니다.
샘플 코드에서는 offset을 둘레의 2배로 설정해두어 animation이 끊기지 않도록 했습니다.
아래는 관련 코드입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
<head>
<style>
.moving-outline circle {
stroke-dasharray: 1360;
animation: dash 2s linear infinite;
}
@keyframes dash {
to {
stroke-dashoffset: 2720;
}
}
</style>
</head>
<body>
<svg
class="moving-outline" width="453" height="453"
viewBox="0 0 453 453" fill="none" xmlns="http://www.w3.org/2000/svg"
>
<circle
cx="226.5" cy="226.5" r="216.5"
stroke="#018EBA" stroke-width="20"
/>
</svg>
</body>
|
cs |
2. js로 animation 만들기
원리는 간단합니다.
dasharray를 원 전체의 둘레로 해놓고 offset을 전체부터 시작해서 조금씩 줄여가는 것입니다.
dasharray를 설정해놓지 않으면 offset이 먹히지 않습니다.
1) 원 둘레 구하기
2) dasharray를 원 둘레로 설정
3) 시간 흐름에 따라 dashoffset 값 늘리기(코드에서는 10ms 마다)
아래는 관련 코드입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
<body>
<svg class="moving-outline" width="453" height="453" viewBox="0 0 453 453"
fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="226.5" cy="226.5" r="216.5"
stroke="#018EBA" stroke-width="20"/>
</svg>
<script>
const outline = document.querySelector(".moving-outline circle");
const outlineLength = outline.getTotalLength();
outline.style.strokeDasharray = outlineLength;
outline.style.strokeDashoffset = 0;
let duration = 60;
let elapsed = 0;
animate(elapsed);
function animate(offset) {
setTimeout(() => {
elapsed++;
if (elapsed > duration * 2) elapsed = 0;
animate((elapsed / duration) * outlineLength);
}, 10);
outline.style.strokeDashoffset = offset;
}
</script>
</body>
|
cs |
'Web > HTML, CSS, Javascript' 카테고리의 다른 글
[CSS] position (static, absolute, relative, sticky, fixed) (0) | 2020.06.26 |
---|---|
[Javascript] requestAnimationFrame (0) | 2020.06.24 |
[CSS] 단위 (rem/em, vh/vw, vmin/vmax) (0) | 2020.06.19 |
[Javascript] 배열 다루기(map, filter, find, every, some, reduce, forEach) (0) | 2020.06.17 |
[CSS] Grid (0) | 2020.06.17 |