Creating a Rotating Billboard System with jQuery and CSS

Currently we are in the “hey, let’s do that flash thing in jQuery”-mood and so we came up with another idea: a rotating billboard system. In this tutorial we will […]

From our sponsor: From online stores to member areas, Squarespace is everything you need to sell anything.

billboard

Currently we are in the “hey, let’s do that flash thing in jQuery”-mood and so we came up with another idea: a rotating billboard system.

In this tutorial we will use some images, CSS and jQuery to create the effect of a rotating billboard with two ads. The idea is to make one set of image slices disappear while another one (the other ad) appear. We will decrease the width of each disappearing slice and increase the width of each appearing slice. This will give the effect of rotating slices, just like in a rotating billboard system.

Ok, let’s start coding!

1. The HTML

We will have quite a lot of markup for the image slices – it will be 22 slices for each ad:

<div class="container">
	<div class="ad">
		<div id="ad_1" class="ad_1">
			<img class="slice_1" src="ads/ad1_slice01.jpg"/>
			<img class="slice_2" src="ads/ad1_slice02.jpg"/>
			<img class="slice_3" src="ads/ad1_slice03.jpg"/>
			<img class="slice_4" src="ads/ad1_slice04.jpg"/>
			<img class="slice_5" src="ads/ad1_slice05.jpg"/>
			<img class="slice_6" src="ads/ad1_slice06.jpg"/>
			<img class="slice_7" src="ads/ad1_slice07.jpg"/>
			<img class="slice_8" src="ads/ad1_slice08.jpg"/>
			<img class="slice_9" src="ads/ad1_slice09.jpg"/>
			<img class="slice_10" src="ads/ad1_slice10.jpg"/>
			<img class="slice_11" src="ads/ad1_slice11.jpg"/>
			<img class="slice_12" src="ads/ad1_slice12.jpg"/>
			<img class="slice_13" src="ads/ad1_slice13.jpg"/>
			<img class="slice_14" src="ads/ad1_slice14.jpg"/>
			<img class="slice_15" src="ads/ad1_slice15.jpg"/>
			<img class="slice_16" src="ads/ad1_slice16.jpg"/>
			<img class="slice_17" src="ads/ad1_slice17.jpg"/>
			<img class="slice_18" src="ads/ad1_slice18.jpg"/>
			<img class="slice_19" src="ads/ad1_slice19.jpg"/>
			<img class="slice_20" src="ads/ad1_slice20.jpg"/>
			<img class="slice_21" src="ads/ad1_slice21.jpg"/>
			<img class="slice_22" src="ads/ad1_slice22.jpg"/>
		</div>
		<div id="ad_2" class="ad_2">
			<img class="slice_1" src="ads/ad2_slice01.jpg"/>
			<img class="slice_2" src="ads/ad2_slice02.jpg"/>
			<img class="slice_3" src="ads/ad2_slice03.jpg"/>
			<img class="slice_4" src="ads/ad2_slice04.jpg"/>
			<img class="slice_5" src="ads/ad2_slice05.jpg"/>
			<img class="slice_6" src="ads/ad2_slice06.jpg"/>
			<img class="slice_7" src="ads/ad2_slice07.jpg"/>
			<img class="slice_8" src="ads/ad2_slice08.jpg"/>
			<img class="slice_9" src="ads/ad2_slice09.jpg"/>
			<img class="slice_10" src="ads/ad2_slice10.jpg"/>
			<img class="slice_11" src="ads/ad2_slice11.jpg"/>
			<img class="slice_12" src="ads/ad2_slice12.jpg"/>
			<img class="slice_13" src="ads/ad2_slice13.jpg"/>
			<img class="slice_14" src="ads/ad2_slice14.jpg"/>
			<img class="slice_15" src="ads/ad2_slice15.jpg"/>
			<img class="slice_16" src="ads/ad2_slice16.jpg"/>
			<img class="slice_17" src="ads/ad2_slice17.jpg"/>
			<img class="slice_18" src="ads/ad2_slice18.jpg"/>
			<img class="slice_19" src="ads/ad2_slice19.jpg"/>
			<img class="slice_20" src="ads/ad2_slice20.jpg"/>
			<img class="slice_21" src="ads/ad2_slice21.jpg"/>
			<img class="slice_22" src="ads/ad2_slice22.jpg"/>
		</div>
	</div>
