Creating an Interactive Clock and Timer with HTML, CSS, and JavaScript
Introduction:
To embark on this coding adventure, make sure you have a code editor installed and a basic understanding of HTML, CSS, and JavaScript. You can follow along with the steps below or find the complete code on [your GitHub repository link].
Setting Up the HTML Structure:
html
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8" /> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
<title>Stopwatch</title> | |
<link | |
href="https://fonts.googleapis.com/css?family=Orbitron|Text+Me+One" | |
rel="stylesheet" | |
/> | |
<link rel="stylesheet" href="style.css" /> | |
<script | |
src="https://kit.fontawesome.com/6b0af4bcb3.js" | |
crossorigin="anonymous" | |
></script> | |
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> | |
</head> | |
<body> | |
<div id="blurScreen" class="blur-screen"></div> | |
<!-- Warning GIF for portrait mode --> | |
<div | |
id="portraitWarning" | |
class="warning-container" | |
style="background-color: black" | |
> | |
<img src="warning.gif" alt="Portrait Warning" /> | |
<p class="warning_message"> | |
Please rotate your device to landscape mode/ or resize your window for | |
the best experience. | |
</p> | |
</div> | |
<div class="container"> | |
<div class="ClockHolder"> | |
<div class="WeekDays"> | |
<span>sat</span> | |
<span>sun</span> | |
<span>mon</span> | |
<span>tue</span> | |
<span>wed</span> | |
<span>thu</span> | |
<span>fri</span> | |
</div> | |
<div class="TimeHolder"> | |
<div class="TimeOptions"> | |
<i class="fas fa-clock" data-title="Time"></i> | |
<i class="fas fa-stopwatch" data-title="StopWatch"></i> | |
<i class="far fa-clock" data-title="CountDown"></i> | |
</div> | |
<div class="Numbers"> | |
<div class="NumberHolder H1"> | |
<span class="d1"></span> | |
<span class="d2"></span> | |
<span class="d3"></span> | |
<span class="d4"></span> | |
<span class="d5"></span> | |
<span class="d6"></span> | |
<span class="d7"></span> | |
</div> | |
<div class="NumberHolder H2"> | |
<span class="d1"></span> | |
<span class="d2"></span> | |
<span class="d3"></span> | |
<span class="d4"></span> | |
<span class="d5"></span> | |
<span class="d6"></span> | |
<span class="d7"></span> | |
</div> | |
<span>:</span> | |
<div class="NumberHolder M1"> | |
<span class="d1"></span> | |
<span class="d2"></span> | |
<span class="d3"></span> | |
<span class="d4"></span> | |
<span class="d5"></span> | |
<span class="d6"></span> | |
<span class="d7"></span> | |
</div> | |
<div class="NumberHolder M2"> | |
<span class="d1"></span> | |
<span class="d2"></span> | |
<span class="d3"></span> | |
<span class="d4"></span> | |
<span class="d5"></span> | |
<span class="d6"></span> | |
<span class="d7"></span> | |
</div> | |
<span>:</span> | |
<div class="NumberHolder S1"> | |
<span class="d1"></span> | |
<span class="d2"></span> | |
<span class="d3"></span> | |
<span class="d4"></span> | |
<span class="d5"></span> | |
<span class="d6"></span> | |
<span class="d7"></span> | |
</div> | |
<div class="NumberHolder S2"> | |
<span class="d1"></span> | |
<span class="d2"></span> | |
<span class="d3"></span> | |
<span class="d4"></span> | |
<span class="d5"></span> | |
<span class="d6"></span> | |
<span class="d7"></span> | |
</div> | |
</div> | |
<span class="Pause"><i class="fas fa-pause"></i>Pause</span> | |
<span class="Stop active"><i class="fas fa-stop"></i>Stop</span> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<script> | |
window.addEventListener("orientationchange", function () { | |
var blurScreen = document.getElementById("blurScreen"); | |
var warningContainer = document.getElementById("portraitWarning"); | |
if (window.orientation === 0) { | |
// Portrait mode | |
// Show blur screen and warning container | |
blurScreen.style.display = "none"; | |
warningContainer.style.display = "flex"; | |
// Add fading animation | |
setTimeout(function () { | |
blurScreen.style.opacity = "0"; | |
warningContainer.style.opacity = "1"; // Set opacity to 1 for warning | |
}, 0); | |
// Hide blur screen after the animation ends | |
setTimeout(function () { | |
blurScreen.style.display = "none"; | |
blurScreen.style.opacity = "1"; // Reset opacity for future use | |
}, 500); // Adjust the duration as needed (500 milliseconds in this example) | |
} else { | |
// Hide blur screen and warning container for landscape mode | |
blurScreen.style.display = "none"; | |
warningContainer.style.display = "none"; | |
} | |
}); | |
function handleScreenSize() { | |
var blurScreen = document.getElementById("blurScreen"); | |
var warningContainer = document.getElementById("portraitWarning"); | |
if (window.innerWidth <= 768) { | |
// Adjust the threshold as needed | |
// Show blur screen and warning container | |
blurScreen.style.display = "block"; | |
warningContainer.style.display = "flex"; | |
// Add fading animation | |
setTimeout(function () { | |
blurScreen.style.opacity = "0"; | |
warningContainer.style.opacity = "1"; // Set opacity to 1 for warning | |
}, 0); | |
// Hide blur screen after the animation ends | |
setTimeout(function () { | |
blurScreen.style.display = "none"; | |
blurScreen.style.opacity = "1"; // Reset opacity for future use | |
}, 500); // Adjust the duration as needed (500 milliseconds in this example) | |
} else { | |
// Hide blur screen and warning container for larger screens | |
blurScreen.style.display = "none"; | |
warningContainer.style.display = "none"; | |
} | |
} | |
// Initial check on page load | |
window.addEventListener("load", handleScreenSize); | |
// Check on window resize | |
window.addEventListener("resize", handleScreenSize); | |
</script> | |
<script src="script.js"></script> | |
</body> | |
</html> |
Styling with CSS:
css
html, body, div, span, applet, object, iframe, | |
h1, h2, h3, h4, h5, h6, p, blockquote, pre, | |
a, abbr, acronym, address, big, cite, code, | |
del, dfn, em, img, ins, kbd, q, s, samp, | |
small, strike, strong, sub, sup, tt, var, | |
b, u, i, center, | |
dl, dt, dd, ol, ul, li, | |
fieldset, form, label, legend, | |
table, caption, tbody, tfoot, thead, tr, th, td, | |
article, aside, canvas, details, embed, | |
figure, figcaption, footer, header, hgroup, | |
menu, nav, output, ruby, section, summary, | |
time, mark, audio, video { | |
margin: 0; | |
padding: 0; | |
border: 0; | |
font-size: 100%; | |
font: inherit; | |
vertical-align: baseline; | |
} | |
/* HTML5 display-role reset for older browsers */ | |
article, aside, details, figcaption, figure, | |
footer, header, hgroup, menu, nav, section { | |
display: block; | |
} | |
body { | |
line-height: 1; | |
} | |
ol, ul { | |
list-style: none; | |
} | |
blockquote, q { | |
quotes: none; | |
} | |
blockquote:before, blockquote:after, | |
q:before, q:after { | |
content: ''; | |
content: none; | |
} | |
table { | |
border-collapse: collapse; | |
border-spacing: 0; | |
} | |
/* Css Code */ | |
body{ | |
background-color: #000000; | |
font-family: 'Text Me One', sans-serif; | |
} | |
.container{ | |
width: 90%; | |
max-width: 1400px; | |
position: absolute; | |
top: 50%; | |
left: 50%; | |
transform: translate(-50%,-50%); | |
display: flex; | |
justify-content: center; | |
} | |
.ClockHolder{ | |
width: 500px; | |
background-color: #1b252a; | |
padding: 30px 50px; | |
border-radius: 15px; | |
border: 3px solid #0277BD; | |
position: relative; | |
} | |
.ClockHolder::after{ | |
content: " "; | |
position: absolute; | |
bottom: -15px; | |
left: 50%; | |
width: 70%; | |
height: 15px; | |
background-color: #0277bd; | |
transform: translate(-50%,0); | |
border-radius: 3px 3px 8px 8px; | |
} | |
.ClockHolder::before{ | |
} | |
.WeekDays{ | |
display: flex; | |
width: 100%; | |
justify-content: space-between; | |
text-transform: uppercase; | |
color: #646c72; | |
cursor: default; | |
} | |
.WeekDays .active{ | |
color: aliceblue; | |
position: relative; | |
} | |
.WeekDays .active::after{ | |
content: ""; | |
position: absolute; | |
bottom: -3px; | |
left: 0; | |
height: 2px; | |
width: 100%; | |
background-color: aliceblue; | |
} | |
.Numbers, | |
.TimeHolder{ | |
display: flex; | |
justify-content: space-around; | |
font-size: 80px; | |
} | |
.NumberHolder { | |
width: 50px; | |
height: 80px; | |
} | |
.Formats span { | |
font-size: 1.5em; | |
} | |
.TimeFormat { | |
height: 90px; | |
} | |
} | |
/* Add styles for portrait mode (hidden by default) */ | |
@media only screen and (max-width: 768px) and (orientation: portrait) { | |
.portrait-warning { | |
display: block; | |
text-align: center; | |
padding: 20px; | |
background-color: #ff0000; | |
color: #ffffff; | |
font-size: 18px; | |
font-weight: bold; | |
} | |
} | |
/* Add this CSS for the blur screen and warning container */ | |
.blur-screen { | |
display: block; | |
position: fixed; | |
top: 0; | |
left: 0; | |
width: 100%; | |
height: 100%; | |
background-color: #000000; | |
z-index: 1; /* Ensure the blur screen is behind other elements */ | |
} | |
.warning-container { | |
display: block; | |
position: fixed; | |
top: 50%; | |
left: 50%; | |
right: 50%; | |
transform: translate(-50%, -50%); | |
z-index: 2; | |
color: #f9d8d8; | |
width: 100%; | |
height: auto; | |
font-family: cursive, sans-serif; | |
font-size: auto; | |
font-weight: 500; | |
} | |
.warning-container img { | |
max-width: 100%; | |
max-height: 100%; | |
} | |
.warning_message{ | |
font-size: 30px; | |
font-weight: 500; | |
text-align: center; | |
margin-bottom: 20px; | |
padding: 0 20px 0 20px; | |
color: white; | |
position: fixed; | |
top: 50%; | |
font-family: cursive, monospace; | |
} |
Coding the JavaScript:
javascript
Copy code
// JavaScript Code - script.js
var Format = 1, | |
TimeHolder = 0, | |
StopChecker = 0; | |
function resetTimer() { | |
$(".S1").removeClass().addClass("NumberHolder S1 show0"); | |
$(".S2").removeClass().addClass("NumberHolder S2 show0"); | |
$(".M1").removeClass().addClass("NumberHolder M1 show0"); | |
$(".M2").removeClass().addClass("NumberHolder M2 show0"); | |
$(".H1").removeClass().addClass("NumberHolder H1 show0"); | |
$(".H2").removeClass().addClass("NumberHolder H2 show0"); | |
} | |
function SetDay(DD) { | |
$(".WeekDays span:nth-child(" + ((DD + 2) % 7) + ")").addClass("active"); | |
} | |
function Run24hr(S1, S2, M1, M2, H1, H2) { | |
$(".S1") | |
.removeClass() | |
.addClass("NumberHolder S1 show" + S1); | |
$(".S2") | |
.removeClass() | |
.addClass("NumberHolder S2 show" + S2); | |
$(".M1") | |
.removeClass() | |
.addClass("NumberHolder M1 show" + M1); | |
$(".M2") | |
.removeClass() | |
.addClass("NumberHolder M2 show" + M2); | |
$(".H1") | |
.removeClass() | |
.addClass("NumberHolder H1 show" + H1); | |
$(".H2") | |
.removeClass() | |
.addClass("NumberHolder H2 show" + H2); | |
} | |
function Run12hr(S1, S2, M1, M2, HH) { | |
if (HH > 12) { | |
HH = HH - 12; | |
$(".Formats span:nth-child(2)").addClass("active"); | |
} else { | |
$(".Formats span:nth-child(1)").addClass("active"); | |
} | |
var H1 = Math.floor(HH / 10), | |
H2 = HH % 10; | |
$(".S1") | |
.removeClass() | |
.addClass("NumberHolder S1 show" + S1); | |
$(".S2") | |
.removeClass() | |
.addClass("NumberHolder S2 show" + S2); | |
$(".M1") | |
.removeClass() | |
.addClass("NumberHolder M1 show" + M1); | |
$(".M2") | |
.removeClass() | |
.addClass("NumberHolder M2 show" + M2); | |
if (H1 === 0) { | |
$(".H1").fadeOut(0); | |
} else { | |
$(".H1") | |
.fadeIn() | |
.removeClass() | |
.addClass("NumberHolder H1 show" + H1); | |
} | |
$(".H2") | |
.removeClass() | |
.addClass("NumberHolder H2 show" + H2); | |
} | |
function Stopwatch(TimeHolder) { | |
var HH = Math.floor(TimeHolder / 3600), | |
MM = Math.floor((TimeHolder - HH * 3600) / 60), | |
SS = Math.floor(TimeHolder - HH * 3600 - MM * 60); | |
var S1 = Math.floor(SS / 10), | |
S2 = SS % 10, | |
M1 = Math.floor(MM / 10), | |
M2 = MM % 10, | |
H1 = Math.floor(HH / 10), | |
H2 = HH % 10; | |
Run24hr(S1, S2, M1, M2, H1, H2); | |
} | |
function update_time() { | |
var dt = new Date(), | |
HH = dt.getHours(), | |
MM = dt.getMinutes(), | |
SS = dt.getSeconds(), | |
DD = dt.getDay(); | |
SetDay(DD); | |
var S1 = Math.floor(SS / 10), | |
S2 = SS % 10, | |
M1 = Math.floor(MM / 10), | |
M2 = MM % 10, | |
H1 = Math.floor(HH / 10), | |
H2 = HH % 10; | |
if (Format === 1) { | |
Run24hr(S1, S2, M1, M2, H1, H2); | |
} else if (Format === 2) { | |
Run12hr(S1, S2, M1, M2, HH); | |
} else if (Format === 3 && StopChecker === 0) { | |
TimeHolder++; | |
Stopwatch(TimeHolder); | |
} else if (Format === 4 && StopChecker === 0) { | |
if (TimeHolder > 0) { | |
StopChecker = 0; | |
resetTimer(); | |
$(this).removeClass("active"); | |
$(".Pause").addClass("active"); | |
$(".AlarmInput").addClass("DisNone"); | |
$(".Numbers").fadeIn(0); | |
} | |
} | |
}); | |
$(".Pause").on("click", function () { | |
StopChecker = 1; | |
$(this).removeClass("active"); | |
$(".Start").addClass("active"); | |
}); | |
$(".Stop").on("click", function () { | |
$("body").removeClass("BgAnimation"); | |
if (Format === 3) { | |
StopChecker = 1; | |
TimeHolder = 0; | |
resetTimer(); | |
$(".Pause").removeClass("active"); | |
$(".Start").addClass("active"); | |
} else if (Format === 4) { | |
resetTimer(); | |
StopChecker = 1; | |
$(".AlarmInput").removeClass("DisNone"); | |
$(".Numbers").fadeOut(0); | |
$(".AlarmInput input").val(""); | |
$(".Pause").removeClass("active"); | |
$(".Start").addClass("active"); | |
} | |
}); | |
$(".fas.fa-clock").on("click", function () { | |
$("body").removeClass("BgAnimation"); | |
if ($(".Type .active").html() === "12hr") { | |
Format = 2; | |
} else { | |
Format = 1; | |
} | |
StopChecker = 0; | |
$(".TimeHolder").removeClass().addClass("TimeHolder"); | |
$(".Numbers").fadeIn(0); | |
}); | |
$(".far.fa-clock").on("click", function () { | |
$("body").removeClass("BgAnimation"); | |
$(".H1").fadeIn(); | |
if (!$(".TimeHolder").hasClass("Alarm")) { | |
$(".TimeHolder").removeClass().addClass("TimeHolder Alarm"); | |
Format = 4; | |
resetTimer(); | |
StopChecker = 1; | |
$(".AlarmInput").removeClass("DisNone"); | |
$(".TimeHolder").addClass("Alarm"); | |
$(".Numbers").fadeOut(0); | |
$(".Pause").removeClass("active"); | |
$(".Start").addClass("active"); | |
} | |
}); | |
// Alarm Out | |
function AlarmOut() { | |
$("body").addClass("BgAnimation"); | |
resetTimer(); | |
StopChecker = 1; | |
} | |
update_time(); |
Features Showcase:
1. Stylish Clock:
Begin with creating a visually appealing clock that displays both 12-hour and 24-hour formats. Customize the design to suit your taste.
2. Dynamic Timer:
Add interactive timer functionality. Users can switch between stopwatch and countdown modes. The timer updates in real-time.
3. Responsive Design:
Ensure a seamless experience by making the project responsive. It works flawlessly on both desktop and mobile devices.
4. Sound Effects:
Enhance user interaction with subtle sound effects. For example, set an alarm sound when the countdown timer hits zero.
Conclusion:
Congratulations! You've successfully built an interactive clock and timer using HTML, CSS, and JavaScript. This project is a fantastic way to practice coding skills while creating something functional and visually appealing.
Feel free to experiment further, add more features, or even share your customized version with me and the coding community. Happy coding!
Author: Prateek Kumar Singh
Project Link : Project_Link
GitHub Repository Link: GitHub_Repository_Link
Comments
Post a Comment