본문 바로가기
Javascript

[Javascript] Number Index를 만들어 보자(ft. 숫자 카운트 애니메이션)

by 즐코딩 2022. 11. 24.
반응형

 

몇년 전부터 기업의 홈페이지 메인에

숫자 인덱스로 실적 지표를 보여주는

그런 형태가 유행하는 것 같습니다.

 

대충 이런 식으로요.

 

 

물론 디즈니 플러스의 경우에는

고정된 형태의 숫자이지만,

저 숫자들이 막 올라가는 형태도 많죠.

 

때마침 필요한 기능이기도 해서

한번 만들어 보기로 합니다.

 

 


 

숫자가 막 올라가는 카운트 모션 만들기

 

 

반응형을 고려해서 대략 이렇게

4개 칼럼으로 이루어진 형태를

계획하고 만들어보기로 생각해봅니다.

 

결과물을 예상해서 설계도를 그립니다.

PPT로 만들어도 좋고

연습장에 손으로 그려도 좋습니다.

 

아무튼 목표점이 구체적이어야 할테니까요.

결론은 아래와 같은 모습의 형태.

 

처음부터 다 코딩하려면 쉽지 않죠.

일단 구글링을 시전해봅니다.

 

검색어를 바꿔가며 몇번 시도해봤더니

Jquery로 만들어진 예제들이 좀 나옵니다.

 

최근에는 Jquery 보다

Vanilla Javascrip 사용을 좀더 선호하고

개발자들간에도 유행을 타는 것 같지만

일단은 빠르게 목적지에 도착해보기 위해

제이쿼리든 뭐든 한번 참고해보기로 합니다.

 

일단 공부가 목적이니까요.

 

검색 결과를 하나씩 눌러 내용을 살펴보니

아래 포스팅 내용이 왠지

저의 목적과 잘 맞을 것 같더군요.

 

https://velog.io/@nowyeh/%EC%88%AB%EC%9E%90-%EC%B9%B4%EC%9A%B4%ED%8A%B8-%EC%95%A0%EB%8B%88%EB%A9%94%EC%9D%B4%EC%85%98

 

 

이 예제에 오른쪽으로 1개 칼럼만 더 추가하면 되니

레이아웃도 비슷하게 활용할 수 있겠습니다.

 

일단 HTML/CSS은 이렇게 코딩해봤습니다.

공부해두었던 Flex를 요긴하게 써먹었습니다.

 

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Number Index</title>
    <style>
        .upper_blank {
            height: 300px;
            background: yellowgreen;
            text-align: center;
            padding-top: 200px;
        }
        .num-container {
            display: flex;
            flex-wrap: wrap;
            justify-content: space-around;
            align-items: center;
            padding: 10%;
        }
        .num-item {
            text-align: center;
            padding: 10px;
            margin-bottom: 30px;
        }
        .in-title {
            font: 30px/1 'arial';
            color: gray;
            font-weight: 600;
            margin-bottom: 20px;
        }
        .sub-title {
            font: 14px/1 'arial';
            color: gray;
        }
        .nums {
            font: bold 80px/1 'arial';
            color: #343048;
        }
        #num-unit {
            font: bold 30px/1 'arial';
            color: dimgray;
        }
    </style>
</head>
<body>
    <!-- 숫자 인덱스	 -->
    <div class="num-container" id="num-container">
        <div class="num-item">
            <h4 class="in-title">Index 1</h4>
            <span class="nums" data-count="180">0</span><span id="num-unit">%</span><br>
            <span class="sub-title">이용률 포함</span><br>
        </div>
        <div class="num-item">
            <h4 class="in-title">Index 2</h4>
            <span class="nums" data-count="1143">0</span><span id="num-unit">개</span><br>
            <span class="sub-title">프랜차이즈 매장수</span><br>
        </div>
        <div class="num-item">
            <h4 class="in-title">Index 3</h4>
            <span class="nums" data-count="34">0</span><span id="num-unit">개</span><br>
            <span class="sub-title">직영매장 수</span><br>
        </div>
        <div class="num-item">
            <h4 class="in-title">Index 4</h4>
            <span class="nums" data-count="438.4">0</span><span id="num-unit">%</span><br>
            <span class="sub-title">수익률</span><br>
        </div>
    </div>
</body>
</html>

 

브라우저에서 확인을 하니

이렇게 잘 나타납니다.

 

 

그리고 예제를 참고하여

Javascript를 코딩해주고

<body> 끝나기 전에 앞쪽에 위치시켜줍니다.

 

 

