가능세계
카운트 업 애니메이션 구현하기(Count Up Animation with JavaScript) 본문
이번 포스팅에서는 지정된 숫자까지 숫자가 증가하는 애니메이션을 구현해봅시다.
간단한 JavaScript로 만들 수 있습니다.
뒤에서는 스크롤에 따라 카운트 업 애니메이션이 재생되는 응용도 해볼 것입니다.
HTML부터 시작해봅시다
사용자 정의 data-*
속성을 사용해 HTML 요소에 데이터를 저장해둡니다.
이렇게 하면 자바스크립트에서 해당 데이터에 접근할 수 있습니다.
<ul class="counter-container">
<li class="counter-item">
<strong class="counter" data-target="12000"></strong>
</li>
<li class="counter-item">
<strong class="counter" data-target="9999"></strong>
</li>
<li class="counter-item">
<strong class="counter" data-target="5000"></strong>
</li>
</ul>
자바스크립트를 추가해볼까요
- 먼저 counter의 값을 0으로 초기화합니다.
- targetNum 변수는 목표 숫자입니다.
getAttribute()
메서드를 사용해 해당 요소에 저장된data-target
속성의 값을 가져옵니다.
이때+
를 달아주어 정수로 파싱합니다.
const counters = document.querySelectorAll(".counter");
counters.forEach((counter) => {
// 초기 카운터 값 설정
counter.textContent = "0";
// 목표 숫자 가져오기
const targetNum = +counter.getAttribute("data-target");
// 나머지 코드...
});
이제 카운터를 업데이트하는 함수를 살펴봅시다.
- increment 변수는 증가량입니다. targetNum / 100에서
100
부분을 조정하여 속도감을 나타낼 수 있습니다. - nextCount 변수는 increment만큼 증가하여 다음에 표시될 값입니다.
const updateCounter = () => {
// 현재 카운터 값 가져오기
const count = +counter.textContent;
// 카운터 값을 점진적으로 증가시키기
const increment = targetNum / 100;
const nextCount = Math.ceil(count + increment);
// 나머지 코드...
};
이제 counter에 숫자를 넣어줄 것입니다.
- 표시되는 값이 목표 숫자를 초과한다면 목표 숫자를 초과하지 않도록 targetNum으로 설정하고, 그렇지 않다면 nextCount로 설정합니다.
- 그리고 현재 카운트 숫자가 목표 숫자보다 작은 경우에만 카운트 업 애니메이션을 진행합니다.
const updateCounter = () => {
// 이전 코드...
// 목표 숫자를 초과하지 않도록 설정
counter.textContent = nextCount > targetNum ? targetNum : nextCount;
// 애니메이션 실행
if (count < targetNum) {
requestAnimationFrame(updateCounter);
}
};
마지막으로 updateCounter 함수를 호출해서 애니메이션을 구현합니다.
아래는 자바스크립트 전체 코드입니다.
const counters = document.querySelectorAll(".counter");
counters.forEach((counter) => {
// 초기 카운터 값 설정
counter.textContent = "0";
// 목표 숫자 가져오기
const targetNum = +counter.getAttribute("data-target");
// 카운터 업데이트 함수
const updateCounter = () => {
// 현재 카운터 값 가져오기
const count = +counter.textContent;
// 카운터 값을 점진적으로 증가시키기
const increment = targetNum / 100;
const nextCount = Math.ceil(count + increment);
// 목표 숫자를 초과하지 않도록 설정
counter.textContent = nextCount > targetNum ? targetNum : nextCount;
// 애니메이션 실행
if (count < targetNum) {
requestAnimationFrame(updateCounter);
}
};
updateCounter();
});
✨ 완성된 코드를 확인하세요
See the Pen count up animation js by cona-tus (@cona-tus) on CodePen.
스크롤 애니메이션과 함께 사용해봐요
응용해봅시다. 카운트 업 애니메이션이 스크롤에 따라 자동 재생되도록 해볼까요?
Intersection Observer를 사용해서 해당 요소가 뷰포트에 들어왔는지 아닌지 감지합니다.
isIntersecting
으로 뷰포트에 들어온 경우에 카운트 업 애니메이션이 작동하도록 만듭니다.
이때 entry의 textContent를 0으로 초기화해주어야 다시 재생된답니다.
const counters = document.querySelectorAll(".counter");
entries.forEach(entry => {
entry.target.textContent = '0';
// 뷰포트에 들어온 경우 실행됩니다.
if (entry.isIntersecting) {
const targetNum = +entry.target.getAttribute('data-target');
const updateCounter = () => {
const count = +entry.target.textContent;
const increment = targetNum / 100;
const nextCount = Math.ceil(count + increment);
entry.target.textContent = nextCount > targetNum ? targetNum : nextCount;
if (count < targetNum) {
requestAnimationFrame(updateCounter);
}
};
updateCounter();
}
});
}, { threshold: 0.3 }); // 뷰포트에 요소가 30% 이상 들어올 때 실행합니다.
// 각 카운터 요소에 IntersectionObserver를 등록합니다.
counters.forEach((counter) => {
counterObserver.observe(counter);
});
스크롤 애니메이션에 대해 자세히 알아보고 싶다면?
✨ 완성된 코드를 확인하세요
See the Pen count up animation js by cona-tus (@cona-tus) on CodePen.