</div>

<div class="billboard"></div>

For these images, 22 slices (each slice 35 pixels wide) of a 770 pixel wide and 340 pixel high image were made. One might think that this is a lot of work and that we could actually take one whole picture and create divs acting like the slices with that background image and the right background position. But then we would not be able to create the same effect of a rotating slice (at least not with the JavaScript we created for this showcase).

The billboard will be an absolute positioned div with the billboard image. Since the image has some transparent spotlights, we want to lay it over the ad container.

2. The CSS

The style for the billboard frame will be the following:

.billboard{
    position:absolute;
    bottom:0px;
    left:50%;
    margin-left:-447px;
    width:916px;
    height:599px;
    background:transparent url(../images/billboard.png) no-repeat 0px 0px;
}

To position the element in the center of the page, we set the left value to 50% and the left margin negatively to half of the width of the element.

The container for the ads will have the same style like the billboard, except the background-image. We do that, because we need to position the containing elements at the same place like the billboard. We don’t want to place the ads inside of the billboard because we need the billboard to be on top of them. So, we do this trick and create another element with the same positioning:

.container{
    position:absolute;
    bottom:0px;
    left:50%;
    margin-left:-447px;
    width:916px;
    height:599px;
}
.ad{
    width:800px;
    height:336px;
    position:relative;
    margin:35px 0px 0px 60px;
    background-color:#333;
}
.ad_1 img{
    width:35px;
    height:336px;
    position:absolute;    
}
.ad_2 img{
    width:0px;
    height:336px;
    margin-left:18px;
    position:absolute;
}

The slices of the ad images will be 35 pixels wide. The slices of the second ad will have the same width, but initially we need to set it to 0. We also need to set the left margin of the second slices to 18 pixels since we want to create the rotating effect. I will explain more about this value after we define the CSS for the slices.

The single slices need to be positioned:

.slice_1{left:0px;}
.slice_2{left:36px;}
.slice_3{left:72px;}
.slice_4{left:108px;}
.slice_5{left:144px;}
.slice_6{left:180px;}
.slice_7{left:216px;}
.slice_8{left:252px;}
.slice_9{left:288px;}
.slice_10{left:324px;}
.slice_11{left:360px;}
.slice_12{left:396px;}
.slice_13{left:432px;}
.slice_14{left:468px;}
.slice_15{left:504px;}
.slice_16{left:540px;}
.slice_17{left:576px;}
.slice_18{left:612px;}
.slice_19{left:648px;}
.slice_20{left:684px;}
.slice_21{left:720px;}
.slice_22{left:756px;}

By positioning the elements one more pixel to the left than they are actually wide, we create a little gap between the them. Now, the left margin has a value of 18 pixels because it is half of a slice plus its gap. We set this because we want the slices to appear (or disappear) from (or to) their center and not just from the side. If we simply set the width of a slice to 0 pixels the image will not seem to be rotating.

And that is all the CSS. For the additional fancy background images you can check out the downloadable version below.

Let’s create the rotating effect with jQuery.

3. The JavaScript

We will now create a function for rotating the slices. The function will make the first ad slices disappear by making their width 0 pixels. To achieve the rotating effect, we add a left margin of 18 pixels.

While the first ad slices disappear we make the others appear by removing the left margin of 18 pixels (that we initially set in the CSS) and giving them a width of 35 pixels. We call the rotate function like this:

 $('#ad_1 > img').each(function(i,e){
        rotate($(this),500,3000,i);
    });

The whole script that we call will look like this:

$(function() {            
    $('#ad_1 > img').each(function(i,e){
        rotate($(this),500,3000,i);
    });
    function rotate(elem1,speed,timeout,i){
        elem1.animate({'marginLeft':'18px','width':'0px'},speed,function(){
            var other;
            if(elem1.parent().attr('id') == 'ad_1')
                other = $('#ad_2').children('img').eq(i);
            else
                other = $('#ad_1').children('img').eq(i);
                other.animate({'marginLeft':'0px','width':'35px'},
                                  speed,function(){
                var f = function() { rotate(other,speed,timeout,i) };
                setTimeout(f,timeout);
            });
        });
    }
});

So, the rotate function performs the hiding of the current element (that it was called upon) and then identifies which element it’s currently dealing with, so that another call of the rotate function can be performed on the other ad slices.
The two times mentioned in the rotate function stand for the speed of the rotation effect (speed) and the duration between the swapping of the ads (timeout) in milliseconds.

And that’s it!
I hope you like and enjoy it!

Message from TestkingWhether you want to get ccnp certification or interested in ccna certification, using ccna wireless prep resources you will pass real exam on first attempt.

Tagged with:

Stay up to date with the latest web design and development news and relevant updates from Codrops.

Feedback 70

Comments are closed.
  1. Very cool… in IE8 & FF 3.5

    However, it doesn’t work in Google Chrome v4.0.266

    Nice effect. Keep up the great work 😉

  2. Sweet idea. This could really be optimized by using the CSS “background” property instead of downloading all the little slices. And it’d be sweet as a plugin… but I’m not volunteering to write it or anything. 🙂

  3. Pingback: uberVU - social comments

  4. Seems to me that you could utilize the background property like @SammyK was saying by calling the same image as the background for each container and using jQuery to determine the background position of the image for each “slice”. Just offset the background-position of the image by the width of each container. You would still have the same amount of HTML but you wouldn’t need to do any actual slicing

  5. @elijah
    Thanks! We only tried it in Chrome Version 4.0.202.0 and it worked fine…we will have to see what the problem is in the new build.
    @Sammy @Trevor
    I actually did that initially but the problem was the rotating effect. You see, when you decrease the width of an image (but keep its height) it gets “squeezed” while a div with a background image will not. I just don’t see how to simulate the rotation effect (i.e. the squeezing) in the “sprites” way.
    The slicing is very laborsome, but there are programs that do that automatically.
    Maybe we can find a solution for a plugin that is less “heavy”.
    Thanks for the feedback!

    • @Eone
      Excellent work! The rotating billboard effect could be simulated with the curtain example! Just the gaps would be missing and the image slices are not really squeezed. But it creates the same effect and it’s much easier to use.
      Puno pozdrava i hvala za komentar 🙂

  6. Another great piece of work! I love the background idea too, the way it adjust for different screen resolutions!

    • @Claude,
      thank you very much! I tried to make it adaptable, I hope it looks good on big screens, I could only tests it on a tiny laptop screen 🙂

  7. instead of having a ton of tiny images why not just use css sprites? Then you would not have to slice up into the little images. Then instead of making all the divs by hand have the js generate them for you and an inline style instead of a class. since the classname is not much longer then the css.

  8. Pingback: Creating a Rotating Billboard System with jQuery and CSS | Codrops « Netcrema – creme de la social news via digg + delicious + stumpleupon + reddit

  9. Well… there’s actually a much better way to do this and you’d never put something into production where you have to make that many HTTP requests. All you need for this is to simulate the slices not actually slice the image. For the “empty parts” during a transition lay divs as position absolutes ON TOP of the full sized graphics which are stacked on top of each other with a z-index. Expand them from 1px wide to 35px. (To get them to seem like they expand from the center you can transition’s left position during the animation of width as well). Then once expanded to max… swap the z-index order of the images…or change their order in code… and then contract your “empty parts” back to 1px again.
    Done!. Less loading. Same effect. Too easy.

  10. First of all, it’s a nice effect! Good work once again. Kevdesign, what u mean with HTTP requests? Where are u seeing them? 🙂

    • @Kevdesign
      thanks for the feedback. That’s looks like a good solution, but again, as I said before, you cannot achieve the “squeezing” image effect like that. To do what you are proposing, there is an even easier solution: the jQuery plugin mentioned by Eone.
      @Jonas
      Thanks! Kevdesign probably means that too many request are done because of the amount of images (slices) used.
      Greets

  11. Pingback: Creating a Rotating Billboard System with jQuery and CSS | Codrops | Squico

  12. Pingback: blog.no-panic.at » links for 2009-12-17

  13. Pingback: Creating a Rotating Billboard System with jQuery and CSS | Codrops | Kerja Keras Adalah Energi Kita

  14. Pingback: Creating a Rotating Billboard System with jQuery and CSS Direct Me

  15. preposterous!!

    before I CUT a jpeg into that many SLICES , I call Lorena Bobbit and …. 🙂

    looks nice, two much work….

    hmmm….. on the other hand…maybe I could write a php program to cut up and create the sliced jpegs??

    maybe call it… LorenaBobbit.php???

    Yes! – See you next Tuesday with the code!

  16. Very Cool. Could probably save yourself the headache of cutting everything in photoshop if you either used the image like you would a regular CSS Sprite. I like it nice work.

  17. Pingback: Really Useful Tutorials You Should Have Read in December 2009 | EMDMA

  18. Pingback: Démonstrations : Créer un système de rotation panneau d’affichage « FrameLinks

  19. Hey guys! Can we add more image like ad_3, ad_4 ?

    I can’t handle with script part. If anybody can help me i’ll be grateful.

    Thnx anyway..

  20. Really cool. I wrote a little Php Script that allows uploading the image, automatically slices the image and pastes it into the gallery..

  21. if you use Adblock extension on your Firefox, on the demo page, you cant see the images. because the images and css classes are named as “ad” or “ads”, etc. and also the images are in “ads” folder. so Adblock extension assume that the images are advertisements and blocks them.

  22. http://www.handbagsonsales.com

    Chanel Handbags

    Gucci Handbags Gucci 2010 New Handbag

    Hermes Handbags

    Balenciaga Handbags

    Bottega Veneta Handbags

    Chloe Handbags

    Coach Handbags

    Dior Handbags

    Fendi Handbags

    Dolce & Gabbana Handbags

    Hermes Handbags

    Versace Handbags

    Prada Handbags

  23. Nice work.the background is also very nice. so tried the background to my site. the background images are moving with the resolution.
    please visit here,
    http://www.sanduwa.comule.com/test/
    & see the problem by changing the resolution.
    so would you mine telling me how to keep the background image at constant position(according to the page)
    hope you will help me.
    thank you

  24. Hi,

    I have a little problem. When i saw your slideshow, i didnt read your tuto and i remake it.

    I need an other version, a jquery plugin version, AND i need it to work with divs and the right background position.
    Caus’ this will be use by someone who just want to upload an image and then it work.
    I could have write a php script that split the image, but i decided to put a “split” number in my jquery plugin options. I could make a script that generate my image splitted and put it in a cache… but i dont like the idea.

    Anyway, So it has to be done with divs for me.
    BUT i had a problem, and i would like you to tell me if you have the same. The jquery animate function doesnt work in IE if you put a background-position in the animate option. I don’t know why… I tried everything, IE doesnt like it.
    Have you got the same problem?

    And for the rotating effect, you are right, we can’t do it this way.
    I thinking about transform all script and do like this :
    Div -> width 35px, absolute position, overflow hidden, no background
    inside this DIV -> an img, absolute position, positionned to have the right part of the image visible.

    And then in the animation, animate div margin left and width, and animate the img width inside AND animate the position to always have the image centered in the div.

    BUT that’s a lot of animations… Have you got an other solution ?

    See you.

  25. Hey.. Great work, what lines of code do i change to add another two adds ?? your help is appreciated..