Showing posts with label how to. Show all posts
Showing posts with label how to. Show all posts

How to make a CSS3 and JavaScript analog clock

1 2 3 4 5 6 7 8 9 10 11 12

This is a "How To" guiding the ones that are interesting in the creation of an analog clock, similar to the one on the left, with CSS3 and jQuery. First of all, I would like to say that this is in no way a useful method of placing an analog clock on your website. It's only meant as an experiment with CSS3. If you do want an analog clock, you could probably use Flash or an image based JavaScript clock.

I used as a reference the Windows 7 sidebar clock, but it's not a perfect copy. I could have added a lot more details to make it look closer to the real one, but it would have made it a lot more difficult to implement.

Internet Explorer (any version) has not been targeted for this experiment due to it's lack of CSS3 support, so don't be surprised if it doesn't work. Making it functional in Internet Explorer would have over-complicated the JavaScript, attempting to make it work with IE's filters. With that out of the way, let's get started.

The HTML

All the styles will be set in the stylesheet later on, so don't bother with it for now. You can see there are a lot of tags that make the clock very heavy. That's why this is not a good way to create an analog clock for use on your website.

The div#clock will hold everything together. The div.hour-marks holds all the numbers and hour marks. We could have done without it, but it's good to have some sort of container just for those. The next 3 divs are the clock handles (hours, minutes, seconds). The last span is the round circle in the center of the clock.

<div id="clock">
 <div class="back"></div>

 <div class="hour-marks">
  <span class="mark m1"></span>
  <span class="mark m2"></span>
  <span class="mark m3"></span>
  <span class="mark m4"></span>
  <span class="mark m5"></span>
  <span class="mark m6"></span>
  <span class="mark m7"></span>
  <span class="mark m8"></span>
  <span class="mark m9"></span>
  <span class="mark m10"></span>
  <span class="mark m11"></span>
  <span class="mark m12"></span>
  <span class="hour h1">1</span>
  <span class="hour h2">2</span>
  <span class="hour h3">3</span>
  <span class="hour h4">4</span>
  <span class="hour h5">5</span>
  <span class="hour h6">6</span>
  <span class="hour h7">7</span>
  <span class="hour h8">8</span>
  <span class="hour h9">9</span>
  <span class="hour h10">10</span>
  <span class="hour h11">11</span>
  <span class="hour h12">12</span>
 </div>

 <div class="hour-handle"><span class="handle"></span></div>
 <div class="minute-handle"><span class="handle"></span></div>
 <div class="seconds-handle"><span class="handle"></span></div>

 <span class="center"><span></span></span>
</div>

The CSS

Oh man, this is a lot of CSS for something so trivial. Let's try to lay it out.

We're going to start with our clock div, or better yet, div#clock and standard CSS. I gave it a width and height of 200px, but you can change that to whatever you like. Take note however that you will need to modify the position of the dandles and marks also. Actually you will need to modify pretty much everything. Position:relative will allow us to position everything else inside it with position:absolute.

div#clock{
 width: 200px;
 height: 200px;
 position: relative;
 }

Now for the fun part. We don't need a rectangular clock. That would look unattractive. Instead we will make it round with the border-radius feature in CSS3. This allows you to make the corners of a box element round. But if you take it all the way up, that box will turn into a circle. For that you need to specify at least half of the width or height, in this case 100px. This works best for squares as it creates a perfect circle. The first rule is the standard CSS3 declaration. This is used by Opera also. The next one is the proprietary declaration for Gecko based browsers (Firefox, Flock) and the last, but not least, is the proprietary declaration for Webkit based browsers (Safari, Chrome).

div#clock{
 border-radius: 100px;
 -moz-border-radius: 100px;
 -webkit-border-radius: 100px;
 }

To make it look a little nicer, we'll add a gradient for the background. First the standard CSS background. Opera will use this as it does not have a linear gradient method implemented yet. The second one is for Mozilla and the third for Webkit.

