Skip to content

Commit 1f28712

Browse files
committed
Solution ex.29
1 parent 3dee1d2 commit 1f28712

File tree

5 files changed

+199
-47
lines changed

5 files changed

+199
-47
lines changed

29 - Countdown Timer/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,6 @@ <h1 class="display__time-left"></h1>
2424
</div>
2525
</div>
2626

27-
<script src="scripts-START.js"></script>
27+
<script src="script.js"></script>
2828
</body>
2929
</html>

29 - Countdown Timer/readme.md

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
# Countdown Clock
2+
3+
We build in this example a [Pomodoro Clock][1]
4+
5+
## Notes
6+
7+
The main function takes care of most of the logic of this exercise. Some comments about it:
8+
9+
* We don't implement it through decrementing a variable inside a `setInterval`, because
10+
we cannot be sure if it's going to work as expected, because sometimes the browser
11+
will shut it down due performance.
12+
13+
```javascript
14+
let leftSeconds = 15;
15+
setInterval(() => leftSeconds--, 1000);
16+
```
17+
18+
* At the beginning we clean the last `setInterval` defined in order to have always
19+
one referece.
20+
* `setInterval` returns always a value that identifies the timer and allows to clear it
21+
at some point in the future.
22+
* The `Date.now()` returns a value in miliseconds
23+
24+
```javascript
25+
function timer(seconds) {
26+
clearInterval(countDown);
27+
28+
const now = Date.now();
29+
const then = now + seconds * 1000;
30+
displayTimeLeft(seconds);
31+
displayEndTime(then);
32+
33+
countDown = setInterval(() => {
34+
const secondsLeft = Math.round((then - Date.now()) / 1000);
35+
if(secondsLeft < 0) {
36+
clearInterval(countDown);
37+
return;
38+
}
39+
displayTimeLeft(secondsLeft);
40+
}, 1000);
41+
}
42+
```
43+
44+
The other two functions implemente have the mission to generate the HTML code
45+
to be inserted into the corresponging HTML elements:
46+
47+
```javascript
48+
function displayTimeLeft(seconds) {
49+
const minutes = Math.floor(seconds / 60);
50+
const remainerSeconds = seconds % 60;
51+
const display = `${minutes}:${remainerSeconds < 10 ? '0' : ''}${remainerSeconds}`;
52+
53+
document.title = display;
54+
timerDisplay.textContent = display;
55+
}
56+
57+
function displayEndTime(timestampt) {
58+
const end = new Date(timestampt);
59+
const hours = end.getHours();
60+
const minutes = end.getMinutes();
61+
62+
endTimeDisplay.textContent = `Be back at ${hours}:${minutes < 10 ? '0' : ''}${minutes}`;
63+
}
64+
```
65+
66+
**Note:** When getting values from HTML elements either through `data` attributes or
67+
`input` values, the return value will be always a string so in this case if we are working with numbers
68+
we have to cast it to Number:
69+
70+
```javascript
71+
const dataAttribute = parseInte(this.dataset.time);
72+
// or
73+
const dataAttribute = +this.dataset.time;
74+
```
75+
76+
**Note:** All HTML elements that have a name attribute can be accessed directly from
77+
the `document` object, without using the `querySelector` method:
78+
79+
```html
80+
<form name="customForm" id="custom">
81+
<input type="text" name="minutes" placeholder="Enter Minutes">
82+
</form>
83+
```
84+
85+
```javascript
86+
const minuteValue = document.customForm.minutes.value;
87+
```
88+
89+
## Events
90+
* **click**
91+
* **submit**
92+
93+
[1]:https://en.wikipedia.org/wiki/Pomodoro_Technique

29 - Countdown Timer/script.js

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
let countDown ;
2+
3+
const timerDisplay = document.querySelector('.display__time-left');
4+
const endTimeDisplay = document.querySelector('.display__end-time');
5+
const buttons = document.querySelectorAll('[data-time]');
6+
7+
8+
9+
buttons.forEach(button => button.addEventListener('click', setTimer));
10+
// works with the 'name' attribute
11+
document.customForm.addEventListener('submit', setTimerFromForm);
12+
13+
14+
function setTimer() {
15+
timer(+this.dataset.time);
16+
}
17+
18+
function setTimerFromForm(e) {
19+
e.preventDefault();
20+
timer(+this.minutes.value * 60);
21+
this.reset();
22+
}
23+
24+
function timer(seconds) {
25+
// clears any existing times
26+
clearInterval(countDown);
27+
28+
// setInterval(fn, 1000); Where fn makes seconds-- Could not work as expected, the browser can shut it down for performance
29+
const now = Date.now();// new to the browser => ms
30+
const then = now + seconds * 1000;// convert seconds to ms
31+
displayTimeLeft(seconds);
32+
displayEndTime(then);
33+
34+
countDown = setInterval(() => {
35+
const secondsLeft = Math.round((then - Date.now()) / 1000);
36+
if(secondsLeft < 0) {
37+
clearInterval(countDown);
38+
return;
39+
}
40+
displayTimeLeft(secondsLeft);
41+
}, 1000);
42+
}
43+
44+
45+
function displayTimeLeft(seconds) {
46+
const minutes = Math.floor(seconds / 60);
47+
const remainerSeconds = seconds % 60;
48+
const display = `${minutes}:${remainerSeconds < 10 ? '0' : ''}${remainerSeconds}`;
49+
50+
document.title = display;
51+
timerDisplay.textContent = display;
52+
}
53+
54+
function displayEndTime(timestampt) {
55+
const end = new Date(timestampt);
56+
const hours = end.getHours();
57+
const minutes = end.getMinutes();
58+
59+
endTimeDisplay.textContent = `Be back at ${hours}:${minutes < 10 ? '0' : ''}${minutes}`;
60+
}

