A Colorful Clock With CSS & jQuery

The first wave of Christmas holidays passed and we are looking forward to New Year’s Eve for a fresh start at all those things we failed to do the last 12 months.

And in the mood of the upcoming holiday, this week we are going to make a colorful jQuery & CSS clock, which will help you keep track of those precious last seconds of the year.

This is also the first tutorial that features our first very own jQuery plug-in – tzineClock (soon to be released officially in a post of its own).

Go ahead, download the demo files and continue with step one.

Step 1 – XHTML

As usual, we start with the XHTML markup. The difference is, that the XHTML is not contained in demo.html, but is dynamically inserted into the page by jQuery (well there is some markup left there after all we need at least one container div for the clock to be inserted in).

This saves us from having to manually type similar blocks of code for each one of the dials (there are three of them, one for the hours, the minutes and the seconds).

Lets take a look at the XHTML that is inserted by jQuery:

jquery.tzineClock.js
view sourceprint?
01.
02.<div class=”green clock”
03.
04.
05.

06.
07.
08.

09.
10.
11.

12.13.

14.
15.
16.

17.18.

19.
20.

This code is contained in jquery.tzineClock/jquery.tzineClock.js. It is generated three times – once for the hours, minutes and seconds. Those are later animated and updated every second, as you’ll see in a moment.

There are three classes that are assigned to the topmost container during the generation process – green, blue and orange. Just by assigning one of those classes, we change the color of the dial.

Lets continue with the next step.

Step 2 – CSS

Before our style sheets can have any effect on the page, we have to include them in the head section of the file:
demo.html
view sourceprint?
1.
2.

Those lines import styles.css and jquery.tzineClock.css in the page. The first one styles the demo page, and the second – the colorful dials (it is part of the plugin).

We can now take a closer look at the CSS rules.
styles.css
view sourceprint?
01.body,h1,h2,h3,p,quote,small,form,input,ul,li,ol,label{
02. /* Simple page reset */
03. margin:0;
04. padding:0;
05.}
06.
07.body{
08. /* Setting default text color, background and a font stack */
09. color:#dddddd;
10. font-size:13px;
11. background: #302b23;
12. font-family:Arial, Helvetica, sans-serif;
13.}
14.
15.#fancyClock{
16. margin:40px auto;
17. height:200px;
18. border:1px solid #111111;
19. width:600px;
20.}

Those few lines are all that is needed to style the demo page. We first implement a simple CSS reset, which will insure that the elements on the page look the same across the different browsers.

Later we style the body of the page and finally the fancyClock div, in which we will later insert the three dials.
jquery.tzineClock.css
view sourceprint?
01..clock{
02. /* The .clock div. Created dynamically by jQuery */
03. background-color:#252525;
04. height:200px;
05. width:200px;
06. position:relative;
07. overflow:hidden;
08. float:left;
09.}
10.
11..clock .rotate{
12. /* There are two .rotate divs – one for each half of the background */
13. position:absolute;
14. width:200px;
15. height:200px;
16. top:0;
17. left:0;
18.}
19.
20..rotate.right{
21. display:none;
22. z-index:11;
23.}
24.
25..clock .bg, .clock .front{
26. width:100px;
27. height:200px;
28. background-color:#252525;
29. position:absolute;
30. top:0;
31.}
32.
33..clock .display{
34. /* Holds the number of seconds, minutes or hours respectfully */
35. position:absolute;
36. width:200px;
37. font-family:”Lucida Sans Unicode”, “Lucida Grande”, sans-serif;
38. z-index:20;
39. color:#F5F5F5;
40. font-size:60px;
41. text-align:center;
42. top:65px;
43. left:0;
44.
45. /* CSS3 text shadow: */
46. text-shadow:4px 4px 5px #333333;
47.}
48.
49./* The left part of the background: */
50.
51..clock .bg.left{ left:0; }
52.
53./* Individual styles for each color: */
54..orange .bg.left{ background:url(img/bg_orange.png) no-repeat left top; }
55..green .bg.left{ background:url(img/bg_green.png) no-repeat left top; }
56..blue .bg.left{ background:url(img/bg_blue.png) no-repeat left top; }
57.
58./* The right part of the background: */
59..clock .bg.right{ left:100px; }
60.
61..orange .bg.right{ background:url(img/bg_orange.png) no-repeat right top; }
62..green .bg.right{ background:url(img/bg_green.png) no-repeat right top; }
63..blue .bg.right{ background:url(img/bg_blue.png) no-repeat right top; }
64.
65..clock .front.left{
66. left:0;
67. z-index:10;
68.}

