count motion ( 숫자 랜덤 카운트 )
숫자가 단계적으로 카운트 되는 것을 간만해 작업해 보았다.
핵심은 배열의 Array.prototype.unshift(), Array.prototype.shift() 그리고 setTimeout() 이다.
HTML
- 테스트 할 숫자 두개정도 준비한다.
<div class="min">0</div>
<div class="max">0</div>
CSS
- 폰트사이즈 및 스타일링은 대충 알아서 적절히 한다.
.min,
.max{line-height:1.4;font-size:30px;font-weight:bold;color:#333;}
JS
- 카운트 모션 함수와 그 모션이 여러개 일 경우를 감안한 함수를 작성한다.
function counterUp( settings ){
var $settings = settings;
var $target =$settings.ele;
var countUpDatas = [];
var countFuncs;
var nums = [];
var delay=$settings.delay || 0.7;
var time=$settings.time || 400;
var divisions = time / delay;
var num = $settings.num;
//콤마가 있는지 체크 정규식
var isComma = /[0-9]+,[0-9]+/.test(num);
num = num.replace(/,/g, '');
// 숫자 목록 생성
for (var i = divisions; i >= 1; i--) {
// int 인 경우 int로 유지
var newNum = parseInt(num / divisions * i);
// 쉼표가있는 경우 쉼표 유지
if (isComma) {
while (/(\d+)(\d{3})/.test(newNum.toString())) {
newNum = newNum.toString().replace(/(\d+)(\d{3})/, '$1'+','+'$2');
}
}
nums.unshift(newNum);
}
countUpDatas=nums;
$target.text('0');
// 완료 될 때까지 번호를 업데이트
function updateNum() {
$target.text( countUpDatas.shift() );
//숫자를 담고 있는 배열 길이가 존재한다면 계속해서 루프 시킴.
if ( countUpDatas.length ) {
setTimeout( countFuncs, delay);
} else {
delete countUpDatas;
countUpDatas=null;
countFuncs=null;
}
}
countFuncs=updateNum;
// 카운트 시작
setTimeout( countFuncs, delay);
}
//실행할 카운트가 여러개일 경우 설정.
function numberMotion( items ) {
if(Object.prototype.toString.call( items )!=='[object Array]'){ return }
for( var i=0;i<items.length;i++){
counterUp( {num:items[i].num, ele:items[i].ele });
}
}
numberMotion( [ {num:'3,120', ele:$('.min') }, {num:'6,032,178', ele:$('.max') }]);
3자리수이상일 경우 내부에서 자동 콤마가 입력되게끔 설정하였다.
대략적인 방식은 numberMotion함수에 전달되는 숫자가 만약 3,000 이라면
2에서 3,000사이의 숫자를 계산된 시간의 수 만큼 루프로 배열에 담아둔다.
예) [12, 23, 25, 36,.........,'2,992', '3,000'] 이런식으로 말이다.
참고로 배열에 숫자가 3자리까지는 number인데 그 4자리 수부터는 문자열로 들어간다.
왜냐하면 정규식( 숫자가 3자리면서 1번이상 반복되는 수)으로 콤마가 들어가겠끔 하였고 콤마+숫자 표현은 결국 문자열이기에 그렇다.
그렇게 저장된 배열( countUpData )을
1. Array내장함수 shift()로 값을 하나씩 가져온다.
2. 그 가져온 값을 dom에 노출시킨다.
1번과 2번을 배열( countUpData )의 길이값(countUpData.length)이 0이 될때까지
루프(재귀방식)시킨다.
( setTimeout을 실행하는 함수 내부에 재호출하여 재귀함수처럼 루프가 된다. )
데모는 아래 주소로 확인할 수 있다.
demo: https://codepen.io/uxicode/pen/qzJKRb