This is a really cool CSS3 Analogue Clock. Its not Flash, but its completely written in CSS3 + Jquery. Transform: rotate; is a new feature of CSS 3 which lets you... well, rotate stuff. Transform will also allow you to scale, skew and translate (move) objects in your web page. All these can be animated by the Transition property (complete with easing and duration).
The mark-up for the clock is a simple unordered list. Each list item will hold a moving part and is given a relevant id. Here it is.
function hello() { <ul id="clock"> <li id="sec"></li> <li id="hour"></li> <li id="min"></li> </ul>
The CSS
#clock { position: relative; width: 600px; height: 600px; margin: 20px auto 0 auto; background: url(clockface.jpg); list-style: none; } #sec, #min, #hour { position: absolute; width: 30px; height: 600px; top: 0px; left: 285px; } #sec { background: url(sechand.png); z-index: 3; } #min { background: url(minhand.png); z-index: 2; } #hour { background: url(hourhand.png); z-index: 1; }
Get the timing information for the clock.
Calculate and inject the CSS style (rotation angle) for each element.
Update the CSS style info at regular intervals.
It should be noted that jQuery has no problem at all using these new CSS3 properties. Also as the styles are allocated dynamically and not from the stylesheet this clock still validates as CSS2.1!
Getting the time
Some of you might (well I did!) equate date and time info with PHP, and when I started this PHP was my first thought, but then I discovered javascript has it's own built in functionality for getting date and time data too. Note with JavaScript the time is local to the machine not the server.
We're going to get this info using the Date() syntax and assigning that to a variable. We can get each hands specific data by attaching GetSeconds(), GetMinutes() or GetHours() to the Date() syntax like this example.
The above code will return a number between 0 and 59 and store it inside the variable 'seconds'.
Getting the angle
Next we have calculate the angle for each hand. In the case of the seconds and minutes which have 60 increments per rotation we just divide 360 by 60 which gives us 6. This means that for each second or minute we have to rotate the hand by 6 degrees. We're going to to store this equation inside another variable. For the seconds it will look like this.
The hour hand throws up a different scenario. Because there are 12 increments per rotation the angle for each hour is 30 degrees. That's 360/12=30. Now that would be simple if a clocks hour hand moved in hour increments but it does't. It moves in smaller amounts based on the minute value. Say at 4:30 the hour hand will be half way between 3 and 4. So how do we do this. Here's the code.
Basically we're going to add the current number of minutes divided by two which should give us a number between 0.5 and 29.5 ('rotate' can handle all floating point numbers) this puts the hand somewhere between any given 30 degree (hour) increment.
Example:
2.40 would be: 2 * 30 = 60 degrees
+ 40 / 2 = 20 degrees
--------- --- ----------
hdegree = 80 degrees
I did think that the clock might explode when it got past 12 as it would be a number higher then 360 but it worked fine.
So now we've figured the math lets inject the new CSS.
Set the style
Here is the CSS3 rotate as if it were in a style sheet.
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
-o-transform: rotate(45deg);
transform: rotate(45deg);
}
Here it is injected by jQuery (NOTE: As of jQuery 1.8, the proper vendor prefixes will be applied when using the .css() function. Older versions of jQuery will need to apply them manually).
"transform": "rotate(45deg)"
});
The problem we have here is getting the variable 'sdegree' (which holds our angle) into this syntax to replace the (45deg). At first I just tried putting the variable between the brackets but it wouldn't have it. To make this work we need to build a 'string' inside another variable called 'srotate' and completely replace the second argument. Here's how we make it.
The jQuery will now be written as this.
Putting it all together (in time!)
The whole jQuery code looks like this.
$(function() { setInterval( function() { var seconds = new Date().getSeconds(); var sdegree = seconds * 6; var srotate = "rotate(" + sdegree + "deg)"; $("#sec").css({ "transform": srotate }); }, 1000 ); setInterval( function() { var hours = new Date().getHours(); var mins = new Date().getMinutes(); var hdegree = hours * 30 + (mins / 2); var hrotate = "rotate(" + hdegree + "deg)"; $("#hour").css({ "transform": hrotate}); }, 1000 ); setInterval( function() { var mins = new Date().getMinutes(); var mdegree = mins * 6; var mrotate = "rotate(" + mdegree + "deg)"; $("#min").css({ "transform" : mrotate }); }, 1000 ); });
Notice how we've used a JavaScript setInterval so the function is run every second. The variables that get the time data have to be inside the function so they update too. If not they would only gather that data on page load once, making a pretty rubbish clock.
Our clock should now work (in Safari and other modern browsers).
Alternatives
Flash is the obvious one but unless you've got ActionScript chops I'd give it a swerve. This may even be possible with PHP using the GD image library to rotate the hands but that's way above my level.
Incidentally, Soh Tanaka posted this a few days after by pure coincidence: CSS clock. His clock uses JavaScript to add classes and sprite images for the hands.
Conclusion
So there you have it folks, a real and (probably the only) practical use for the new CSS3 property transform:rotate. I for one can't wait for upside down and sideways websites (Yes, you can even rotate the HTML tag! Although look what that does to Safari) and my personal favorite the spinning/zooming cartoon newspaper blog posts.
So go on, give some of those new CSS3 features a try!