div#clock{
 background: #3a3937;
 background: -moz-linear-gradient(right 240deg, #3a3937, #1b1d1c);
 background: -webkit-gradient(linear, right top, left bottom, from(#3a3937), to(#1b1d1c));
 }

Now we're adding a drop-shadow around our clock, just to make it stand out a bit. This can be changed to look like a halo on a dark background. The color can be changed and also the size of the shadow.

div#clock{
 box-shadow: 0 0 10px #666;
 -moz-box-shadow: 0 0 10px #666;
 -webkit-box-shadow: 0 0 10px #666;
 }

These methods will be used throughout the stylesheet, so there's no point in describing each of them. Here's some more of the CSS:

div#clock div.back{
 width: 184px;
 height: 184px;
 position: absolute;
 top: 8px;
 left: 8px;

 border-radius: 92px;
 -moz-border-radius: 92px;
 -webkit-border-radius: 92px;

 background: #fffdf4;
 background: -moz-linear-gradient(top 260deg, #fffdf4, #e2dfce);
 background: -webkit-gradient(linear, center top, center bottom, from(#fffdf4), to(#e2dfce));

 box-shadow: inset 0 0 5px #000;
 -moz-box-shadow: inset 0 0 9px #000;
 -webkit-box-shadow: inset 0 0 9px #000;
}
div#clock div.hour-marks span{
 display: block;
 position: absolute;
}
div#clock div.hour-marks span.mark{ background: #333; width: 8px; height: 3px;}
div#clock div.hour-marks span.hour{
 font-size: 14px;
 text-align: center;
 font-family: Helvetica, Arial, sans-serif;
 color: #444;
}
div#clock span.center,div#clock span.center span{
 position: absolute;
 top: 95px;
 left: 95px;
 background: #333;
 width: 10px;
 height: 10px;

 border-radius: 5px;
 -moz-border-radius: 5px;
 -webkit-border-radius: 5px;
}
div#clock span.center span{ width: 6px; height: 6px; top: 2px; left: 2px; background: #666;}

In order to rotate our hour marks so they face towards the center of the clock, we will be using -*-transform: rotate(). This rotates the element by a specific number of degrees. Since we have 12 hours and a circle has 360 degrees, each mark will be rotated at 30 degree intervals. The positioning of these marks are more of a guess. I didn't feel like finding a method of calculating where each of them should go on a circle. So I positioned them by eye.

div#clock div.hour-marks span.m1 {-moz-transform: rotate(-60deg); -webkit-transform: rotate(-60deg); -o-transform: rotate(-60deg); top:  22px; right:  52px;}
div#clock div.hour-marks span.m2 {-moz-transform: rotate(-30deg); -webkit-transform: rotate(-30deg); -o-transform: rotate(-30deg); top:  52px; right:  22px;}
div#clock div.hour-marks span.m3 {-moz-transform: rotate(0deg);   -webkit-transform: rotate(0deg);   -o-transform: rotate(0deg);   top: 100px; right:   8px;}
div#clock div.hour-marks span.m4 {-moz-transform: rotate(30deg);  -webkit-transform: rotate(30deg);  -o-transform: rotate(30deg);  top: 146px; right:  22px;}
div#clock div.hour-marks span.m5 {-moz-transform: rotate(60deg);  -webkit-transform: rotate(60deg);  -o-transform: rotate(60deg);  top: 176px; right:  54px;}
div#clock div.hour-marks span.m6 {-moz-transform: rotate(90deg);  -webkit-transform: rotate(90deg);  -o-transform: rotate(90deg);  top: 188px; right:  95px;}
div#clock div.hour-marks span.m7 {-moz-transform: rotate(120deg); -webkit-transform: rotate(120deg); -o-transform: rotate(120deg); top: 176px; right: 140px;}
div#clock div.hour-marks span.m8 {-moz-transform: rotate(150deg); -webkit-transform: rotate(150deg); -o-transform: rotate(150deg); top: 146px; right: 170px;}
div#clock div.hour-marks span.m9 {-moz-transform: rotate(180deg); -webkit-transform: rotate(180deg); -o-transform: rotate(180deg); top: 100px; right: 184px;}
div#clock div.hour-marks span.m10{-moz-transform: rotate(210deg); -webkit-transform: rotate(210deg); -o-transform: rotate(210deg); top:  52px; right: 170px;}
div#clock div.hour-marks span.m11{-moz-transform: rotate(240deg); -webkit-transform: rotate(240deg); -o-transform: rotate(240deg); top:  22px; right: 140px;}
div#clock div.hour-marks span.m12{-moz-transform: rotate(270deg); -webkit-transform: rotate(270deg); -o-transform: rotate(270deg); top:  10px; right:  95px;}

div#clock div.hour-marks span.h1 { top:  27px; right:  62px;}
div#clock div.hour-marks span.h2 { top:  50px; right:  35px;}
div#clock div.hour-marks span.h3 { top:  90px; right:  20px; font-weight: bold; font-size: 16px}
div#clock div.hour-marks span.h4 { top: 130px; right:  35px;}
div#clock div.hour-marks span.h5 { top: 153px; right:  62px;}
div#clock div.hour-marks span.h6 { top: 163px; right:  95px; font-weight: bold;font-size: 16px}
div#clock div.hour-marks span.h7 { top: 153px; right: 132px;}
div#clock div.hour-marks span.h8 { top: 130px; right: 160px;}
div#clock div.hour-marks span.h9 { top:  90px; right: 170px; font-weight: bold;font-size: 16px}
div#clock div.hour-marks span.h10{ top:  50px; right: 160px;}
div#clock div.hour-marks span.h11{ top:  27px; right: 132px;}
div#clock div.hour-marks span.h12{ top:  20px; right: 100px; font-weight: bold;font-size: 16px}