jquery.tzineClock.css is a part of our plugin (alongside jquery.tzineClock.js) and it styles the colorful dials themselves.

One of the more interesting moments is the use of individual rules that style the colors of the dials, as I mentioned in step one.

You can learn more about the animation from the illustration below:
The animation explained

The animation explained
Step 3 – jQuery

Moving all the JavaScript to the plugin makes it really easy to reuse the code and at the same time enables us to leverage the power of jQuery’s selectors and methods.

To be able to use the jQuery library, we first need to include a couple of scripts in the page:
demo.html
view sourceprint?
1.
2.
3.

The first file is the library itself, included from Google’s CDN, later we have the plug-in and lastly the script file that runs the demo.
script.js
view sourceprint?
1.$(document).ready(function(){
2. /* This code is executed after the DOM has been completely loaded */
3.
4. $(‘#fancyClock’).tzineClock();
5.
6.});

If you’ve followed some of our previous tutorials, you are probably expecting to see some 50+ lines of code here, but this time our scripts file contains only one line of code – a call to our plug-in.

This makes it extremely easy to include the code in an existing site (which is the purpose of jquery plugins in the first place).

Lets dig a little deeper into the plugin:
jquery.tzineClock.js – Part 1
view sourceprint?
01.(function($){
02. // A global object used by the functions of the plug-in:
03. var gVars = {};
04.
05. // Extending the jQuery core:
06.
07. $.fn.tzineClock = function(opts){
08.
09. // “this” contains the elements that were selected when calling the plugin: $(‘elements’).tzineClock();
10. // If the selector returned more than one element, we use the first one:
11. var container = this.eq(0);
12. if(!container)
13. {
14. try{
15. console.log(“Invalid selector!”);
16. } catch(e){}
17.
18. return false;
19. }
20.
21. if(!opts) opts = {};
22.
23. var defaults = {
24. /* Additional options will be added in future versions of the plugin. */
25. };
26.
27. /* Merging the provided options with the default ones (will be used in future versions of the plugin): */
28.
29. $.each(defaults,function(k,v){
30. opts[k] = opts[k] || defaults[k];
31. });
32.
33. // Calling the setUp function and passing the container,
34. // will be available to the setUp function as “this”:
35.
36. setUp.call(container);
37.
38. return this;
39. }
40.
41. function setUp()
42. {
43. // The colors of the dials:
44. var colors = [‘orange’,’blue’,’green’];
45.
46. var tmp;
47. for(var i=0;i<3;i++)
48. {
49. // Creating a new element and setting the color as a class name:
50.
51. tmp = $(‘

‘).attr(‘class’,colors[i]+’ clock’).html(
52. ”+
53. ‘

‘+
54. ‘

‘+
55. ”+
56. ‘

‘+
57. ‘

‘+
58. ”+
59. ‘


60. );
61.
62. // Appending to the fancyClock container:
63. $(this).append(tmp);
64.
65. // Assigning some of the elements as variables for speed:
66. tmp.rotateLeft = tmp.find(‘.rotate.left’);
67. tmp.rotateRight = tmp.find(‘.rotate.right’);
68. tmp.display = tmp.find(‘.display’);
69.
70. // Adding the dial as a global variable. Will be available as gVars.colorName
71. gVars[colors[i]] = tmp;
72. }
73.
74. // Setting up a interval, executed every 1000 milliseconds:
75. setInterval(function(){
76.
77. var currentTime = new Date();
78. var h = currentTime.getHours();
79. var m = currentTime.getMinutes();
80. var s = currentTime.getSeconds();
81.
82. animation(gVars.green, s, 60);
83. animation(gVars.blue, m, 60);
84. animation(gVars.orange, h, 24);
85. },1000);
86. }

Making a plug-in for jQuery comes down to defining a custom function through the jQuery.fn method. This way your function is available on any elements that you normally use jQuery on.

For example, in script.js we select the div width an id of fancyClock and use the tzineClock() method on it: $(‘#fancyClock’).tzineClock();. The elements we selected are later passed to the tzineClock function and are available through the “this” property.

I have left place for future improvements of the plugin, like passing configuration options for the dimensions of the clock, color themes etc. Those will however be implemented in future releases of the plugin.

Because there might be more than one element selected, we extract only the first one of the set with the eq(0) method. Later we have the setUp() function that inserts the markup for the dials and sets up the interval which will update the figures every second.
jquery.tzineClock.js – Part 2
view sourceprint?
01. function animation(clock, current, total)
02. {
03. // Calculating the current angle:
04. var angle = (360/total)*(current+1);
05.
06. var element;
07.
08. if(current==0)
09. {
10. // Hiding the right half of the background:
11. clock.rotateRight.hide();
12.
13. // Resetting the rotation of the left part:
14. rotateElement(clock.rotateLeft,0);
15. }
16.
17. if(angle<=180)
18. {
19. // The left part is rotated, and the right is currently hidden:
20. element = clock.rotateLeft;
21. }
22. else
23. {
24. // The first part of the rotation has completed, so we start rotating the right part:
25. clock.rotateRight.show();
26. clock.rotateLeft.show();
27.
28. rotateElement(clock.rotateLeft,180);
29. element = clock.rotateRight;
30.
31. angle = angle-180;
32. }
33.
34. rotateElement(element,angle);
35.
36. // Setting the text inside of the display element, inserting a leading zero if needed:
37. clock.display.html(current<10?’0’+current:current);
38. }
39.
40. function rotateElement(element,angle)
41. {
42. // Rotating the element, depending on the browser:
43. var rotate = ‘rotate(‘+angle+’deg)’;
44.
45. if(element.css(‘MozTransform’)!=undefined)
46. element.css(‘MozTransform’,rotate);
47.
48. else if(element.css(‘WebkitTransform’)!=undefined)
49. element.css(‘WebkitTransform’,rotate);
50.
51. // A version for internet explorer using filters, works but is a bit buggy (no surprise here):
52.
53. else if(element.css(“filter”)!=undefined)
54. {
55. var cos = Math.cos(Math.PI * 2 / 360 * angle);
56. var sin = Math.sin(Math.PI * 2 / 360 * angle);
57.
58. element.css(“filter”,”progid:DXImageTransform.Microsoft.Matrix(M11=”+cos+”,M12=-“+sin+”,M21=”+sin+”,M22=”+cos+”,SizingMethod=’auto expand’,FilterType=’nearest neighbor’)”);
59. element.css(“left”,-Math.floor((element.width()-200)/2));
60. element.css(“top”,-Math.floor((element.height()-200)/2));
61. }
62. }
63.})(jQuery)

The last two of the functions used by the plug-in are animation and rotateElement. The first one updates the dials according to the value passed (we also pass a parameter with the maximum value so that the function can calculate the rotation).

The next function is the one that actually rotates the passed element. The rotation works only for Firefox, Safari, Chrome and IE6+. Internet Explorer does not support the CSS3 rotation used by the other browsers, but provides a proprietary filter property which allows for a similar transformation.

With this our colorful jQuery clock is complete!
Conclusion

Today we created a colorful clock with the help of CSS, jQuery and our first plug-in. You are free to use the code given here in your own projects. As a bonus, I’ve included the PSD file that I used to make the backgrounds, so you can easily create new colors and designs for the dials.

download
demo

Advertisements
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: