-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
278 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
# Day 29 Countdown Timer | ||
|
||
I added some buttons for more functionally when using a custom timer. You can play and add new buttons for later use. | ||
|
||
## Attribution | ||
* none | ||
|
||
|
||
## Key Topics | ||
* We used the date object and its properties to grab current date and grab user input to calculate the end time and the countdown for the timer. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<title>Countdown Timer</title> | ||
<link rel="stylesheet" href="../normalize.css"> | ||
<link rel="stylesheet" href="../reset.css"> | ||
<link rel="stylesheet" href="style.css"> | ||
<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=Concert+One&display=swap" rel="stylesheet"> | ||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons+Round" rel="stylesheet"/> | ||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@24,400,0,0" /> | ||
<script src="script.js" defer></script> | ||
</head> | ||
<body> | ||
<a href="../" alt="Home"><span class="material-icons-round home">home</span></a> | ||
<p class="instructions">Default value is minutes, but you can specify hours with 'hours:minutes' format, and seconds with 'hours:minutes:seconds' <br> | ||
Preceding values are optional, but you must include the colons for accurate formatting (ex: '::30' represents 30 secs). | ||
</p> | ||
<form name="customForm" id="custom"> | ||
<label class="timer-label" for="timer-input">Custom timer</label> | ||
<input type="text" name="timer-input" placeholder="Enter Minutes"> | ||
<button class="play-timer"> | ||
<span class="material-symbols-rounded timer-icon">timer_play</span> | ||
</button> | ||
<button class="add-timer"> | ||
<span class="material-symbols-rounded timer-icon">alarm_add</span> | ||
</button> | ||
</form> | ||
<div class="display"> | ||
<h1 class="timer">Please select or add a timer</h1> | ||
<p class="end-time"></p> | ||
</div> | ||
<div class="selection"> | ||
<button data-time = "::30">30 secs</button> | ||
<button data-time = "1">1 min(s)</button> | ||
<button data-time = "5">5 min(s)</button> | ||
<button data-time = "15">15 min(s)</button> | ||
<button data-time = "20">20 min(s)</button> | ||
<button data-time = "1:">1 hour</button> | ||
</div> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
const timer = document.querySelector('.timer'); | ||
const endTimer = document.querySelector('.end-time'); | ||
const buttons = document.querySelectorAll("[data-time]"); | ||
const timerInput = document.querySelector('[name="timer-input"]'); | ||
console.log(typeof timerInput.value); | ||
console.log(buttons); | ||
function parseTime(time){ | ||
let hours = 0, minutes = 0, seconds = 0; //initialize | ||
|
||
parts = time.split(':').map(Number).reverse(); | ||
|
||
switch(parts.length){ | ||
case 3: | ||
[seconds, minutes, hours] = parts; | ||
break; | ||
case 2: | ||
[minutes, hours] = parts; | ||
break; | ||
default: | ||
[minutes] = parts; | ||
break; | ||
} | ||
|
||
console.log(hours); | ||
console.log(minutes); | ||
console.log(seconds); | ||
return hours * 3600 + minutes * 60 + seconds; | ||
} | ||
|
||
|
||
let countdown; /* startTimer('::3'); */ | ||
|
||
function parseData(){ | ||
const time = this.dataset.time; | ||
startTimer(time); | ||
} | ||
function startTimer(time){ | ||
clearInterval(countdown); | ||
console.log(time); | ||
let seconds = parseTime(time); | ||
console.log('time', time); | ||
console.log(seconds); | ||
/* console.log(seconds); */ | ||
const endTime = Date.now() + seconds * 1000; //because date.now returns in ms, we have to convert our seconds to ms | ||
|
||
displayTimeLeft(seconds); | ||
displayEndTime(endTime); | ||
|
||
countdown = setInterval(() => { | ||
/* let secondsLeft = Math.round((endTime - Date.now()) / 1000); */ | ||
|
||
if(seconds <= 0){ | ||
timer.textContent = 'Please select or add a timer'; | ||
endTimer.textContent = ''; | ||
clearInterval(countdown); | ||
return; | ||
} | ||
seconds --; | ||
displayTimeLeft(seconds); | ||
}, 1000); | ||
} | ||
|
||
function displayTimeLeft(seconds){ | ||
const hoursLeft = Math.floor(seconds / 3600); | ||
const minutesLeft = Math.floor((seconds / 60) % 60); | ||
const secondsLeft = seconds % 60; | ||
|
||
// Pad each time unit with leading zeros to ensure two digits | ||
const paddedHoursLeft = String(hoursLeft).padStart(2, "0"); | ||
const paddedMinutesLeft = String(minutesLeft).padStart(2, "0"); | ||
const paddedSecondsLeft = String(secondsLeft).padStart(2, "0"); | ||
|
||
const timeLeft = | ||
hoursLeft > 0 | ||
? `${paddedHoursLeft}:${paddedMinutesLeft}:${paddedSecondsLeft}` | ||
: `${minutesLeft}:${paddedSecondsLeft}`; | ||
timer.textContent = timeLeft; | ||
} | ||
function displayEndTime(time){ | ||
const end = new Date(time); | ||
const timeConfig = {hour: 'numeric', minute: '2-digit'}; | ||
endTimer.textContent = `Be Back At ${end.toLocaleTimeString(navigator.language, timeConfig)}`; | ||
} | ||
|
||
buttons.forEach((button) => button.addEventListener("click", parseData)); | ||
|
||
|
||
document.querySelector('.play-timer').addEventListener('click', (e) =>{ | ||
e.preventDefault(); | ||
startTimer(timerInput.value); | ||
timerInput.value = ''; | ||
}); | ||
|
||
document.querySelector('.add-timer').addEventListener('click', (e) =>{ | ||
e.preventDefault(); | ||
addButton(timerInput.value); | ||
timerInput.value = ''; | ||
}) | ||
document.customForm.addEventListener('submit', function(e) { | ||
e.preventDefault(); | ||
startTimer(timerInput.value); | ||
timerInput.value = ''; | ||
}); | ||
|
||
function addButton(time){ | ||
const button = document.createElement('button'); | ||
button.setAttribute('data-time', time); | ||
const timeParse = time.split(':').map(str => str.padStart(2, "0")).join(':'); | ||
button.textContent = timeParse; | ||
button.addEventListener('click', parseData); | ||
document.querySelector('.selection').appendChild(button); | ||
} | ||
/* | ||
function parseTimeString(timeString) { | ||
const timeParts = timeString.split(":").map(Number); | ||
const [seconds, minutes, hours] = [0, 0, 0]; // Default values | ||
if (timeParts.length === 3) { | ||
[hours, minutes, seconds] = timeParts; | ||
} else if (timeParts.length === 2) { | ||
[minutes, seconds] = timeParts; | ||
} else if (timeParts.length === 1) { | ||
[seconds] = timeParts; | ||
} | ||
return { hours, minutes, seconds }; | ||
} */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
*{ | ||
box-sizing: border-box; | ||
|
||
} | ||
html, body{ | ||
height: 100%; | ||
} | ||
html{ | ||
font-family: "Concert One", sans-serif; | ||
font-weight: 400; | ||
text-align: center; | ||
color: white; | ||
background: rgb(231, 230, 157); | ||
} | ||
body{ | ||
height: 100%; | ||
display: flex; | ||
flex-direction: column; | ||
justify-content: center; | ||
align-items: center; | ||
gap: 40px; | ||
} | ||
|
||
.home{ | ||
position:fixed; | ||
top:0; | ||
left: 0; | ||
padding: 1%; | ||
color:rgb(35, 51, 67); | ||
} | ||
|
||
.instructions{ | ||
color: rgb(110, 53, 53) | ||
} | ||
|
||
.display{ | ||
padding: 5% 2%; | ||
font-size: 2rem; | ||
width: 500px; | ||
height: 300px; | ||
background: rgb(35, 51, 67); | ||
border: 10px solid rgb(18, 34, 49); | ||
outline: 5px solid rgb(35, 51, 67); | ||
border-radius: 15px; | ||
/* box-shadow: inset 0 0 10px rgb(106, 190, 179); */ | ||
display: flex; | ||
flex-direction: column; | ||
justify-content: center; | ||
align-items: center; | ||
} | ||
|
||
.display .timer{ | ||
max-width: 100%; | ||
font-size: 4rem; | ||
margin-bottom: 10px; | ||
} | ||
|
||
.selection{ | ||
width: 70%; | ||
display: flex; | ||
justify-content: center; | ||
flex-wrap: wrap; | ||
gap: 10px; | ||
} | ||
form{ | ||
max-width: 70%; | ||
border: solid rgb(35, 51, 67); | ||
border-radius: 5px; | ||
display: flex; | ||
font-size: 2rem; | ||
} | ||
|
||
.material-symbols-rounded.timer-icon{ | ||
font-size: 3rem; | ||
vertical-align: middle; | ||
} | ||
button, label{ | ||
background: rgb(35, 51, 67); | ||
font-size: 2rem; | ||
border-radius: 5px; | ||
color: white; | ||
} | ||
input{ | ||
width: 100%; | ||
text-align: center; | ||
color:rgb(35, 51, 67); | ||
} | ||
label{ | ||
display: flex; | ||
align-items: center; | ||
border-radius: 5px 0 0 5px; | ||
padding: 0 5px; | ||
} | ||
form label, form button{ | ||
border-radius: 0; | ||
} |