The handles are also rotated using CSS3 and JavaScript. To make them rotate around a certain axis, we need to set the transformation origin. If we don't do that, they would just spin in one place, like the needle on a compass.

div#clock div.hour-handle, div#clock div.minute-handle, div#clock div.seconds-handle{
 height: 55px;
 width: 6px;
 position: absolute;
 top: 45px;
 left: 97px;
 overflow: hidden;

 -moz-transform-origin: 50% 100%;
 -webkit-transform-origin: 50% 100%;
 -o-transform-origin: 50% 100%;
}
div#clock div.minute-handle{ height: 80px; top: 20px; width: 4px}
div#clock div.seconds-handle{ height: 80px; top: 20px; left: 100px; width: 1px;}

The color for the handles is given by the inside span.handle. This will also suffer some transformations, in order to become pointed towards one end. In this case we will skew them along the Y axis by a huge amount. The number of degrees indicates the angle at which the skewing is make. This increases the height of the handle, but it's parent container has overflow:hidden and the only part that we can see is the one that we nee: a nice sharp clock handle.

div#clock div.hour-handle .handle, div#clock div.minute-handle .handle, div#clock div.seconds-handle .handle{
 display: block;
 background: #333;
 width: 180%;
 height: 100%;

 -moz-transform: skewY(-84deg);
 -webkit-transform: skewY(-84deg);
 -o-transform: skewY(-84deg);
}
div#clock div.minute-handle .handle{
 -moz-transform: skewY(-86deg); 
 -webkit-transform: skewY(-86deg); 
 -o-transform: skewY(-86deg);
}
div#clock div.seconds-handle .handle{
 -moz-transform: skewY(-88deg); 
 -webkit-transform: skewY(-88deg); 
 -o-transform: skewY(-88deg); 
 background: #f00;
}

That's about all the CSS required for our analog clock.

The JavaScript - jQuery, what else?

After loading the jQuery framework (1.4.2 in this case, but older versions might work) we can add the JavaScript required for the clock to function. It does this by repeating a function every second with the help of setInterval(). Read the comments below for more information. The position / angle of the handles is modified each time the function is run using the same -*-transform: rotate() method described in the CSS.

/* make sure everything is loaded */
$(document).ready(function(){
 /*
 *  this function is run every second to update the clock handles
 */
 function setClock(){
  /* get the handles of the clock */
  var hourHandle = $('div#clock div.hour-handle');
  var minuteHandle = $('div#clock div.minute-handle');
  var secondsHandle = $('div#clock div.seconds-handle');
  /* get the current date from te users computer */
  var now = new Date();

  /* 
  * determine the degrees we need to rotate each handle 
  * we need to create this variable as a string here, before applying it
  */
  var hourDeg = 'rotate(' + ((now.getHours() * 30) + Math.floor(now.getMinutes() / 2)) + 'deg)';
  var minDeg = 'rotate(' + (now.getMinutes() * 6) + 'deg)';
  var secDeg = 'rotate(' + (now.getSeconds() * 6) + 'deg)';

  /* change the CSS for each of the handles */
  hourHandle.css({
   '-moz-transform': hourDeg,
   '-webkit-transform': hourDeg,
   '-o-transform': hourDeg
  });
  minuteHandle.css({
   '-moz-transform': minDeg,
   '-webkit-transform': minDeg,
   '-o-transform': minDeg
  });
  secondsHandle.css({
   '-moz-transform': secDeg,
   '-webkit-transform': secDeg,
   '-o-transform': secDeg
  });
 }

 /* call the function every second */
 setInterval( setClock, 1000);
 });

This is all there is to it. A working example can be seen at the top of this page. I would like to repeat myself: this is not a good way to add an analog clock to your website. It's just a way of showing what can be done with CSS3. Here is the complete code used to make the clock.

The HTML

The CSS

The JavaScript

If you have any comments or questions, please let me know.

How to get Slimbox to work with Blogger

I planned to make this happen for some time now: getting Slimbox to work with Blogger's quirky platform. But the solutions I always come up with never seem to be any viable ones. But today I finally managed to make it work in a way that satisfies me. If you want to know how, read on.

