counter
by Soya Natsuki
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.2.0/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.2.0/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.4/moment-with-locales.min.js"></script>
<!DOCTYPE HTML>
<html>
<head>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR&display=swap" rel="stylesheet">
</head>
<body>
<div class="content">
<div class="row">
<div class="col-12">
<div class="card image-card">
<img src="http://soya.moe:463/CDN/SOYA_Stamp.png" class="card-img-top" alt="soyanyan stamp">
<div class="card-body">
<h5 class="fw-bold text-muted">
소야냥은 얼마나 기다려야 될까요?
</h5>
<p class="card-text text-muted">혀니가 일하는동안 소야냥은 졸음을 참으면서 기다리고 있습니다. 오늘은 언제까지 기다려야 될까요?</p>
<div class="form-group">
<label for="end-time fw-bold text-muted">종료시간</label>
<input type="datetime-local" class="form-control" id="end-time" />
</div>
<div class="text-center mt-3 text-muted counter">
00시간 00분 00초
</div>
</div>
<div class="card-footer bg-white d-flex">
<button type="button" class="btn btn-outline-success flex-fill me-1 set-timer">
타이머 설정
</button>
<button type="button" class="btn btn-outline-danger flex-fill reset-timer">
타이머 리셋
</button>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
CSS
body {
height: 100vh;
padding: 0;
margin: 0;
box-sizing: border-box;
font-family: 'Noto Sans KR', sans-serif;
background-color: #ccc;
}
.content {
height: 100%;
display: flex;
align-items: center;
justify-content: center;
padding: 5rem;
}
.image-card {
width: 25rem;
}
.card-footer {
padding-top: 0.75rem;
padding-bottom: 0.75rem;
}
label {
margin-bottom: 0.25rem;
}
.counter {
border-radius: 5px;
border: 1px rgba(0, 0, 0, 0.175) solid;
padding: 1rem 0;
font-size: 2rem;
}
JavaScript
let timer, timerFlag
// on document ready
$(function() {
// set timer
$('.set-timer').on('click', function() {
// if timer already executed
if(timerFlag) return
// get input
const end = $('#end-time').val().replace('T', ' ')
// check input
if (end === '') return
// loop
timerFlag = true
timer = setInterval(() => {
// format input
const today = moment()
const to = moment(`${end}:00`)
// format output
const hours = moment.duration(to.diff(today)).hours()
const minutes = moment.duration(to.diff(today)).minutes()
const seconds = moment.duration(to.diff(today)).seconds()
// check end condition
if (hours === 0 && minutes === 0 && seconds === 0) {
// reset timer
clearInterval(timer)
timerFlag = false
// reset input & output
reset()
// show message
alert('혀니가 돌아올 시간이에요!')
}
// render result
$('.counter').html(`${hours}시간 ${minutes}분 ${seconds}초`)
}, 1000)
})
// reset timer
$('.reset-timer').on('click', function() {
// reset timer
clearInterval(timer)
timerFlag = false
// reset input & output
reset()
})
})
// reset input and output
function reset() {
// reset input
$('#end-time').val('')
// reset counter
$('.counter').html('00시간 00분 00초')
}