29 - Countdown Timer/scripts-START.js

Whitespace-only changes.

29 - Countdown Timer/style.css

Lines changed: 45 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,81 @@
11
html {
2-
box-sizing: border-box;
3-
font-size: 10px;
4-
background: #8E24AA;
5-
background: linear-gradient(45deg, #42a5f5 0%,#478ed1 50%,#0d47a1 100%);
2+
box-sizing: border-box;
3+
font-size: 10px;
4+
background: #8E24AA;
5+
background: linear-gradient(45deg, #42a5f5 0%, #478ed1 50%, #0d47a1 100%);
66
}
77

88
*, *:before, *:after {
9-
box-sizing: inherit;
9+
box-sizing: inherit;
1010
}
1111

1212
body {
13-
margin:0;
14-
text-align: center;
15-
font-family: 'Inconsolata', monospace;
13+
margin: 0;
14+
text-align: center;
15+
font-family: 'Inconsolata', monospace;
1616
}
1717

1818
.display__time-left {
19-
font-weight: 100;
20-
font-size: 20rem;
21-
margin: 0;
22-
color:white;
23-
text-shadow:4px 4px 0 rgba(0,0,0,0.05);
19+
font-weight: 100;
20+
font-size: 20rem;
21+
margin: 0;
22+
color: white;
23+
text-shadow: 4px 4px 0 rgba(0, 0, 0, 0.05);
2424
}
2525

2626
.timer {
27-
display:flex;
28-
min-height: 100vh;
29-
flex-direction:column;
27+
display: flex;
28+
min-height: 100vh;
29+
flex-direction: column;
3030
}
3131

3232
.timer__controls {
33-
display: flex;
33+
display: flex;
3434
}
3535

3636
.timer__controls > * {
37-
flex:1;
37+
flex: 1;
3838
}
3939

4040
.timer__controls form {
41-
flex:1;
42-
display:flex;
41+
flex: 1;
42+
display: flex;
4343
}
4444

4545
.timer__controls input {
46-
flex:1;
47-
border:0;
48-
padding:2rem;
46+
flex: 1;
47+
border: 0;
48+
padding: 2rem;
4949
}
5050

5151
.timer__button {
52-
background:none;
53-
border:0;
54-
cursor: pointer;
55-
color:white;
56-
font-size: 2rem;
57-
text-transform: uppercase;
58-
background:rgba(0,0,0,0.1);
59-
border-bottom:3px solid rgba(0,0,0,0.2);
60-
border-right:1px solid rgba(0,0,0,0.2);
61-
padding:1rem;
62-
font-family: 'Inconsolata', monospace;
52+
background: none;
53+
border: 0;
54+
cursor: pointer;
55+
color: white;
56+
font-size: 2rem;
57+
text-transform: uppercase;
58+
background: rgba(0, 0, 0, 0.1);
59+
border-bottom: 3px solid rgba(0, 0, 0, 0.2);
60+
border-right: 1px solid rgba(0, 0, 0, 0.2);
61+
padding: 1rem;
62+
font-family: 'Inconsolata', monospace;
6363
}
6464

65-
.timer__button:hover,
66-
.timer__button:focus {
67-
background:rgba(0,0,0,0.2);
68-
outline:0;
65+
.timer__button:hover, .timer__button:focus {
66+
background: rgba(0, 0, 0, 0.2);
67+
outline: 0;
6968
}
7069

7170
.display {
72-
flex:1;
73-
display:flex;
74-
flex-direction: column;
75-
align-items: center;
76-
justify-content: center;
71+
flex: 1;
72+
display: flex;
73+
flex-direction: column;
74+
align-items: center;
75+
justify-content: center;
7776
}
7877

7978
.display__end-time {
80-
font-size: 4rem;
81-
color:white;
82-
}
79+
font-size: 4rem;
80+
color: white;
81+
}

0 commit comments

Comments
 (0)