Firstly, the problem is the incapability to host the files required for Slimbox on a server (unless you're running on your own server/hosting account and not the free *.blogspot.com). Slimbox provides a very nice way of presenting an image or even a collection of images. For those that do not know, Slimbox is a clone of the original Lightbox. I prefer Slimbox because it's more lightweight as file size and also file count. The original Lightbox was built using the Prototype framework, which I personally never liked, and Slimbox comes in two flavors: MooTools and jQuery. So if you use any of those, you are safe to go for Slimbox.

But the issue at hand is not the history or origins of Slimbox, but rather the way we need to go to implement it into Blogger. So let's get started.

  1. Include the jQuery framework in your Blogger layout's html. Because we can't just upload it, we'll use the one Google places at our disposal here. So just go like this in your <head> tag:
    <script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js'></script>
    I went here for version 1.3.2 but you can use whichever you'd like
  2. That's one down. Now we need to include the Slimbox files. Head on over and download them from digitalia.be. At the moment of this writing, the latest version is 2.03. Once downloaded unpack them somewhere on your hard drive where you can find them
  3. Uploading the files to our host is again an issue, as we don't have one. But Google yet again comes to our aid. Go to Google Sites and make a new website or use an existing site if you have one already. Having a Blogger account, I assume it shouldn't be too hard. On your Google Site click the "More Actions" button, go to Manage and click Attachments. Upload the slimbox2.js and image files you unpacked from the Slimbox archive. Don't upload slimbox2.css yet. You need to edit that first
  4. Open slimbox2.css with your favorite editor (please don't use Microsoft Word, I don't feel like explaining why it won't work if you have any problems) and edit the location of the image files. There are 4 of them, all of which you should have already uploaded to your Google site (closelabel.gif, loading.gif, nextlabel.gif and prevlabel.gif). Make sure you replace the url in the css file so they point to the location of your uploaded images. You can find out the location if you hover over the download link in your Google Sites Attachments section. You can skip the last part of the URL, after the file extension, the one with "?attredirects...". You don't need that. After you're done editing the slimbox2.css you can upload that one too
  5. Get back to editing your Blogger layout and add the JavaScript and CSS files from your Google site. It should look something like this:
    <link href='http://sites.google.com/site/your_site/slimbox2.css' rel='stylesheet' type='text/css'/>
    <script src='http://sites.google.com/site/your_site/slimbox2.js' type='text/javascript'></script>
    
    Make sure the HREF and SRC attributes point to your uploaded files.
  6. That' about it! Now all you have to do is place a rel="lightbox" (or rel="lightbox[some_name]" if you would like to group them) attribute on the links that point to an image and you want it/them to have Lightbox/Slimbox capabilities. More on how Slimbox works and available features can be found on the official website. For a working example you can check out this page. At the end you will find a gallery of just 5 images and you will be able to scroll through them left/right.

One issue I had was with the fact that the links to images uploaded through Blogger were not pointing to the image itself but rather to a Picasa page containing the image and the Lighbox was activated but no image was displayed. To fix this I had to right-click the image in that page (Picasa page) and click "View image" in Firefox. After that replace the SRC in the link tag with the one of the image. A little more work but it gets the things working.

That's all I went through to get Slimbox working on a Blogger blog. Hope anyone find this useful. If you have any questions/suggestions feel free to leave a comment.

How to really remove the Blogspot Navbar

The Blogspot Navbar is meant to provide some functionality to the Blogspot users, but let's face it: we don't want it there. It was probably placed at the top of all these blogs for people that don't want to read something in particular and are just browsing. And even if it can bring new users to your blog (very few indeed), it can also take users away. That, added with the fact that it just looks bad, forces many Blogspot blogs to remove it. And here are the ways you can do that.

The "hidden" way

Using this method you are not really removing the Navbar, but you are hiding it so people visiting your blog won't see it. What this involves is adding a CSS rule at the top of your CSS. Here's how to do it: on your blog's Dashboard, go to "Layout" and then to "Edit HTML". Scroll to the beginning of your CSS and on a new line, immediately after

 <b:skin><![CDATA[ 
write the following:
#navbar{display: none;}

The Navbar will still be loaded, but it will not be displayed. If you look at the source of your page you will notice that it is still there. I didn't like that so fortunately there is another way.

The better way

I believe this method to be a little better because the code for the Navbar is not loaded anymore. Using this little hack, the template engine will understand that you want to remove it, and will even ask for confirmation. Here's what you need to do: go to Layout and Edit HTML again. Scroll down to your closing

</head>
tag and just before that, on a new line paste the following:
<!-- </head><body> -->

When you click "Save Template" you will be asked to confirm if you want to remove the "Navbar1" widget. Click on the orange "Confirm & Save" button and that's it. If you look at the source of your page now, you will notice that the Navbar is really gone, not just hidden. Well actually something still remains, but it's just a comment line that is completely harmless. This is the line that actually tells the template engine to display the Navbar. The reason you don't see it when you edit your layout is because it gets added later and this way you "trick" it into getting loaded into an HTML comment. Because of that it won't be parsed, hence it won't be loaded.

And that was my quick "how to" for removing the Blogspot Navbar. I hope someone finds this useful.