<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Custom Countdown</title>
<link rel="icon" type="image/png" href="favicon.png">
<link rel="stylesheet" href="style.css">
</head>
<body>
<!-- Video Background -->
<video class="video-background" id="video-background" loop muted autoplay>
<source src="time.mp4"></source>
</video>
<div class="video-overlay"></div>
<!-- Container -->
<div class="container">
<!-- Input -->
<div class="input-container" id="input-container">
<h1>카운트다운을 만들어 보세요!</h1>
<form class="form" id="countdownForm">
<label for="title">제목</label>
<input type="text" id="title" placeholder="언제부터 세고 싶으세요?">
<label for="date-picker">날짜를 선택하세요.</label>
<input type="date" id="date-picker">
<button type="submit">제출.</button>
</form>
</div>
<!-- Countdown -->
<div class="countdown" id="countdown" hidden>
<h1 id="countdown-title"></h1>
<ul>
<li><span></span>Days</li>
<li><span></span>Hours</li>
<li><span></span>Minutes</li>
<li><span></span>Seconds</li>
</ul>
<button id="countdown-button">RESET</button>
</div>
<!-- Complete -->
<div class="complete" id="complete" hidden>
<h1 class="complete-title">Countdown Complete!</h1>
<h1 id="complete-info"></h1>
<button id="complete-button">NEW COUNTDOWN</button>
</div>
</div>
<!-- Script -->
<script src="script.js"></script>
</body>
</html>
@import url("https://fonts.googleapis.com/css?family=Nunito&display=swap");
html {
box-sizing: border-box;
}
body {
margin: 0;
min-height: 100vh;
overflow-y: hidden;
display: flex;
align-items: center;
font-family: Nunito, sans-serif;
background-color: #c1690a;
}
/* Video Background */
.video-background {
position: fixed;
right: 0;
bottom: 0;
width: 100vw;
height: auto;
}
video {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.video-overlay {
position: fixed;
left: 0;
top: 0;
height: 100vh;
width: 100vw;
background: rgba(255, 255, 255, 0.35);
}
/* Container */
.container {
min-width: 580px;
min-height: 304px;
color: black;
margin: 0 auto;
padding: 25px 50px;
border-radius: 5px;
z-index: 2;
background: rgba(255, 255, 255, 0.85);
display: flex;
justify-content: center;
}
.input-container {
position: relative;
top: 20px;
}
h1 {
font-size: 35px;
text-align: center;
margin-top: 0;
margin-bottom: 10px;
}
/* Form */
.form {
width: 480px;
}
label {
font-weight: bold;
margin-left: 10px;
}
input {
width: 95%;
margin-bottom: 10px;
padding: 10px;
border: 1px solid #ccc;
border-radius: 20px;
background: #fff;
outline: none;
font-family: Nunito, sans-serif;
}
/* Button */
button {
width: 100%;
height: 40px;
border-radius: 20px;
margin-top: 15px;
border: none;
text-transform: uppercase;
background: #006959;
color: white;
cursor: pointer;
outline: none;
}
button:hover {
filter: brightness(110%);
}
/* Countdown */
ul {
margin-left: -45px;
}
li {
display: inline-block;
font-size: 30px;
list-style-type: none;
padding: 10px;
text-transform: uppercase;
}
li span {
display: block;
font-size: 80px;
text-align: center;
}
/* Complete */
.complete {
position: relative;
top: 60px;
}
.complete-title {
animation: complete 4s infinite;
}
@keyframes complete {
0% {
color: rgb(233, 12, 12);
}
25% {
color: rgb(214, 193, 0);
}
50% {
color: rgb(68, 231, 19);
transform: scale(1.5);
}
75% {
color: rgb(19, 79, 209);
}
100% {
color: rgb(188, 16, 211);
}
}
/* Media Query: Large Smartphone (Vertical) */
@media screen and (max-width: 600px) {
video {
object-fit: cover;
object-position: 70%;
margin-top: -1px;
}
.video-background {
height: 100vh;
width: 100vw;
}
.container {
min-width: unset;
width: 95vw;
min-height: 245px;
padding: 20px;
margin: 10px;
}
.input-container {
top: unset;
}
.countdown {
position: relative;
top: 10px;
}
.form {
width: unset;
}
input {
width: 93%;
}
h1 {
font-size: 20px;
}
li {
font-size: 15px;
}
li span {
font-size: 40px;
}
}
//값들.
//기본창.
//전체 입력창.
const inputContainer = document.getElementById('input-container');
//전체 폼.
const countdownForm = document.getElementById('countdownForm');
//날짜 입력창.
const dateEl = document.getElementById('date-picker');
//카운트다운창.
//전체 카운트다운.
const countdownEl = document.getElementById('countdown');
//제목
const countdownElTitle = document.getElementById('countdown-title');
//리셋 버튼
const countdownBtn = document.getElementById('countdown-button');
//시간을 표기하는 숫자들.
const timeElements = document.querySelectorAll('span');
//완료창
//전체 완료창.
const completeEl = document.getElementById('complete');
//완료정보
const completeElInfo = document.getElementById('complete-info');
//완료 버튼.
const completeBtn = document.getElementById('complete-button');
let countdownTitle = '';
let countdownDate = '';
let countdownValue = Date;
let countdownActive;
let savedCountdown;
//시간.
const second = 1000;
const minute = second * 60;
const hour = minute * 60;
const day = hour * 24;
//오늘의 날짜를 date의 최솟값으로 설정해 카운트다운의 기준점을 만든다.
const today = new Date().toISOString().split('T')[0];
dateEl.setAttribute('min', today);
// 문서에 카운트다운 값 채우기. / UI 완성.
function updateDOM() {
countdownActive = setInterval(() => {
//현재시간의 총량을 가져옴.
const now = new Date().getTime();
//선택시간- 현재시간량은 걸리는 기간.
const distance = countdownValue - now;
//시간 계산.
const days = Math.floor(distance / day);
const hours = Math.floor((distance % day) / hour);
const minutes = Math.floor((distance % hour) / minute);
const seconds = Math.floor((distance % minute) / second);
// 입력 숨기기.
inputContainer.hidden = true;
// 카운트다운이 끝나면 최종 실행.
if (distance < 0) {
countdownEl.hidden = true;
clearInterval(countdownActive);
completeElInfo.textContent = `${countdownTitle} finished on ${countdownDate}`;
completeEl.hidden = false;
} else {
// 카운트다운이 진행되는 동안에는 시간이 줄어드는 게 보여야 한다.
countdownElTitle.textContent = `${countdownTitle}`;
timeElements[0].textContent = `${days}`;
timeElements[1].textContent = `${hours}`;
timeElements[2].textContent = `${minutes}`;
timeElements[3].textContent = `${seconds}`;
completeEl.hidden = true;
countdownEl.hidden = false;
}
}, second);
//setinterval의 간격이 초단위로 가면서 초시계 완성!
}
function updateCountdown(e) {
e.preventDefault();
//제목,날짜를 변경, 값을 로컬 저장소에 저장.
countdownTitle = e.srcElement[0].value;
countdownDate = e.srcElement[1].value;
savedCountdown = {
title: countdownTitle,
date: countdownDate,
};
localStorage.setItem('countdown', JSON.stringify(savedCountdown));
// Check if no date entered
if (countdownDate === '') {
alert('날짜를 선택해주세요');
} else {
//선택한 날짜가 가지는 전체 시간.
countdownValue = new Date(countdownDate).getTime();
updateDOM();
}
}
function reset() {
// 카운트다운은 숨기고 입력창은 보이게.
countdownEl.hidden = true;
completeEl.hidden = true;
inputContainer.hidden = false;
// 카운트다운 멈춰!
clearInterval(countdownActive);
//값을 리셋, 로컬 저장소값도 삭제.
countdownTitle = '';
countdownDate = '';
localStorage.removeItem('countdown');
}
function restorePreviousCountdown() {
// 유효값이 있을 경우 저장소에서 날짜를 가져온다.
if (localStorage.getItem('countdown')) {
//값이 있으면 카운트다운 실행.
inputContainer.hidden = true;
savedCountdown = JSON.parse(localStorage.getItem('countdown'));
//parse를 통해 문자값을 변환.
countdownTitle = savedCountdown.title;
countdownDate = savedCountdown.date;
countdownValue = new Date(countdownDate).getTime();
updateDOM();
//저장값으로 카운트다운 실행.
}
}
// Event Listener
//카운트다운에서 입력받으면 다음 창으로 넘어감.
countdownForm.addEventListener('submit', updateCountdown);
countdownBtn.addEventListener('click', reset);
completeBtn.addEventListener('click', reset);
// On Load, check localStorage
restorePreviousCountdown();
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.