diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..6f3a291
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,3 @@
+{
+ "liveServer.settings.port": 5501
+}
\ No newline at end of file
diff --git a/theme-clock.zip b/theme-clock.zip
new file mode 100644
index 0000000..9225117
Binary files /dev/null and b/theme-clock.zip differ
diff --git a/theme-clock/index.html b/theme-clock/index.html
index 8b50d24..bce2015 100644
--- a/theme-clock/index.html
+++ b/theme-clock/index.html
@@ -18,6 +18,16 @@
+
+
+
+
Time's up! Alarm triggered!
+
+
diff --git a/theme-clock/mixkit-digital-clock-digital-alarm-buzzer-992.wav b/theme-clock/mixkit-digital-clock-digital-alarm-buzzer-992.wav
new file mode 100644
index 0000000..9b0b32b
Binary files /dev/null and b/theme-clock/mixkit-digital-clock-digital-alarm-buzzer-992.wav differ
diff --git a/theme-clock/script.js b/theme-clock/script.js
index 5f1126d..4b0889d 100644
--- a/theme-clock/script.js
+++ b/theme-clock/script.js
@@ -1,48 +1,98 @@
-const hourEl = document.querySelector('.hour')
-const minuteEl = document.querySelector('.minute')
-const secondEl = document.querySelector('.second')
-const timeEl = document.querySelector('.time')
-const dateEl = document.querySelector('.date')
-const toggle = document.querySelector('.toggle')
+const hourEl = document.querySelector('.hour');
+const minuteEl = document.querySelector('.minute');
+const secondEl = document.querySelector('.second');
+const timeEl = document.querySelector('.time');
+const dateEl = document.querySelector('.date');
+const toggle = document.querySelector('.toggle');
+const alarmTimeEl = document.querySelector('#alarm-time');
+const setAlarmButton = document.querySelector('.set-alarm');
+const alarmStatusEl = document.querySelector('.alarm-status');
+const alarmNotification = document.querySelector('#alarm-notification');
+const weatherLocationEl = document.querySelector('.weather-location');
+const weatherDescriptionEl = document.querySelector('.weather-description');
+const weatherTempEl = document.querySelector('.weather-temp');
const days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
const months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
+let alarmTime = null;
+
+// Load the alarm sound
+const alarmSound = new Audio('./mixkit-digital-clock-digital-alarm-buzzer-992.wav');
+
toggle.addEventListener('click', (e) => {
- const html = document.querySelector('html')
+ const html = document.querySelector('html');
if (html.classList.contains('dark')) {
- html.classList.remove('dark')
- e.target.innerHTML = 'Dark mode'
+ html.classList.remove('dark');
+ e.target.innerHTML = 'Dark mode';
+ } else {
+ html.classList.add('dark');
+ e.target.innerHTML = 'Light mode';
+ }
+});
+
+setAlarmButton.addEventListener('click', () => {
+ alarmTime = alarmTimeEl.value;
+ if (alarmTime) {
+ alarmStatusEl.textContent = `Alarm set for ${alarmTime}`;
} else {
- html.classList.add('dark')
- e.target.innerHTML = 'Light mode'
+ alarmStatusEl.textContent = 'Please set a valid time for the alarm';
}
-})
+});
function setTime() {
const time = new Date();
- const month = time.getMonth()
- const day = time.getDay()
- const date = time.getDate()
- const hours = time.getHours()
- const hoursForClock = hours >= 13 ? hours % 12 : hours;
- const minutes = time.getMinutes()
- const seconds = time.getSeconds()
- const ampm = hours >= 12 ? 'PM' : 'AM'
-
- hourEl.style.transform = `translate(-50%, -100%) rotate(${scale(hoursForClock, 0, 12, 0, 360)}deg)`
- minuteEl.style.transform = `translate(-50%, -100%) rotate(${scale(minutes, 0, 60, 0, 360)}deg)`
- secondEl.style.transform = `translate(-50%, -100%) rotate(${scale(seconds, 0, 60, 0, 360)}deg)`
-
- timeEl.innerHTML = `${hoursForClock}:${minutes < 10 ? `0${minutes}` : minutes} ${ampm}`
- dateEl.innerHTML = `${days[day]}, ${months[month]} ${date}`
+ const month = time.getMonth();
+ const day = time.getDay();
+ const date = time.getDate();
+ const hours = time.getHours();
+ const hoursForClock = hours % 12 || 12; // Adjust for 12-hour format
+ const minutes = time.getMinutes();
+ const seconds = time.getSeconds();
+ const ampm = hours >= 12 ? 'PM' : 'AM';
+
+ hourEl.style.transform = `translate(-50%, -100%) rotate(${scale(hoursForClock, 0, 12, 0, 360)}deg)`;
+ minuteEl.style.transform = `translate(-50%, -100%) rotate(${scale(minutes, 0, 60, 0, 360)}deg)`;
+ secondEl.style.transform = `translate(-50%, -100%) rotate(${scale(seconds, 0, 60, 0, 360)}deg)`;
+
+ timeEl.innerHTML = `${hoursForClock}:${minutes.toString().padStart(2, '0')} ${ampm}`;
+ dateEl.innerHTML = `${days[day]}, ${months[month]} ${date}`;
}
-// StackOverflow https://stackoverflow.com/questions/10756313/javascript-jquery-map-a-range-of-numbers-to-another-range-of-numbers
-const scale = (num, in_min, in_max, out_min, out_max) => {
- return (num - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
+function checkAlarm() {
+ const time = new Date();
+ const hours = time.getHours();
+ const minutes = time.getMinutes();
+ const currentTime = `${hours}:${minutes.toString().padStart(2, '0')}`;
+
+ if (alarmTime && currentTime === alarmTime) {
+ alarmSound.play(); // Play alarm sound
+ showAlarmNotification(); // Show the notification
+ alarmTime = null; // Reset alarm after triggering
+ alarmStatusEl.textContent = 'No alarm set';
+ }
+}
+
+// Show the alarm notification on the webpage
+function showAlarmNotification() {
+ alarmNotification.classList.add('show'); // Show the notification
+ setTimeout(() => {
+ alarmNotification.classList.remove('show'); // Hide the notification after 5 seconds
+ }, 5000); // Notification disappears after 5 seconds
}
-setTime()
-setInterval(setTime, 1000)
+// Scale function for time rotation
+const scale = (num, in_min, in_max, out_min, out_max) => {
+ return ((num - in_min) * (out_max - out_min)) / (in_max - in_min) + out_min;
+};
+
+// Set the clock and weather widget
+setTime();
+setInterval(() => {
+ setTime();
+ checkAlarm(); // Check if the alarm time is reached
+}, 1000);
+
+// Initialize weather widget
+getLocation();
diff --git a/theme-clock/style.css b/theme-clock/style.css
index aa33562..2d17118 100644
--- a/theme-clock/style.css
+++ b/theme-clock/style.css
@@ -1,4 +1,4 @@
-@import url('https://fonts.googleapis.com/css?family=Heebo:300&display=swap');
+@import url('https://fonts.googleapis.com/css2?family=Heebo:wght@300;400&display=swap');
* {
box-sizing: border-box;
@@ -7,58 +7,71 @@
:root {
--primary-color: #000;
--secondary-color: #fff;
+ --accent-color: #4caf50;
+ --danger-color: #e74c3c;
+ --background-color: #f9f9f9;
+ --shadow-color: rgba(0, 0, 0, 0.2);
}
html {
- transition: all 0.5s ease-in;
+ transition: all 0.5s ease-in-out;
}
html.dark {
--primary-color: #fff;
--secondary-color: #333;
-}
-
-html.dark {
- background-color: #111;
- color: var(--primary-color);
+ --background-color: #111;
+ --shadow-color: rgba(255, 255, 255, 0.2);
}
body {
font-family: 'Heebo', sans-serif;
+ background-color: var(--background-color);
+ color: var(--primary-color);
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
- overflow: hidden;
margin: 0;
+ overflow: hidden;
}
.toggle {
cursor: pointer;
- background-color: var(--primary-color);
+ background-color: var(--accent-color);
color: var(--secondary-color);
border: 0;
- border-radius: 4px;
- padding: 8px 12px;
+ border-radius: 50px;
+ padding: 10px 20px;
position: absolute;
- top: 100px;
+ top: 20px;
+ right: 20px;
+ font-size: 16px;
+ font-weight: 400;
+ box-shadow: 0 4px 6px var(--shadow-color);
+ transition: all 0.3s ease-in-out;
}
-.toggle:focus {
- outline: none;
+.toggle:hover {
+ background-color: var(--primary-color);
+ color: var(--accent-color);
+ transform: scale(1.05);
}
.clock-container {
display: flex;
flex-direction: column;
- justify-content: space-between;
align-items: center;
+ gap: 20px;
}
.clock {
position: relative;
- width: 200px;
- height: 200px;
+ width: 250px;
+ height: 250px;
+ background: linear-gradient(145deg, #05b54e, #ffffff);
+ border-radius: 50%;
+ box-shadow: inset 0 4px 6px var(--shadow-color), 0 6px 10px var(--shadow-color);
}
.needle {
@@ -66,58 +79,50 @@ body {
position: absolute;
top: 50%;
left: 50%;
- height: 65px;
- width: 3px;
+ width: 4px;
+ border-radius: 2px;
transform-origin: bottom center;
- transition: all 0.5s ease-in linear;
+ transition: all 0.5s ease-in-out;
}
.needle.hour {
+ height: 70px;
transform: translate(-50%, -100%) rotate(0deg);
}
.needle.minute {
- transform: translate(-50%, -100%) rotate(0deg);
height: 100px;
+ transform: translate(-50%, -100%) rotate(0deg);
}
.needle.second {
+ height: 110px;
+ background-color: var(--danger-color);
transform: translate(-50%, -100%) rotate(0deg);
- height: 100px;
- background-color: #e74c3c;
}
.center-point {
- background-color: #e74c3c;
- width: 10px;
- height: 10px;
- position: absolute;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- border-radius: 50%;
-}
-
-.center-point::after {
- content: '';
- background-color: var(--primary-color);
- width: 5px;
- height: 5px;
+ background-color: var(--danger-color);
+ width: 12px;
+ height: 12px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border-radius: 50%;
+ box-shadow: 0 2px 4px var(--shadow-color);
}
.time {
- font-size: 60px;
+ font-size: 50px;
+ font-weight: 400;
+ letter-spacing: 1px;
}
.date {
- color: #aaa;
- font-size: 14px;
- letter-spacing: 0.3px;
+ color: var(--accent-color);
+ font-size: 16px;
+ letter-spacing: 0.5px;
text-transform: uppercase;
}
@@ -125,12 +130,65 @@ body {
background-color: var(--primary-color);
color: var(--secondary-color);
border-radius: 50%;
- height: 18px;
- width: 18px;
+ height: 20px;
+ width: 20px;
display: inline-flex;
align-items: center;
justify-content: center;
- line-height: 18px;
- transition: all 0.5s ease-in;
+ line-height: 20px;
font-size: 12px;
-}
\ No newline at end of file
+ transition: all 0.5s ease-in-out;
+ box-shadow: 0 2px 4px var(--shadow-color);
+}
+
+.alarm-container {
+ margin-top: 20px;
+ text-align: center;
+}
+
+.set-alarm {
+ cursor: pointer;
+ background-color: var(--accent-color);
+ color: var(--secondary-color);
+ border: 0;
+ border-radius: 50px;
+ padding: 10px 20px;
+ font-size: 16px;
+ font-weight: 400;
+ margin-top: 10px;
+ transition: all 0.3s ease-in-out;
+}
+
+.set-alarm:hover {
+ background-color: var(--primary-color);
+ color: var(--accent-color);
+ transform: scale(1.05);
+}
+
+.alarm-status {
+ margin-top: 10px;
+ font-size: 16px;
+ color: var(--danger-color);
+}
+.alarm-notification {
+ position: fixed;
+ top: 20px;
+ left: 50%;
+ transform: translateX(-50%);
+ background-color: var(--danger-color);
+ color: var(--secondary-color);
+ padding: 15px;
+ border-radius: 8px;
+ font-size: 16px;
+ font-weight: bold;
+ opacity: 0;
+ visibility: hidden;
+ transition: opacity 0.5s ease, visibility 0.5s ease;
+ box-shadow: 0 4px 6px var(--shadow-color);
+}
+
+.alarm-notification.show {
+ opacity: 1;
+ visibility: visible;
+}
+