-
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
1 parent
4edb192
commit 2d5ea3f
Showing
3 changed files
with
295 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,42 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
|
||
<head> | ||
<meta charset="UTF-8" /> | ||
<meta http-equiv="X-UA-Compatible" content="IE=edge" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
<title>Document</title> | ||
<link rel="stylesheet" href="style.css" /> | ||
<script defer src="javascript.js"></script> | ||
</head> | ||
|
||
<body> | ||
<section> | ||
<div class="stopwatch" id="stopwatch"> | ||
<header> | ||
<!-- <img src="./asset/timer_black_24dp.svg" alt="" /> --> | ||
<h1>Stopwatch</h1> | ||
</header> | ||
<div class="timer" id="timer"> | ||
<h1 id="minute" class="minute">00</h1> | ||
<div class="colon"></div> | ||
<h1 id="second" class="second">00</h1> | ||
<div class="colon"></div> | ||
<h1 class="millisecond">00</h1> | ||
</div> | ||
<div class="ctaBtns" id="ctaBtns"> | ||
<button class="startBtn" id="start" data-value="start ">Start</button> | ||
<button class="reset" id="reset" data-value="stop ">Reset</button> | ||
<button id="lap" class="lapBtn" data-value="lap ">Lap</button> | ||
</div> | ||
<div class="lapsCont"> | ||
<header> | ||
<p>Laps</p> | ||
</header> | ||
<div class="laps" id="laps"></div> | ||
</div> | ||
</div> | ||
</section> | ||
</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,137 @@ | ||
function StopWatch(element, action) { | ||
this.element = | ||
element instanceof Element ? element : document.querySelector(element); | ||
|
||
this.action = action; | ||
|
||
let startTime = null; | ||
let isRunning = false; | ||
let interval = null; | ||
let savedTime = null; | ||
let lapCount = 0; | ||
this.laps = []; | ||
|
||
// Elements | ||
|
||
let minuteEl = this.element.querySelector(".minute"); | ||
let secondEl = this.element.querySelector(".second"); | ||
let millisecondEl = this.element.querySelector(".millisecond"); | ||
const lapCont = this.element.querySelector(".laps"); | ||
|
||
// Function | ||
|
||
this.start = (currentBtn) => { | ||
if (isRunning) return this.stop(currentBtn); | ||
isRunning = true; | ||
startTime = new Date().getTime(); | ||
getTime(); | ||
currentBtn.innerHTML = `Stop`; | ||
}; | ||
|
||
this.stop = (currentBtn) => { | ||
isRunning = false; | ||
stopTime = new Date().getTime(); | ||
clearInterval(interval); | ||
interval = null; | ||
savedTime = time.getTime(); | ||
currentBtn.innerHTML = `Resume`; | ||
}; | ||
|
||
this.lap = () => { | ||
if (isRunning) updateTime(true); | ||
updateLap(); | ||
}; | ||
|
||
this.reset = (currentBtn) => { | ||
isRunning = false; | ||
clearInterval(interval); | ||
interval = null; | ||
startTime = null; | ||
stopTime = null; | ||
interval = null; | ||
savedTime = null; | ||
currentBtn.innerHTML = `Start`; | ||
updateDOM(); | ||
this.laps = []; | ||
updateLap(); | ||
}; | ||
|
||
function getTime() { | ||
interval = setInterval(updateTime.bind(this), 100); | ||
} | ||
|
||
function updateTime(laps) { | ||
let currentTime = new Date().getTime(); | ||
|
||
if (savedTime) time = new Date(currentTime - startTime + savedTime); | ||
else time = new Date(currentTime - startTime); | ||
|
||
setTime(time, laps); | ||
} | ||
|
||
function setTime(time, lap) { | ||
let minuteHolder = time.getMinutes(); | ||
let minute = minuteHolder < 30 ? minuteHolder : minuteHolder - 30; | ||
let second = time.getSeconds(); | ||
let millisecond = time.getMilliseconds(); | ||
formatTime(minute, second, millisecond, lap); | ||
} | ||
|
||
formatTime = (minute, second, millisecond, lap) => { | ||
let minuteText = minute <= 9 ? `0${minute}` : `${minute}`; | ||
let secondText = second <= 9 ? `0${second}` : `${second}`; | ||
let millisecondText = | ||
Math.floor(millisecond / 11) <= 9 | ||
? `0${Math.floor(millisecond / 11)}` | ||
: `${Math.floor(millisecond / 11)}`; | ||
|
||
if (!lap) updateDOM(minuteText, secondText, millisecondText); | ||
else this.laps.push(`${minuteText}:${secondText}:${millisecondText}`); | ||
}; | ||
|
||
function updateDOM( | ||
minuteText = `00`, | ||
secondText = `00`, | ||
millisecondText = `00` | ||
) { | ||
minuteEl.innerHTML = minuteText; | ||
secondEl.innerHTML = secondText; | ||
millisecondEl.innerHTML = millisecondText; | ||
} | ||
|
||
updateLap = () => { | ||
lapCont.innerHTML = null; | ||
lapCount = 0; | ||
this.laps.forEach((lap) => createLapEl(lap)); | ||
}; | ||
|
||
createLapEl = (lapTime) => { | ||
const lapEl = document.createElement("div"); | ||
lapEl.className = `lap`; | ||
const lapPara = document.createElement("p"); | ||
lapEl.appendChild(lapPara); | ||
lapPara.innerHTML = `${lapCount <= 9 ? `0${lapCount}` : `${lapCount}` | ||
} - ${lapTime}`; | ||
lapCont.prepend(lapEl); | ||
lapCount++; | ||
}; | ||
|
||
// Event Listener | ||
|
||
const { start: startEl, reset: resetEl, lapEl: lapBtn } = this.action; | ||
|
||
startEl.addEventListener("click", () => this.start(startBtn)); | ||
resetEl.addEventListener("click", () => this.reset(startBtn)); | ||
lapBtn.addEventListener("click", () => this.lap()); | ||
} | ||
|
||
const stopwatchEl = document.getElementById("stopwatch"); | ||
const startBtn = document.getElementById("start"); | ||
const resetBtn = document.getElementById("reset"); | ||
const lapBtn = document.getElementById("lap"); | ||
|
||
const stopWatch = new StopWatch(stopwatch, { | ||
start: startBtn, | ||
reset: resetBtn, | ||
lapEl: lapBtn, | ||
}); |
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,116 @@ | ||
@import url("https://fonts.googleapis.com/css2?family=Overpass:wght@200;300;600;700;800&display=swap"); | ||
|
||
* { | ||
margin: 0%; | ||
padding: 0%; | ||
box-sizing: border-box; | ||
font-family: "Overpass", sans-serif; | ||
} | ||
body { | ||
background-color: aliceblue; | ||
display: flex; | ||
align-items: center; | ||
justify-content: center; | ||
} | ||
body section { | ||
width: 90%; | ||
max-width: 500px; | ||
margin-top: 1.5rem; | ||
} | ||
body section header { | ||
display: flex; | ||
align-items: center; | ||
} | ||
body section header h1 { | ||
font-size: 2rem; | ||
margin-left: 5px; | ||
margin-top: 6px; | ||
color: #a14f4f; | ||
position: relative; | ||
} | ||
|
||
body section header img { | ||
width: 35px; | ||
} | ||
body section .timer { | ||
display: flex; | ||
align-items: center; | ||
justify-content: center; | ||
margin-top: 2.5rem; | ||
} | ||
body section .timer h1 { | ||
font-size: 5rem; | ||
font-weight: bolder; | ||
width: 110px; | ||
display: flex; | ||
align-items: center; | ||
justify-content: center; | ||
color: rgb(48, 48, 48); | ||
} | ||
body section .timer .colon { | ||
height: 10px; | ||
width: 10px; | ||
background-color: rgb(48, 48, 48); | ||
position: relative; | ||
margin: 0 5px; | ||
border-radius: 4px; | ||
} | ||
body section .timer .colon:nth-child(2):after { | ||
content: ""; | ||
height: 100%; | ||
width: 100%; | ||
background-color: rgb(48, 48, 48); | ||
position: absolute; | ||
border-radius: 4px; | ||
top: -20px; | ||
} | ||
body section .ctaBtns { | ||
display: grid; | ||
grid-template-columns: repeat(3, 1fr); | ||
margin-top: 1.5rem; | ||
} | ||
body section .ctaBtns button { | ||
padding: 0.475rem 1.5rem; | ||
font-size: 1rem; | ||
line-height: 1.5; | ||
border: none; | ||
outline: none; | ||
cursor: pointer; | ||
background: #0d6efd; | ||
color: #fff; | ||
width: fit-content; | ||
border-radius: 0.25rem; | ||
margin: 0% auto; | ||
} | ||
body section .ctaBtns .reset { | ||
background: #b02a37; | ||
} | ||
body section .ctaBtns .lapBtn { | ||
background: #61428f; | ||
} | ||
body section .lapsCont { | ||
margin-top: 2rem; | ||
} | ||
body section .lapsCont header { | ||
margin: 1rem 0; | ||
} | ||
body section .laps { | ||
display: flex; | ||
flex-direction: column; | ||
justify-content: flex-start; | ||
} | ||
body section .laps .lap { | ||
background-color: #61428f; | ||
padding: 1rem; | ||
margin: 5px 0; | ||
border-radius: 0.25rem; | ||
} | ||
body section .laps .lap p { | ||
color: #fff; | ||
} | ||
|
||
@media (max-width: 500px) { | ||
body section .timer h1 { | ||
font-size: 4rem; | ||
} | ||
} |