[jQuery] 숫자 카운팅 효과 (Counting)

choii_ii·2025년 2월 4일

[jQuery] 스터디노트

목록 보기
6/6
post-thumbnail

📌 KEY POINT

💚 해당 슬라이드에 도달 시, 숫자 카운팅 스크립트 동작
💚 숫자 증가 과정을 steps로 나누어, 주어진 duration 내에서 자연스럽고 일정한 속도로 숫자가 증가하도록 세분화
💚 숫자가 점진적으로 증가하는 애니메이션을 구현할 때 setInterval()을 활용하면 쉽게 구현 가능!


👉🏻 마크업은 이렇게! (HTML5)

🩵 마크업 시, 시작값으로 써주는 것이 일반적
🩵 초기 로딩 시 자연스러운 상태를 유지하기 위함

<body>
<h2 class="main-vis__maintitle yellow counter">279,000</h2>
</body>

👉🏻 스크립트는 이렇게! (jQuery)

🩵 코드 미리보기

<script>
function startCounting() {
    startCounter('#counter', 279000, 2396445, 2000);
}

function startCounter(selector, start, end, duration) {
	const counterEl = document.querySelector(selector);

    const totalCount = end - start; // 증가해야 할 숫자의 범위
    const interval = 30; // 숫자가 변경될 간격 (밀리초 단위)
    const steps = Math.floor(duration / interval); // 전체 애니메이션 진행 횟수
    let currentStep = 0; // 현재 진행 중인 스텝 수

    // 선택한 모든 요소에 대해 카운팅 애니메이션 실행
    const counter = setInterval(function() {
        currentStep++;
        const currentCount = start + Math.round(totalCount * (currentStep / steps));  
       
        counterEl.innerHTML = currentCount.toLocaleString();
        
        if (currentStep >= steps) {
            clearInterval(counter);
        }
    }, interval);
}
</script>

🩵 startCounting() 함수

<script>
function startCounting() {
    startCounter('#counter', 279000, 2396445, 3000);
    // startCounter('요소', '시작값', '종료값', '지속시간');
}
</script>

🩵 startCounter() 함수에 전달할 인수를 정의
🔹 .counter 클래스를 가진 모든 요소에서 카운팅 애니메이션을 시작
🔹 숫자가 279,000부터 2,396,445까지 증가하며, 애니메이션 지속 시간은 2초(2000ms)

🩵 startCounter() 함수 선언 (카운트 증가 방식)

🩵 totalCount = end - start : 증가해야 할 숫자의 범위
🔹 2,396,445 - 279,000 = 2,117,445

🩵 interval = 30 : 숫자가 변경될 간격을 30ms(0.03초)로 설정
🔹 너무 짧은 간격이면 부드럽지 않고, 너무 길면 끊기는 느낌이 들 수 있다.

🩵 steps = Math.ceil(duration / interval) : 전체 애니메이션을 몇 단계로 나눌 것인지 계산
🔹 3000ms / 50ms = 60번
🔹 Math.ceil() : 소수점을 올림하여 가장 가까운 정수를 반환
🔹 남은 간격을 고려하여 더 많은 단계를 생성할 수 있기 때문에, 카운팅이 종료될 때 더 정확한 값에 도달할 수 있다고 한다. (소수점이하 자리가 발생할 경우를 대비하여 올림처리)

🚫 숫자가 무조건 1씩 증가하면 너무 느리고, 너무 크게 증가하면 부자연

🚫 Math.floor()를 사용하여 내림을 하면 소수점 반올림이 일관되지 않게 적용되어 목표 값을 정확히 찍지 못할 수 있어, 남는 시간이 버려지게 되거나 부족하게 계산될 수 있다. 따라서 end값에 더 정확하게 도달할 수 있는 ceil을 사용하여 올림을 했습니다.

🩵 currentStep = 0 : 현재 진행 중인 단계

🩵 setInterval()을 이용한 숫자 증가

🩵 currentStep++ : 1씩 증가

🩵 currentCount = start + Math.round(totalCount * currentStep / steps)
🔹 처음에는 279000 + (2117445 1 / 60) = 314907
🔹 두 번째는 279000 + (2117445
2 / 60) = 350815
🔹 이렇게 종료값(2,396,445)까지 점점 증가
🔹 Math.round() : 반올림하여 오차가 조금씩 발생할 수 있지만, 일반적으로 end 값에 거의 정확히 도달

🚫 duration만으로 카운팅을 조절하면, 정확한 증가 단위, 간격 유지가 어렵고, 설정한 2초보다 긴 시간동안 카운팅이 되었다. 따라서 애니메이션을 진행시킬 단계를 계산한 후, 증가해야 할 범위(totalCount)를 steps로 나눠서 일정한 속도로 증가하도록 계산식을 작성

💡 프레임 단위(interval)로 나누어 숫자가 부드럽게 증가하도록 최적화한 코드!

🩵 counterEl.innerHTML = currentCount.toLocaleString();
🔹 .innerHTML : HTML 요소의 내용을 변경
🔹 .toLocaleString() : 숫자를 1,234,567과 같은 형식으로 표시해 가독성 향상

🩵clearInterval()을 이용한 카운트 종료

🩵 currentStep이 steps 값에 도달하면 clearInterval(counter)를 호출하여 애니메이션을 중지


🥨 한 줄 기록

만약 속도를 더 빠르게 설정하고 싶다면, duration을 낮추고, interval 값을 줄여 결과적으로 steps을 줄이면 된다.
interval 값은 작아질수록 더 자주 숫자가 변경되므로 속도가 체감상 빨라진다.

profile
퍼블리셔 / 작업 기로끄v

0개의 댓글