Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
# Rocket Academy Coding Bootcamp: Timer

Published via Netlify: https://stopwatch-a.netlify.app/
Binary file added assets/play.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/reset.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/split.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/stop.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 9 additions & 2 deletions index.html
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
<!DOCTYPE html>
<html>
<head>
<title>Timer</title>
<title>⏱ Stopwatch</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="styles.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=Quantico:ital,wght@0,400;0,700;1,400;1,700&display=swap"
rel="stylesheet"
/>
</head>

<body>
<h1 id="header">Timer!</h1>
<h1 id="header">⏱ Stopwatch!</h1>
<!-- Import program logic -->
<script src="script.js"></script>
</body>
Expand Down
157 changes: 157 additions & 0 deletions script.js
Original file line number Diff line number Diff line change
@@ -1 +1,158 @@
// Please implement exercise logic here
let handle = null; // for setInterval and clearInterval
let handle2 = null;
let start = true;
let prevTime = 0; // for Date.now() difference with elapsedTime
let elapsedTime = 0;
let firstSplit = true;
let split = false;
let prevSplitTime = 0;
let elapsedSplitTime = 0;

//build stopwatch elapsed time
const stopWatch = document.createElement("div");
stopWatch.classList.add("elapsed");
stopWatch.innerHTML = `00 : 00 : 00 : 000`;
document.body.appendChild(stopWatch);

// build interactive buttons
const imgContainer = document.createElement("div");
imgContainer.classList.add("image-container");
document.body.appendChild(imgContainer);
const goStart = document.createElement("img");

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can improve readability by separating each of the const declarations with an empty line

goStart.classList.add("img", "start");
goStart.src = "/assets/play.png";
imgContainer.appendChild(goStart);
const goStop = document.createElement("img");
Copy link

@liam9408 liam9408 Dec 21, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can simply name these variables as startTimer, stopTimer, or even startButton, stopButton ... etc. This is to provide super clear context of what each button does.

goStop.classList.add("img", "stop");
goStop.src = "/assets/stop.png";
goStop.classList.add("disabled");
imgContainer.appendChild(goStop);
const goReset = document.createElement("img");
goReset.classList.add("img", "reset");
goReset.src = "/assets/reset.png";
goReset.classList.add("disabled");
imgContainer.appendChild(goReset);
const goSplit = document.createElement("img");
goSplit.classList.add("img", "split");
goSplit.src = "/assets/split.png";
goSplit.classList.add("disabled");
imgContainer.appendChild(goSplit);

// build split container to record lap
const splitContainer = document.createElement("div");
splitContainer.classList.add("split-container");
document.body.appendChild(splitContainer);
let splitWatch;

// stopwatch time display
const renderTime = (element, elapsed) => {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nicely done ! 👍

let tempTime = elapsed;
let milliseconds = tempTime % 1000; // get the remainder of 1000 ms which can go to second
tempTime = Math.floor(tempTime / 1000); //to get seconds
let seconds = tempTime % 60; // get the remainder of 60s which can go to minutes
tempTime = Math.floor(tempTime / 60); // to get minutes
let minutes = tempTime % 60; // get the remainder of 60mins which can go to hours
tempTime = Math.floor(tempTime / 60); // to get hours
let hours = tempTime % 60; //to get the remaider of hours

//concat all the units above
let text = "";
text += hours.toString().padStart(2, "0") + " : ";

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

very nice use of padStart

text += minutes.toString().padStart(2, "0") + " : ";
text += seconds.toString().padStart(2, "0") + " : ";
text += milliseconds.toString().padStart(3, "0");
element.innerHTML = text;
return element.innerHTML;
};

//start stopwatch for start and split
const startStopwatch = () => {
if (handle) return; //check flag
//console.log("This 1 line");
if (start && !split) {
start = false;
handle = setInterval(function () {
if (!prevTime) {
prevTime = Date.now(); //to set the initial value of the time
}
elapsedTime += Date.now() - prevTime; //to get the difference between elapsed and 0;
prevTime = Date.now();
renderTime(stopWatch, elapsedTime);
}, 100);
split = true;
}
};

//pause the stopwatch
const pauseStopwatch = () => {
clearInterval(handle);
handle = null;
prevTime = 0;
};

//reset the stopwatch
const resetStopwatch = () => {
pauseStopwatch();
elapsedTime = 0;
prevTime = 0;
start = true;
split = false;
prevSplitTime = 0;
elapsedSplitTime = 0;
firstSplit = true;
renderTime(stopWatch, elapsedTime);
splitContainer.innerHTML = "";
};

//split the stopwatch
const splitStopwatch = () => {
if (split && !start && handle !== null) {
if (!firstSplit) {
console.log("not first split");
splitWatch = document.createElement("div");
splitContainer.appendChild(splitWatch);
renderTime(splitWatch, elapsedSplitTime);
elapsedSplitTime = 0;
}
if (firstSplit) {
firstSplit = false;
console.log("first split");
splitWatch = document.createElement("div");
splitContainer.appendChild(splitWatch);
handle2 = setInterval(function () {
if (!prevSplitTime) {
prevSplitTime = Date.now(); //to set the initial value of the time
}
elapsedSplitTime += Date.now() - prevSplitTime; //to get the difference between elapsed and 0;
prevSplitTime = Date.now();
}, 100);
renderTime(splitWatch, elapsedTime);
elapsedSplitTime = 0;
}
}
};

//add event listener to each button
goStart.addEventListener("click", function () {
startStopwatch();
goStart.classList.add("disabled");
goSplit.classList.remove("disabled");
goStop.classList.remove("disabled");
goReset.classList.remove("disabled");
});
goStop.addEventListener("click", function () {
pauseStopwatch();
goSplit.classList.add("disabled");
goStop.classList.add("disabled");
});
goReset.addEventListener("click", function () {
resetStopwatch();
goStart.classList.remove("disabled");
goSplit.classList.add("disabled");
goStop.classList.add("disabled");
goReset.classList.add("disabled");
});
goSplit.addEventListener("click", function () {
splitStopwatch();
});
39 changes: 38 additions & 1 deletion styles.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,40 @@
html {
min-height: 100vh;
cursor: url(https://cur.cursors-4u.net/holidays/hol-1/hol80.ani),
url(https://cur.cursors-4u.net/holidays/hol-1/hol80.png), auto !important;
}

body {
background-color: pink;
font-family: "Quantico", sans-serif;
margin: 0;
text-align: center;
background: radial-gradient(#ffb6c1, #ffffff);
}

.elapsed {
font-size: 250%;
}

.image-container {
display: inline-block;
}

.img {
max-width: 50px;
margin: 30px;
}

.disabled {
opacity: 35%;
}

.split {
max-width: 65px;
margin: 25px;
}

.split-container {
font-size: 150%;
font-style: italic;
font-weight: thin;
}