<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.6.0.min.js"></script>
    <script>
        //숫자 카운트 애니메이션
        $('.nums').each(function () {
            const $this = $(this),
                countTo = $this.attr('data-count');

            $({
                countNum: $this.text()
            }).animate({
                countNum: countTo
            }, {
                duration: 3000,
                easing: 'linear',
                step: function () {
                    $this.text(Math.floor(this.countNum));
                },
                complete: function () {
                    $this.text(this.countNum);
                }
            });
        });
    </script>

 

 

저장을 하고 페이지 새로고침을 해보니,

오옷~! 숫자가 잘 올라갑니다!!

신기하군요~

 

 

그런데, 숫자가 좀 이상해 보이는 게,

세자릿수 마다 콤마(,)가 찍혔으면 좋겠습니다.

 

잽싸게 구글링을 해봤더니,

이 이슈의 해결영역은 "정규식" 분야 더라구요.

 

정규식은 나중에 한번 더 자세하게

살펴보면서 공부해보기로 하고

일단 해당 부분 코드를 수정해봅니다.

 

 

원래 출력되던 숫자값들에

 

.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')

 

.toString() 으로 문자열을 반환하고

.replace()로 문자열을 다시 써주되,

 

/\B(?=(\d{3})+(?!\d))/g

 

이라는 정규식에 일치할 때,

,(콤마)를 넣게 됩니다.

 

참고로 replace() 매서드는

replace( 'A', 'B' )처럼 사용되고

'A'를 찾아보고 존재하는 경우

그 자리에 'B'로 교체해주는(=replace)

기능을 합니다.

 

아무튼...

최종 수정된 전체 코드는 다음과 같습니다.

 

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Number Index</title>
    <style>
        .upper_blank {
            height: 300px;
            background: yellowgreen;
            text-align: center;
            padding-top: 200px;
        }
        .num-container {
            display: flex;
            flex-wrap: wrap;
            justify-content: space-around;
            align-items: center;
            padding: 10%;
        }
        .num-item {
            text-align: center;
            padding: 10px;
            margin-bottom: 30px;
        }
        .in-title {
            font: 30px/1 'arial';
            color: gray;
            font-weight: 600;
            margin-bottom: 20px;
        }
        .sub-title {
            font: 14px/1 'arial';
            color: gray;
        }
        .nums {
            font: bold 80px/1 'arial';
            color: #343048;
        }
        #num-unit {
            font: bold 30px/1 'arial';
            color: dimgray;
        }
    </style>
</head>
<body>
    <!-- 숫자 인덱스	 -->
    <div class="num-container" id="num-container">
        <div class="num-item">
            <h4 class="in-title">Index 1</h4>
            <span class="nums" data-count="180">0</span><span id="num-unit">%</span><br>
            <span class="sub-title">이용률 포함</span><br>
        </div>
        <div class="num-item">
            <h4 class="in-title">Index 2</h4>
            <span class="nums" data-count="1143">0</span><span id="num-unit">개</span><br>
            <span class="sub-title">프랜차이즈 매장수</span><br>
        </div>
        <div class="num-item">
            <h4 class="in-title">Index 3</h4>
            <span class="nums" data-count="34">0</span><span id="num-unit">개</span><br>
            <span class="sub-title">직영매장 수</span><br>
        </div>
        <div class="num-item">
            <h4 class="in-title">Index 4</h4>
            <span class="nums" data-count="438.4">0</span><span id="num-unit">%</span><br>
            <span class="sub-title">수익률</span><br>
        </div>
    </div>
    <script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.6.0.min.js"></script>
    <script>
        //숫자 카운트 애니메이션
        $('.nums').each(function () {
            const $this = $(this),
                countTo = $this.attr('data-count');

            $({
                countNum: $this.text()
            }).animate({
                countNum: countTo
            }, {
                duration: 3000,
                easing: 'linear',
                step: function () {
                    $this.text(Math.floor(this.countNum));
                },
                complete: function () {
                    $this.text(this.countNum.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','));
                    //3자리 마다 콤마 표시 적용
                }
            });
        });
    </script>
</body>
</html>

 

최종 결과 브라우저 화면입니다.

제대로 잘 동작합니다.^^

 

 

제 직업은 개발자가 아닌데도,

저는 이런 프로그래밍이

아주 흥미롭고 재미있습니다.

 

앞으로도 꾸준히 공부해서

그간 생각해오던 많은 것들을

직접 만들어보고 싶습니다.

 

즐코딩하세요~!!

 

 

https://app.kincoding.com 

 

WANTED MBTI

MBTI Girl Match a Lovely Girl Friend 당신과 어울리는 사랑스런 여친을 매칭해드립니다.

app.kincoding.com

 

반응형

댓글