';
22 | // containerDiv.innerHTML = stringDiv;
23 |
--------------------------------------------------------------------------------
/01-html-css-fundamentals/20-js-html/style.css:
--------------------------------------------------------------------------------
1 | .helloclass {
2 | font-weight: bold;
3 | }
4 |
--------------------------------------------------------------------------------
/01-html-css-fundamentals/21-events/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
Events
11 |
12 |
13 |
14 |
Click Me
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/01-html-css-fundamentals/21-events/script.js:
--------------------------------------------------------------------------------
1 | const btn = document.querySelector('#button');
2 |
3 | btn.addEventListener('click', function() {
4 | console.log('hey you clicked me!!!')
5 | });
6 |
--------------------------------------------------------------------------------
/01-html-css-fundamentals/22-timing-functions/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
Timing Functions
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/01-html-css-fundamentals/22-timing-functions/script.js:
--------------------------------------------------------------------------------
1 | // setTimeout
2 | setTimeout(function() {
3 | console.log('Dinner is ready!');
4 | }, 3 * 1000);
5 |
6 | // // setInterval
7 | // setInterval(function() {
8 | // console.log('Has this happened?')
9 | // }, 1000);
10 | //
11 | // // Timer
12 | // const timer = document.querySelector('#timer');
13 | // let seconds = 10;
14 | //
15 | // const clock = setInterval(function() {
16 | // timer.innerText = seconds; // add some javascript
17 | //
18 | // if(seconds == 0) {
19 | // // stop the interval
20 | // clearInterval(clock);
21 | // console.log('...happy new year?! 🎉');
22 | // } else {
23 | // seconds--;
24 | // }
25 | //
26 | // }, 1000);
27 |
--------------------------------------------------------------------------------
/02-talking-duck/images/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/boolean-uk/coding-week/b197f8483554fed902f223db477d841ab7021594/02-talking-duck/images/icon.png
--------------------------------------------------------------------------------
/02-talking-duck/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/boolean-uk/coding-week/b197f8483554fed902f223db477d841ab7021594/02-talking-duck/images/logo.png
--------------------------------------------------------------------------------
/02-talking-duck/images/play.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/boolean-uk/coding-week/b197f8483554fed902f223db477d841ab7021594/02-talking-duck/images/play.png
--------------------------------------------------------------------------------
/02-talking-duck/images/talking-duck-animated.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/boolean-uk/coding-week/b197f8483554fed902f223db477d841ab7021594/02-talking-duck/images/talking-duck-animated.gif
--------------------------------------------------------------------------------
/02-talking-duck/images/talking-duck-static.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/boolean-uk/coding-week/b197f8483554fed902f223db477d841ab7021594/02-talking-duck/images/talking-duck-static.png
--------------------------------------------------------------------------------
/02-talking-duck/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
Talking Duck
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | Pitch
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/02-talking-duck/script.js:
--------------------------------------------------------------------------------
1 | // // BONUS
2 | // // ! NB Chrome retrieves voices asynchronously
3 | // let voices = []
4 | //
5 | // // the speechSynthesis.getVoices() array starts off empty when page is first loaded.
6 | // // The web speech API at some point populates this. When it's updated (async), the event voiceschanged fires.
7 | // // we're hooking it to that event to retrieve list of voices.
8 | // speechSynthesis.onvoiceschanged = function () {
9 | // voices = speechSynthesis.getVoices()
10 | // console.log(voices) // toggle this to show available voices.
11 | // }
12 |
13 | // query the page for elements
14 | const textArea = document.querySelector('textarea')
15 | const playButton = document.querySelector('button')
16 | const pitchBar = document.querySelector('input')
17 | const duckFigure = document.querySelector('figure')
18 |
19 |
20 | // Control what happens when button is clicked
21 | // When clicked, check if there is text in the input field
22 | playButton.addEventListener('click', function () {
23 | const textLength = textArea.value.trim().length
24 | if (textLength > 0) {
25 | speak()
26 | }
27 | })
28 |
29 | // Function to make the duck talk!
30 | function speak() {
31 | // Retrieve text and audio values
32 | const text = textArea.value
33 | const pitch = pitchBar.value
34 |
35 | // Initialiase a new utterance
36 | const utterance = new SpeechSynthesisUtterance(text)
37 |
38 | // utterance.volume = 1 // 0 - 1
39 | // utterance.rate = 0.5; // 0.1 - 10
40 |
41 | // set the pitch level
42 | utterance.pitch = pitch // 0 - 2
43 |
44 | // // BONUS: set the voice
45 | // const voice = voices.find(item => item.name.includes("CHOOSE ONE!"))
46 | // console.log(voices, voice)
47 | //
48 | // utterance.voice = voice;
49 |
50 |
51 | // Make the duck talk
52 | speechSynthesis.speak(utterance)
53 |
54 | // When the duck begins to speak...
55 | utterance.addEventListener('start', function () {
56 | textArea.disabled = true
57 | pitchBar.disabled = true
58 | playButton.disabled = true
59 | duckFigure.classList.add('talking')
60 | })
61 |
62 | // When the duck has finished...
63 | utterance.addEventListener('end', function () {
64 | textArea.disabled = false
65 | pitchBar.disabled = false
66 | playButton.disabled = false
67 | duckFigure.classList.remove('talking')
68 | })
69 | }
70 |
--------------------------------------------------------------------------------
/02-talking-duck/site.webmanifest:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "Talking Duck",
3 | "name": "Talking Duck",
4 | "icons": [
5 | {
6 | "src": "images/icon.png",
7 | "type": "image/png",
8 | "sizes": "192x192"
9 | }
10 | ],
11 | "background_color": "#f71469",
12 | "theme_color": "#f71469",
13 | "display": "fullscreen"
14 | }
15 |
--------------------------------------------------------------------------------
/02-talking-duck/style.css:
--------------------------------------------------------------------------------
1 | /* Custom properties */
2 | :root {
3 | --font: Roboto, sans-serif;
4 | --pink: #f71469;
5 | }
6 |
7 | /* CSS Reset */
8 | * {
9 | margin: 0;
10 | padding: 0;
11 | box-sizing: border-box;
12 | }
13 |
14 | /* Generic Rules */
15 | html {
16 | height: 100%;
17 | font-family: var(--font);
18 | color: white;
19 | background-image: linear-gradient(to top, var(--pink) -40%, #3535ec 85%);
20 | background-attachment: fixed;
21 | }
22 |
23 | img {
24 | max-width: 100%;
25 | }
26 |
27 | /* Container */
28 | .container {
29 | display: grid;
30 | width: 90vw;
31 | padding: 16px;
32 | margin: 0 auto;
33 | }
34 |
35 | /* Logo */
36 | header img {
37 | width: 56px;
38 | height: auto;
39 | margin-bottom: 32px;
40 | }
41 |
42 | /* Text box */
43 | textarea {
44 | border: none;
45 | resize: none;
46 | width: 100%;
47 | height: 120px;
48 | border-radius: 16px;
49 | font-size: 20px;
50 | padding: 24px;
51 | font-family: var(--font);
52 | margin-bottom: 32px;
53 | }
54 |
55 | textarea:focus-within {
56 | outline: 1px auto var(--pink);
57 | }
58 |
59 | /* Controls */
60 |
61 | .controls {
62 | display: grid;
63 | grid-gap: 10px;
64 | grid-template-columns: 1fr 4fr;
65 | }
66 |
67 | /* Play button */
68 |
69 | button {
70 | border: none;
71 | border-radius: 8px;
72 | width: 64px;
73 | height: 56px;
74 | background-color: var(--pink);
75 | }
76 |
77 | button:disabled {
78 | opacity: 0.6;
79 | background-color: #dedede;
80 | }
81 |
82 | button img {
83 | vertical-align: middle;
84 | }
85 |
86 | /* Audio controls */
87 |
88 | .pitch-controls {
89 | margin-bottom: 32px;
90 | }
91 |
92 | label {
93 | display: block;
94 | margin-bottom: 12px;
95 | }
96 |
97 | #pitch-range {
98 | width: 100%;
99 | accent-color: white;
100 | }
101 |
102 | /* # TALKING CLASS */
103 |
104 | .talking .static-duck {
105 | display: none;
106 | }
107 |
108 | .talking .animated-duck {
109 | display: block;
110 | }
111 |
--------------------------------------------------------------------------------
/03-codigotchi/images/codigotchi-actions/dance.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/boolean-uk/coding-week/b197f8483554fed902f223db477d841ab7021594/03-codigotchi/images/codigotchi-actions/dance.gif
--------------------------------------------------------------------------------
/03-codigotchi/images/codigotchi-actions/eat.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/boolean-uk/coding-week/b197f8483554fed902f223db477d841ab7021594/03-codigotchi/images/codigotchi-actions/eat.gif
--------------------------------------------------------------------------------
/03-codigotchi/images/codigotchi-actions/sleep.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/boolean-uk/coding-week/b197f8483554fed902f223db477d841ab7021594/03-codigotchi/images/codigotchi-actions/sleep.gif
--------------------------------------------------------------------------------
/03-codigotchi/images/codigotchi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/boolean-uk/coding-week/b197f8483554fed902f223db477d841ab7021594/03-codigotchi/images/codigotchi.png
--------------------------------------------------------------------------------
/03-codigotchi/images/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/boolean-uk/coding-week/b197f8483554fed902f223db477d841ab7021594/03-codigotchi/images/favicon.ico
--------------------------------------------------------------------------------
/03-codigotchi/images/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/boolean-uk/coding-week/b197f8483554fed902f223db477d841ab7021594/03-codigotchi/images/icon.png
--------------------------------------------------------------------------------
/03-codigotchi/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/boolean-uk/coding-week/b197f8483554fed902f223db477d841ab7021594/03-codigotchi/images/logo.png
--------------------------------------------------------------------------------
/03-codigotchi/images/mic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/boolean-uk/coding-week/b197f8483554fed902f223db477d841ab7021594/03-codigotchi/images/mic.png
--------------------------------------------------------------------------------
/03-codigotchi/images/static.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/boolean-uk/coding-week/b197f8483554fed902f223db477d841ab7021594/03-codigotchi/images/static.png
--------------------------------------------------------------------------------
/03-codigotchi/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
Coding Week - Codigotchi
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
Activate microphone
50 |
51 |
52 |
53 |
54 |
Speak one of the commands below!
55 |
Supported Commands
56 |
57 |
58 | Eat
59 | Dance
60 | Sleep
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
--------------------------------------------------------------------------------
/03-codigotchi/script.js:
--------------------------------------------------------------------------------
1 | // REMEMBER: use Chrome browser. Speech Recognition API is non-standard.
2 | // Provide default value
3 | const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
4 |
5 | // Query the page for elements
6 | const micBtn = document.getElementById('microphone');
7 | const screen = document.getElementById('screen');
8 | const panelsData = document.getElementById('panels-data');
9 | const transcript = document.getElementById('transcript');
10 |
11 | const commands = ['eat', 'dance', 'sleep'];
12 |
13 | // Initialisation
14 | const recognition = new SpeechRecognition();
15 |
16 | function onStartListening() {
17 | recognition.start();
18 | panelsData.classList.add('listening');
19 | }
20 |
21 | function onResult(e) {
22 | panelsData.classList.remove('listening');
23 |
24 | // retrieve the transcribed speech
25 | const text = e.results[0][0].transcript;
26 | // update the page with the transcript
27 | transcript.textContent = `You said: '${text}'`;
28 |
29 | // find if the command is available
30 | const action = commands.find(function(cmd) {
31 | return text.toLowerCase().includes(cmd);
32 | });
33 |
34 | let actionClassname
35 | // if the action was found, apply the CSS rule by class
36 | if (action) {
37 | actionClassname = 'codigotchi-screen_' + action;
38 |
39 | screen.classList.add(actionClassname);
40 | } else {
41 | // show user message saying it's not valid
42 | transcript.textContent += ' - not a valid command!';
43 | }
44 |
45 | // Show GIFs for 2seconds
46 | // then reset the message area
47 | setTimeout(function() {
48 | screen.classList.remove(actionClassname);
49 | transcript.innerText = '';
50 | }, 2000);
51 | }
52 |
53 | function onError(e) {
54 | console.error(e.error);
55 | }
56 |
57 | micBtn.addEventListener('click', onStartListening);
58 | recognition.addEventListener('result', onResult);
59 | recognition.addEventListener('error', onError);
60 |
--------------------------------------------------------------------------------
/03-codigotchi/site.webmanifest:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "Codigotchi",
3 | "name": "Codigotchi",
4 | "icons": [{
5 | "src": "images/icon.png",
6 | "type": "image/png",
7 | "sizes": "192x192"
8 | }],
9 | "theme_color": "#3535EC",
10 | "display": "fullscreen"
11 | }
12 |
--------------------------------------------------------------------------------
/03-codigotchi/style.css:
--------------------------------------------------------------------------------
1 | * {
2 | box-sizing: border-box;
3 | margin: 0;
4 | padding: 0;
5 | }
6 |
7 | html {
8 | background: linear-gradient(#838ef9, #3535ec);
9 | background-attachment: fixed;
10 | height: 100%;
11 | font-family: 'Roboto', sans-serif;
12 | }
13 |
14 | main {
15 | text-align: center;
16 | }
17 |
18 | .container {
19 | width: 90%;
20 | max-width: 720px;
21 | margin: 0 auto;
22 | padding: 16px;
23 | }
24 |
25 | /* Logo */
26 | header img {
27 | width: 56px;
28 | }
29 |
30 | h2 {
31 | font-size: 20px;
32 | margin-bottom: 16px;
33 | font-weight: bold;
34 | }
35 |
36 | h3 {
37 | font-size: 16px;
38 | margin-top: 24px;
39 | margin-bottom: 12px;
40 | color: #4C6C96;
41 | }
42 |
43 | p {
44 | color: #ffffff;
45 |
46 | }
47 |
48 | img {
49 | max-width: 100%;
50 | height: auto;
51 | }
52 |
53 | .codigotchi {
54 | width: 230px;
55 | margin: 0 auto 24px auto;
56 | position: relative;
57 | }
58 |
59 | .codigotchi-screen {
60 | position: absolute;
61 | top: 118px;
62 | left: 56px;
63 | height: 120px;
64 | width: 120px;
65 | background-image: url('./images/static.png');
66 | background-position: center center;
67 | background-repeat: no-repeat;
68 | background-size: contain;
69 | }
70 |
71 | .codigotchi-screen_sleep {
72 | background-image: url('./images/codigotchi-actions/sleep.gif');
73 | }
74 |
75 | .codigotchi-screen_eat {
76 | background-image: url('./images/codigotchi-actions/eat.gif');
77 | }
78 |
79 | .codigotchi-screen_dance {
80 | background-image: url('./images/codigotchi-actions/dance.gif');
81 | }
82 |
83 | .commands {
84 | /* */
85 | }
86 |
87 | .commands ul {
88 | width: 100%;
89 | display: grid;
90 | grid-template-columns: repeat(3, 1fr);
91 | list-style: none;
92 | }
93 |
94 | .commands ul li {
95 | font-size: 24px;
96 | font-weight: bold;
97 | }
98 |
99 | .panels {
100 | position: relative;
101 | margin-bottom: 16px;
102 | }
103 |
104 | .panel {
105 | background-color: white;
106 | border-radius: 10px;
107 | padding: 16px 24px;
108 | transition: transform 0.2s;
109 | width: 100%;
110 | }
111 |
112 | .panel-commands {
113 | position: absolute;
114 | top: 0;
115 | left: 0;
116 | visibility: hidden;
117 | transform: scale(0.1);
118 | }
119 |
120 | .listening .panel-commands {
121 | visibility: visible;
122 | transform: scale(1);
123 | }
124 |
125 | .listening .panel-microphone {
126 | visibility: hidden;
127 | transform: scale(0.1);
128 | }
129 |
130 | button {
131 | border: none;
132 | background-color: #f71469;
133 | border-radius: 8px;
134 | cursor: pointer;
135 | padding: 12px 16px;
136 | margin: 12px;
137 | }
138 |
--------------------------------------------------------------------------------
/04-meteo/images/01d.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/boolean-uk/coding-week/b197f8483554fed902f223db477d841ab7021594/04-meteo/images/01d.png
--------------------------------------------------------------------------------
/04-meteo/images/01n.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/boolean-uk/coding-week/b197f8483554fed902f223db477d841ab7021594/04-meteo/images/01n.png
--------------------------------------------------------------------------------
/04-meteo/images/02d.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/boolean-uk/coding-week/b197f8483554fed902f223db477d841ab7021594/04-meteo/images/02d.png
--------------------------------------------------------------------------------
/04-meteo/images/02n.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/boolean-uk/coding-week/b197f8483554fed902f223db477d841ab7021594/04-meteo/images/02n.png
--------------------------------------------------------------------------------
/04-meteo/images/03d.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/boolean-uk/coding-week/b197f8483554fed902f223db477d841ab7021594/04-meteo/images/03d.png
--------------------------------------------------------------------------------
/04-meteo/images/03n.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/boolean-uk/coding-week/b197f8483554fed902f223db477d841ab7021594/04-meteo/images/03n.png
--------------------------------------------------------------------------------
/04-meteo/images/04d.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/boolean-uk/coding-week/b197f8483554fed902f223db477d841ab7021594/04-meteo/images/04d.png
--------------------------------------------------------------------------------
/04-meteo/images/04n.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/boolean-uk/coding-week/b197f8483554fed902f223db477d841ab7021594/04-meteo/images/04n.png
--------------------------------------------------------------------------------
/04-meteo/images/09d.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/boolean-uk/coding-week/b197f8483554fed902f223db477d841ab7021594/04-meteo/images/09d.png
--------------------------------------------------------------------------------
/04-meteo/images/09n.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/boolean-uk/coding-week/b197f8483554fed902f223db477d841ab7021594/04-meteo/images/09n.png
--------------------------------------------------------------------------------
/04-meteo/images/10d.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/boolean-uk/coding-week/b197f8483554fed902f223db477d841ab7021594/04-meteo/images/10d.png
--------------------------------------------------------------------------------
/04-meteo/images/10n.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/boolean-uk/coding-week/b197f8483554fed902f223db477d841ab7021594/04-meteo/images/10n.png
--------------------------------------------------------------------------------
/04-meteo/images/11d.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/boolean-uk/coding-week/b197f8483554fed902f223db477d841ab7021594/04-meteo/images/11d.png
--------------------------------------------------------------------------------
/04-meteo/images/11n.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/boolean-uk/coding-week/b197f8483554fed902f223db477d841ab7021594/04-meteo/images/11n.png
--------------------------------------------------------------------------------
/04-meteo/images/13d.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/boolean-uk/coding-week/b197f8483554fed902f223db477d841ab7021594/04-meteo/images/13d.png
--------------------------------------------------------------------------------
/04-meteo/images/13n.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/boolean-uk/coding-week/b197f8483554fed902f223db477d841ab7021594/04-meteo/images/13n.png
--------------------------------------------------------------------------------
/04-meteo/images/50d.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/boolean-uk/coding-week/b197f8483554fed902f223db477d841ab7021594/04-meteo/images/50d.png
--------------------------------------------------------------------------------
/04-meteo/images/50n.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/boolean-uk/coding-week/b197f8483554fed902f223db477d841ab7021594/04-meteo/images/50n.png
--------------------------------------------------------------------------------
/04-meteo/images/geolocation_disabled.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/boolean-uk/coding-week/b197f8483554fed902f223db477d841ab7021594/04-meteo/images/geolocation_disabled.png
--------------------------------------------------------------------------------
/04-meteo/images/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/boolean-uk/coding-week/b197f8483554fed902f223db477d841ab7021594/04-meteo/images/icon.png
--------------------------------------------------------------------------------
/04-meteo/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/boolean-uk/coding-week/b197f8483554fed902f223db477d841ab7021594/04-meteo/images/logo.png
--------------------------------------------------------------------------------
/04-meteo/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
Weather App | Coding Week
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
Retrieving data...
41 |
42 |
43 |
44 |
45 |
46 |
Info
47 |
Brrr! It's cold!
48 |
49 |
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/04-meteo/script.js:
--------------------------------------------------------------------------------
1 | // query the page to retrieve DOM elements
2 | const htmlElement = document.documentElement;
3 | const weatherIcon = document.querySelector('.weather-icon');
4 | const weatherLocation = document.querySelector('.weather-location');
5 | const weatherTemperature = document.querySelector('.weather-temperature');
6 | const suggestionElement = document.querySelector('.suggestion');
7 |
8 | // Retrieve current position with success and error callback functions
9 |
10 | navigator.geolocation.getCurrentPosition(onSuccess, onError);
11 |
12 |
13 | // function to handle if there's an error accessing current position
14 | function onError(error) {
15 | weatherLocation.innerText = 'You must permit your browser to access your current location'
16 | console.error(error);
17 | }
18 |
19 | // function to handle what to do after retrieving current position
20 | function onSuccess(position) {
21 | console.log(position)
22 | const latitude = position.coords.latitude;
23 | const longitude = position.coords.longitude;
24 |
25 | // Call an external API to retrieve weather data
26 | // Open Weather Map API: https://openweathermap.org/
27 |
28 | // Prepare your data (replace this dummy API_KEY with your own)
29 | // create an account and generate your own key: https://home.openweathermap.org/api_keys
30 | const ENDPOINT = 'https://api.openweathermap.org/data/2.5/weather';
31 | const API_KEY = '617d-replace-this-with-your-own-key-950c';
32 | const UNITS = 'metric';
33 | const LANGUAGE = 'en';
34 |
35 | // example: https://openweathermap.org/current#one
36 | const apiUri = `${ENDPOINT}?lat=${latitude}&lon=${longitude}&appid=${API_KEY}&units=${UNITS}&lang=${LANGUAGE}`;
37 |
38 | fetch(apiUri)
39 | .then(function (response) {
40 | return response.json();
41 | })
42 | .then(function (data) {
43 | console.log(data);
44 |
45 | // Extract needed data
46 | const locationName = data.name;
47 | const temperature = Math.floor(data.main.temp);
48 | const iconCode = data.weather[0].icon;
49 | const description = data.weather[0].description;
50 |
51 | weatherIcon.alt = description;
52 | weatherIcon.src = `images/${iconCode}.png`;
53 | weatherLocation.textContent = locationName;
54 | weatherTemperature.textContent = `${temperature}°`;
55 |
56 | suggestionElement.textContent = getDescription(iconCode);
57 |
58 | htmlElement.classList.remove('js-loading');
59 | });
60 | }
61 |
62 | // a list of weather descriptions stored by key that corresponds to the Open Weather Map API response data
63 | const descriptions = {
64 | '01d': 'Remember to apply suncream!',
65 | '01n': 'Good night!',
66 | '02d': 'Variable...',
67 | '02n': 'Beware werewolves...',
68 | '03d': 'Perfect lighting for photos!',
69 | '03n': 'Sleep well :)',
70 | '04d': 'Today: a case of the classic British overcast sky :)',
71 | '04n': 'So cloudy, you won\'t even see the moon!',
72 | '09d': 'You might need a brolly.',
73 | '09n': 'Cover up well today',
74 | '10d': 'You\'ll need two umbrellas',
75 | '10n': 'Don\'t expose bare skin to the sun!',
76 | '11d': 'Wear rubber boots!',
77 | '11n': 'Might be one or two sparks in the sky',
78 | '13d': 'Weather for snow-men and snow-angels.',
79 | '13n': 'Perfect night to be under the stars outside!',
80 | '50d': 'Fog lights should be on!',
81 | '50n': 'Drive carefully!',
82 | }
83 |
84 | // function to retrieve the correct description
85 | function getDescription(iconCode) {
86 | return descriptions[iconCode];
87 | }
88 |
--------------------------------------------------------------------------------
/04-meteo/site.webmanifest:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "Meteo",
3 | "name": "Meteo",
4 | "icons": [{
5 | "src": "icon.png",
6 | "type": "image/png",
7 | "sizes": "192x192"
8 | }],
9 | "background_color": "#3535EC",
10 | "theme_color": "#3535EC",
11 | "display": "fullscreen"
12 | }
13 |
--------------------------------------------------------------------------------
/04-meteo/style.css:
--------------------------------------------------------------------------------
1 | /* Custom properties */
2 | :root {
3 | --font: 'Roboto', sans-serif;
4 | --gradient: linear-gradient(to bottom, #ebeffd, #85a5fa);
5 | }
6 |
7 | /* CSS Reset */
8 | * {
9 | margin: 0;
10 | padding: 0;
11 | box-sizing: border-box;
12 | }
13 |
14 | /* Generic rules */
15 | html {
16 | height: 100vh;
17 | line-height: 1;
18 | font-family: var(--font);
19 | background-attachment: fixed;
20 | background-image: var(--gradient);
21 | }
22 |
23 | .container {
24 | width: 90vw;
25 | padding: 16px;
26 | margin: 0 auto;
27 | }
28 |
29 | /* Header */
30 | header img {
31 | width: 56px;
32 | height: auto;
33 | }
34 |
35 | main {
36 | text-align: center;
37 | }
38 |
39 | /* Weather info */
40 |
41 | .weather-info {
42 | margin-bottom: 16px;
43 | }
44 |
45 | .weather-icon {
46 | max-width: 100%;
47 |
48 | transition: transform 0.3s, opacity 1s;
49 | transition-delay: 0.2s;
50 | }
51 |
52 | .weather-location {
53 | font-size: 18px;
54 | font-weight: bold;
55 | }
56 |
57 | .weather-temperature {
58 | font-size: 112px;
59 | }
60 |
61 | /* Panel */
62 | .panel {
63 | background-color: #fff;
64 | padding: 20px;
65 | border-radius: 10px;
66 |
67 | transition: transform 0.3s, opacity 0.3s;
68 | transition-delay: 0.2s;
69 | }
70 |
71 | .panel-title {
72 | color: #4c6c96;
73 | font-weight: normal;
74 | margin-bottom: 12px;
75 | }
76 |
77 | .description {
78 | font-size: 18px;
79 | font-weight: bold;
80 | }
81 |
82 | .js-loading .weather-icon {
83 | opacity: 0;
84 | transform: translateY(30px);
85 | }
86 |
87 | .js-loading .panel {
88 | opacity: 0;
89 | transform: scale(0);
90 | }
91 |
--------------------------------------------------------------------------------