JSFiddle - React, Tailwind, and code Playground

by Felipe Alfaro

HTML

<input id="num" type="number">
<button id="countNow">Count now</button>

<div id="test" class="spinnerCircle" data-counting="false">
    <div><span></span></div>
    <div><span></span></div>
    <p></p>
</div>

CSS

.spinnerCircle{
    width: 26px;
    height: 26px;
    overflow: hidden;
    background: white;
    border-radius: 50%;
    position: relative;
}
.spinnerCircle p{
    display: block;
    position: absolute;
    width: calc(100% - 4px);
    height: calc(100% - 4px);
    left: 2px; top: 2px;
    background: white;
    border-radius: 50%;
    padding: 0;
    margin: 0;
    text-align: center;
    line-height: 22px;
}
.spinnerCircle > div{
    float: left;
    position: relative;
    width: 50%;
    height: 100%;
    background: transparent;
    top: 0;
    overflow: hidden;
}
.spinnerCircle > div > span{
    background: green;
    display: block;
    width: 100%;
    height: 100%;
    transform: rotate(-180deg);
}
.spinnerCircle div:first-child{
    left: 0;
}
.spinnerCircle div:last-child{
    right: 0;
}
.spinnerCircle div:nth-child(1) span{
    transform-origin: center right;
    border-radius: 26px 0 0 26px;
    
}
.spinnerCircle div:nth-child(2) span{
    transform-origin: center left;
    border-radius: 0 26px 26px 0;
}

JavaScript

var timer;
function spinCounter(el,userSeconds){

	var spans = el.getElementsByTagName('span'),
        frontCounter = el.getElementsByTagName('p')[0];
        
	if( el.getAttribute('data-counting')=='true' ){
    	clearInterval(timer);
        [].forEach.call(spans,function(span){
            span.style.transition = '0ms linear';
            span.style.transform = 'rotate(-180deg)';
        });
    }
    
    var time = Number(userSeconds)*1000,
        halfTime = time/2,
        lastTime = time/1000;
        
    el.setAttribute('data-counting',true);
    
    timer = setInterval(function(){
        lastTime -= 1;
        frontCounter.innerText = lastTime;
        if( lastTime <= 0 ){
            frontCounter.innerText = '';
            [].forEach.call(spans,function(span){
                span.style.transition = '0ms linear';
                span.style.transform = 'rotate(-180deg)';
            });
            el.setAttribute('data-counting',false);
            clearInterval(timer);
        }
    },1000);
    
    frontCounter.innerText = lastTime;
    setTimeout(function(){
    	
    },0);
    spans[0].style.transition = halfTime+'ms linear';
    spans[1].style.transition = halfTime+'ms linear';
    spans[1].style.transform = 'rotate(0)';
    var rotate_2 = setTimeout(function(){
        spans[0].style.transform = 'rotate(0)';
    },halfTime);
};


var _input = document.getElementById('num'),
	_button = document.getElementById('countNow'),
    _spinner = document.getElementById('test');

_button.onclick = function(){
	console.log(_input.value);
	spinCounter(_spinner,_input.value);
}