In this tutorial we will be building an analog wall clock using jQuery. We will learn about retrieving the current time, rotating elements and cross-browser support. This tutorial requires a basic knowledge of HTML, CSS and jQuery.
We will be using the following files throughout this tutorial. You can download them using the link below. Feel free to use an alternative structure, but remember to change your file paths from those in the example code.
Let’s take a quick look at our file structure before getting started. We will be working with three files in this tutorial –index.htm, style.css, and page_scripts.js. If you were working with a larger project, you may want to keep your JavaScript files in a separate directory, but for simplicity we will keep it in the root directory.
Building the Clock Face
The first thing we need to do is create a container div
for the clock. This is where we will add all of the clock components.
Open the index.htm file and add a div
with the class of “clock” to the body.
<!DOCTYPE HTML>
<html>
<head>
<title>jQuery Analog Clock Demo</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="clock"></div>
</body>
<script src="//code.jquery.com/jquery-latest.min.js" type="text/javascript"></script>
<script src="page_scripts.js" type="text/javascript"></script>
</html>
Now we need to add the new div
to our style.css file. Notice the border-radius: 106px;
in the following code. The “clock” div is a 200px square with rounded corners create the illusion of a circle. The radius size is calculated by finding the radius of the circle including the border.
.clock {
width: 200px;
height: 200px;
background: -webkit-radial-gradient(#3b3b3b, #000);
background: radial-gradient(#3b3b3b, #000);
box-shadow: inset 0px 0px 30px #777, 0px 2px 18px rgba(0,0,0,0.5), 0px 20px 40px #bbb;
border: 6px solid #222;
border-radius: 106px;
margin: auto;
position: absolute;
top: 0; bottom: 0; left: 0; right: 0;
}
Open the index.htm file in your web browser and take a look. You should see a dark circle in the center of the screen with a radial background.
Building the Hands
It’s time to add some hands to this clock! Get it? It’s a clock pun! Anyway, as you can see in the code below, we need to add three new elements for the clock hands and one for the cap. Add the following code to the index.htm file.
<div class="clock">
<div class="minute-hand"></div>
<div class="hour-hand"></div>
<div class="second-hand"></div>
<div class="pin"></div>
</div>
Now let’s go back to the style.css file and add the following code for our new clock parts.
.hour-hand {
width: 4px;
height: 55px;
background: #fff;
box-shadow: 0px 0px 7px #000;
position: absolute;
top: 45px;
left: 98px;
}
.minute-hand {
width: 4px;
height: 80px;
background: #fff;
box-shadow: 0px 0px 4px #000;
position: absolute;
top: 20px;
left: 98px;
}
.second-hand {
width: 2px;
height: 80px;
background: #bbb;
box-shadow: 0px 0px 7px #000;
position: absolute;
top: 20px;
left: 99px;
}
.pin {
width: 10px;
height: 10px;
background: #111;
border-radius: 10px;
margin: auto;
position: absolute;
top: 0; bottom: 0; left: 0; right: 0;
}
If you refresh the page in your browser, you’ll notice that the hands are currently stacked on top of each other. If the cap didn’t make sense before, it should now. It’s just there to keep the center neat and tidy.
Retrieving the Current Time
So our clock looks great, but it doesn’t do anything useful. We need to get the current time and use it to change the position of the hands. Let’s create a call to jQuery asking for the current local time when the page is loaded.
Open the page_scripts.js file and add the following code inside of the main jQuery function.
$(document).ready(function() {
var dt = new Date();
alert(time);
});
The Date()
object gets the current time and the alert()
method creates a pop-up containing the time so we can check for accuracy. Refresh the page in your browser and check that you are getting the correct time.
Rotating the Clock Hands
We need to do a little math to move the clock hands to the correct position based on the time. To do this, we will be using the transform: rotate()
and transform-origin
CSS properties. The transform: rotate()
property allows us to turn an element on a given axis and transform-origin
defines the axis point.
We need to split the circle into 60 equal parts (one for every second). To do this, we take 360 (degrees in a circle) and divide by 60. We get an answer of 6 and that is how many degrees the second hand will rotate every second. We can use the same math for the minute hand as well since there are 60 minutes in a hour. For the hour hand, we can simply divide 360 by 12 since that is the number of hours displayed on a clock face. The answer to that one is 30, so the hour hand will move 30 degrees every hour.
You will notice in the example below that we have used a few methods from the Date()
object to split the time into separate variables for seconds, minutes, and hours. Following the new variables are the CSS transform: rotate()
properties for each hand of the clock. These properties are rather new to CSS, so we will need to use the prefixed version for browsers that do not yet support them.
Take a look at the code below and add it to the page_scripts.js file.
var sec_deg = dt.getSeconds() * 6;
var min_deg = dt.getMinutes() * 6;
var hr_deg = dt.getHours() * 30;
$('.clock .second-hand').css({'-webkit-transform':'rotate(' + sec_deg + 'deg)', '-moz-transform':'rotate(' + sec_deg + 'deg)', '-o-transform':'rotate(' + sec_deg + 'deg)', '-ms-transform':'rotate(' + sec_deg + 'deg)', 'transform':'rotate(' + sec_deg + 'deg)'});
$('.clock .minute-hand').css({'-webkit-transform':'rotate(' + min_deg + 'deg)', '-moz-transform':'rotate(' + min_deg + 'deg)', '-o-transform':'rotate(' + min_deg + 'deg)', '-ms-transform':'rotate(' + min_deg + 'deg)', 'transform':'rotate(' + min_deg + 'deg)'});
$('.clock .hour-hand').css({'-webkit-transform':'rotate(' + hr_deg + 'deg)', '-moz-transform':'rotate(' + hr_deg + 'deg)', '-o-transform':'rotate(' + hr_deg + 'deg)', '-ms-transform':'rotate(' + hr_deg + 'deg)', 'transform':'rotate(' + hr_deg + 'deg)'});
Before we check our progress, we need to add the transform-origin property to style.css. Otherwise the clock hands would rotate from the center of each element instead of the center of the clock face.
Add the following code to the style.css file.
.hour-hand,
.minute-hand,
.second-hand {
-webkit-transform-origin: 50% 100%;
-moz-transform-origin: 50% 100%;
-o-transform-origin: 50% 100%;
-ms-transform-origin: 50% 100%;
transform-origin: 50% 100%;
}
Now we can take a look at our changes. You’ll notice that the time is correct, but it does not change as time moves on. This is because jQuery is only running our code one time when the page is loaded.
Animating the Clock
I saved the fun part for last! It’s time to animate the hands so they change auto-magically. To accomplish this, we need to wrap all of our jQuery code in a setInterval()
method. This will run the code over and over at a given frequency of time. The setInterval()
method accepts a time parameter in milliseconds. In our case, we want to rerun our code every 1 second which equates to 1000 milliseconds.
Go back to the page_scripts.js file and add a setInterval() method around everything except the main jQuery function.
$(document).ready(function() {
setInterval(function(){
var dt = new Date();
//alert(time);
var sec_deg = dt.getSeconds() * 6;
var min_deg = dt.getMinutes() * 6;
var hr_deg = dt.getHours() * 30;
$('.clock .second-hand').css({'-webkit-transform':'rotate(' + sec_deg + 'deg)', '-moz-transform':'rotate(' + sec_deg + 'deg)', '-o-transform':'rotate(' + sec_deg + 'deg)', '-ms-transform':'rotate(' + sec_deg + 'deg)', 'transform':'rotate(' + sec_deg + 'deg)'});
$('.clock .minute-hand').css({'-webkit-transform':'rotate(' + min_deg + 'deg)', '-moz-transform':'rotate(' + min_deg + 'deg)', '-o-transform':'rotate(' + min_deg + 'deg)', '-ms-transform':'rotate(' + min_deg + 'deg)', 'transform':'rotate(' + min_deg + 'deg)'});
$('.clock .hour-hand').css({'-webkit-transform':'rotate(' + hr_deg + 'deg)', '-moz-transform':'rotate(' + hr_deg + 'deg)', '-o-transform':'rotate(' + hr_deg + 'deg)', '-ms-transform':'rotate(' + hr_deg + 'deg)', 'transform':'rotate(' + hr_deg + 'deg)'});
}, 1000);
});
Refresh the index.htm file in your browser and you should have a working clock!
Final Thoughts
You could take this tutorial ever further with a little imagination. You could create separate clocks for difference time-zones or a date area on the clock face. You could even load it up on a iPad and hang it in your office for a real wall clock effect! Okay, that might be a little ridiculous, but you get the idea. Let me know what do with this little gadget!
Further Resources
CSS Transform Property: http://www.w3schools.com/cssref/css3_pr_transform.asp
CSS Transform-Origin Property: http://www.w3schools.com/cssref/css3_pr_transform-origin.asp
JavaScript setInterval() Method: http://www.w3schools.com/jsref/met_win_setinterval.asp