STUDY/javascript

rolling text number animation (수정 ES6 버전)

수밤바 2021. 5. 17. 22:59
728x90

해당 소스를 최근에 사용할 일이 있어 차용해보니

jquery가 섞여있어 최신 문법으로 리펙토링 했다

훨씬 코드가 줄어들었고 slide 여부를 동일한 방법으로 작성하고 css transition 유무로 구분지었다

 

콤마 적용방법도 정규식을통해 미리 콤마를 찍어두고 숫자와 동일하게 롤링시켰다

 

new source

 

 

 

 

new RollingNum('.countTest1','123000','slide');
new RollingNum('.countTest2','123000');


function RollingNum(className, number, type) {
    const speed = 100
    const delay = 300
    const el = document.querySelector(className);
    const num = number.replace(/\B(?<!\.\d*)(?=(\d{3})+(?!\d))/g, ",").split('')
    num.forEach((item,i)=>{
        const classId= item==','? `num-idx-${i}-point` : `num-idx-${i}-${item}`
        const text = item
        const slideStyle = 'transition: margin .3s'
        el.innerHTML += `<span class="num ${classId}" data-text="${text}">
                <span class="num-list" style="${type=='slide'? slideStyle : ''}">0 1 2 3 4 5 6 7 8 9 ,</span>
            </span>`

        setTimeout(()=>{
            numAnimate(`.${classId}`)
        }, delay*i)
    })
    
    function numAnimate(unit){
        const el = document.querySelector(className).querySelector(unit)
        const numList = el.querySelector('.num-list')
        const dataText = el.getAttribute('data-text')
        const pos = dataText == ',' ? 10 : dataText
        let n = 0;
        const numInterval = setInterval(()=>{
            numList.style.marginTop= `-${n*30}px`
            if (n >= 10) {
                clearInterval(numInterval)
                numList.style.marginTop= `-${pos*30}px`
            }
            n++
        },speed)
    }
}

 

 

 

 

 

===== 구버전

 

 

span num 안의 숫자는 설정한 speed로 0부터 9까지 바뀌고 난 다음 각 위치의 숫자가 최종적으로 노출된다.

모든 숫자가 노출된 후 num의 3자리 단위마다 ,(콤마)를 찍어준다.

 

1234를 적용한다고 하면 아래와 같은 결과가 나온다

<script>
 new RollingNum('countTest1','1234');
</script>

<div id="countTest1">
 <span class="num idx3" data-num="1">1</span>
 <span class="point">,</span>
 <span class="num idx2" data-num="2">2</span>
 <span class="num idx1" data-num="3">3</span>
 <span class="num idx0" data-num="4">4</span>
</div>

 

 

span에 각 자리수 class와 최종 출력되어야 할 숫자를 data-num에 담아서 정의되어있는 id안에 넣어준다.

var $cntBox = document.getElementById(id);
var $cntNum = number;
var $cntLen = $cntNum.length;
var $numArr=$cntNum.split('');

// 카운트
for ( var i=0; i<$cntLen; i++){
	var bckI = ($cntLen - i*1) -1;
	var num = document.createElement('span');
	num.classList.add('num', 'idx'+bckI);
	num.setAttribute('data-num',$numArr[i]);
	
	$cntBox.append(num);
	setNum (num, i);
}

 

1. span안에 0부터 9까지 speed 간격으로 변경해주며

2. 숫자가 9가 되면 interval을 clear해주고

3. 그 자리에 맞는 숫자(data-num에 넣어둔 숫자)를 마지막으로 넣어준다.

function setNum (el, n){
	setTimeout(function(){
		var bckN = ($cntLen - n*1) -1;
		var no=0;
		var intervalNo = setInterval(function(){
			el.innerText = no++;
			if(no == 10) {
				clearInterval(intervalNo);
				el.innerText = el.getAttribute('data-num');
			}
		},speed);
	}, delay*i);
}

 

마지막으로 3의 배수마다 콤마(,)처리

1. 해당 id의 3의배수인 span.idx3n 마다 그 뒤에 span.point를 추가해준다.

2. setTimeout으로 모든 숫자 롤링이 끝난후 span.point에 콤마(,)를 넣어준다.

//,처리
if ($cntLen>3) {
	for (var i=1; i<=Math.floor($cntLen/3); i++) {
		var idx3n = $cntBox.querySelector('.idx'+i*3);
		var span = document.createElement('span');
		span.classList.add('point');
		idx3n.after(span);
	}
	setTimeout(function(){
		var point = $cntBox.querySelectorAll('.point');
		point.forEach(el => {
			el.innerText=','
		});
	},(speed*10) + ($cntLen * delay));
};

 

 

prototype으로 만들어 다중으로 실행될수 있도록 처리.

function RollingNum(id, number) {
...
}

new RollingNum('countTest1','1234');
new RollingNum('countTest2','5912307');

 

 

최종 실행 화면