georgi

Making fancy websites without Flash 2: Animating background image

This is a continuation of the Making fancy website without Flash entry from a few days ago. To make the story short – I will try and show you some jQuery alernatives for popular Flash animation. We will start with a

Smooth background image swap – jQuery Background-Image Transition Plugin

I will show you an example right now, so you know what I am talking about.

Here is a working example

What we basically do is:

  1. Create an additional hidden <div> element on top ( using z-index ) of the element we want to animate
  2. Load the new image in the in the cache in the background, so that the effect is smooth
  3. Set the new src to the new <div> element
  4. fadeIn() the new <div> element so that it creates the illusion that the background image of our initial div is smoothly changing
  5. Optional step – if we need to change the image once again, go from 2 to 5 but setting the new src to our initial <div> and then using fadeOut() on the new element, so that it disappears and the new image is set as background to the old <div>. This way we won’t have an infinitive increase of the z-index and won’t actually change the z-index of the initial <div>

OK, let’s get to work, we will start with the HTML markup:

<div id=”backImage”></div>

Well, that was pretty easy: we have a simple <div> element with some demo text and just next to it we add that additional <div> which we will need for the animation.

So, here is the CSS:

#backImage {
    z-index: -2;
    height:600px;
    width:800px;
    background-image: url('path/to/initial/img');
}

We just set a height and width of the element so that we are sure the image will actually be shown. It is generally a good idea to have the z-index set to a negative number while other elements have a greater z-index value.

We will use jQuery’s Background-Image Transition Plugin for our example.

First, add jQuery and the plugin

<script lang=”Javascript” src=”path/to/jQuery.js” type=”text/javascript”> </script>
<script lang=”Javascript” src=”path/to/jQuery.bgImageTransition.js” type=”text/javascript”> </script>

Then, at the end of the document, add the following lines:

jQuery( function(){
    jQuery('#backImage').bgImageTransition( 'path/to/new/image', {
        duration: 'slow',
        easing: 'linear',
        helperElementId: 'backImage2',
        zindex: -1
        callback: function(){
           //do sth
        }
    });
});

The only mandatory argument is the path to the new image. The optional second argument is an object holding some tweaks. You can set the desired duration, easing, helperElementId ( which is generated by the plugin ), z-index of the helperElement ( by default it will take the selected element’s zindex and increment by 1 ) and a callback function in case you want to execute some functionality when the transition is over.

Tags: , , ,

34 Responses to “Making fancy websites without Flash 2: Animating background image”

  1. Nik Says:

    I was looking for something like this to realize a menu with fading background effect like with the “BackgroundColor”.

    I was trying something like this:

    [code]
    $(document).ready(function(){
    $(“.buttonOne”).hover(function(){
    $(this).BgImageTransition( ‘img/overstate.jpg’ );
    },function(){
    $(this).BgImageTransition( ‘img/standardstate.jpg’ );
    });
    });

    [/code]

    but it didn’t work out very well. The images seems to “pulsate”. I am not that good in jQuery so any help would be appreciated.

  2. Nik Says:

    …. or maybe just fade in a background-image on hover and fade it out again on mouseleave

  3. georgi georgi Says:

    @Nik: what kind of element is .buttonOne? Can you show me an example of that code?

  4. Nik Says:

    Hi Georgi,

    what I want to do is fading the background of a menu element/Button, like a hover, but with a smooth fading effect

    This is my testing sample code:

    buttonOne

    and the css:

    #buttonOne {
    background-image: url(“img/standardstate.jpg”);
    display: block;
    width: 129px;
    height: 41px ;
    }

    ul {
    list-style-type: none
    }

  5. georgi georgi Says:

    @Nik: first, in the css you refer to the element’s ID but in the js you do it for a class. And I don’t think the plugin will work for a button.. I have never tried it personally. You may want to download the latest version as it has some enhancements.
    Let me know, if it works.

  6. Nik Says:

    yes, of course…. class and Id should be same, I have it like that. But there is still the same problem.
    What is the latest version ?

  7. georgi georgi Says:

    you can get it from http://plugins.jquery.com

  8. Steeve Poirier Says:

    This scripts does not work in IE8
    http://www.ovalpixels.com/bgImageTransition/

    Detail

    Agent utilisateur : Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) ; .NET CLR 2.0.50727; .NET CLR 1.1.4322; InfoPath.1; .NET CLR 3.0.04506.30; .NET CLR 3.0.04506.648)
    Horodateur : Wed, 6 May 2009 19:38:02 UTC

    Message : Argument non valide.
    Ligne : 12
    Caractère : 12949
    Code : 0
    URI : http://www.ovalpixels.com/bgImageTransition/js/jquery.min.js

  9. noel Says:

    is there any example of using multiple background images? thanks.

  10. georgi georgi Says:

    Actually, you can use http://www.gruppo4.com/~tobia/cross-slide.shtml

  11. Rudi Says:

    Dear Georgi

    This script work well on my site, but when i add “slide panel” effect “on click event” above the background slideshow, my slide panel is not working well, can u help me with this ??

  12. georgi georgi Says:

    Rudi,

    How do you attach the event on that panel? What slide panel effect exactly do you use?

  13. Rudi Says:

    i use the same jquery script from this site http://www.learningjquery.com/2006/09/slicker-show-and-hide

    i wanna show panel on click event (Show the box)
    and hide it also on click (Hide the box)

    any idea ??

  14. georgi georgi Says:

    can you paste your html, css and js code here?

  15. Rudi Says:

    im sorry, i cant paste the code here
    here’s the address
    http://balisidenotes.com/demo/home02.html ( html )
    http://balisidenotes.com/demo/slicker.js ( Jquery )

    thx for your help

  16. georgi georgi Says:

    use pastebin

  17. Rudi Says:

    mmm you can see the code here
    http://balisidenotes.com/demo/home02.html
    http://balisidenotes.com/demo/slicker.js

    thx for reply man 🙂

  18. Rudi Says:

    here’s the address

    http://pastebin.ca/1509785

    thx for da help

  19. georgi georgi Says:

    I guess that is due to zIndex – try setting the zIndex of the panel to a high level.

  20. Rudi Says:

    yea i’ve try that i set
    #slickbox { z-index : 100; }

    its working fine on the first background image of the slideshow, but when image changing to the second one, the “show / hide” link is not working

  21. georgi georgi Says:

    set the zindex of the underlying wrapper to 1

  22. Rudi Says:

    mmm still not workin man,

    you can see the action on http://www.balisidenotes.com/demo/home02.html
    i’ve upload all include the css, u can check it all there
    thx again for your time

  23. Tom Says:

    Hi Georgi,

    This is a great script, and helping with a major section of a site I am working on.

    However, the images need to play in a definate order (there are 5 photos) and currently they play in a random order.

    Also, between each photo it returns to the first photo (the one declared in the CSS). EG – Photo1, Photo 3, Photo 1, Photo 5, Photo 1, Photo 3 etc..

    I just need them to go Photo1, Photo2, Photo3, Photo4, Photo5 – REPEAT

    I would be extremely grateful if you have a solution to this.

    Regards,

    Tom

  24. georgi georgi Says:

    @Tom: The plugin itself does not rotate any images. The script I am using in the demo uses Math.random() – you can change that.

  25. Tom Says:

    Thanks Georgi.

    I don’t suppose you know the JS that should be used instead of Math.random()

    I’m afraid my JS knowledge is very limited..

    Thanks,

    Tom

  26. georgi georgi Says:

    @Tom: I cannot write your js since you know your project much better and your job to do it. Create an array with the images and loop through it instead of using random()

  27. Karthick Says:

    Hi Georgi,

    Great script! but i have to apply it on body tag instead of div..Could u plz guide?

    Thanks,

    karthick

  28. georgi georgi Says:

    You should I am no sure whether you can. Just create a new div element the first child of the body and make it “snap” the body borders. Then make it switch images.

  29. Bill Says:

    This is very helpful. However, in your demo, Rosso Castilla.JPG never loads?

  30. Jason Says:

    I’m also trying to run through a list of images, which was easy enough to do, however it alternates to the initial image every other time.

    So instead of: Image1.jpg, Image2.jpg, Image3.jpg, Image4.jpg, Image5.jpg…..
    I’m getting: Image1.jpg, Image2.jpg, Image1.jpg, Image4.jpg, Image1.jpg, Image6.jpg…..

  31. janimal Says:

    I used a modulo function to send the images sequentially and to wrap around the index, but the issue is the same as Jason has.

    The problem appears to be related to your point number 5 in the post.

    The script never replaces the image used for the initial div. I will try to fix it myself, but I am brand new to Javascript.

    For those struggling with a sequential function try the following.
    1) use the array index instead of a string to set the next image
    eg: $(‘#banner’).BgImageTransition(‘/images/featured/’+bgImages[currIndex]);

    2) Set currIndex to 0 before calling setInterval

    3) increment currIndex within setInterval like this
    currIndex = ++currIndex % bgImages.length;

    This will give you sequential indexes which wraps around to the 1st element when it reaches the upper bound of the array

  32. Michael Says:

    Great help—thanks! Like a few people have mentioned, the optional “step 5” in the case of several photos was never explained, was it? The way the plugin natively works is alternating back to the initial image every time…

    There’s got to be a way to change the initial div as well, so that when the HelperElement fades out, the next image is in place (or even if, once the HelperElement faded in, to set the same image as the initial background-image, so that when the HelperElement fades out, it doesn’t revert to the initial image, and you could just speed up the transition or something)…

    Any help would be greatly appreciated… Thanks!

  33. Michael Says:

    Actually, in the jquery.BgImageTransition.js file, I added this:

    if (helperElement.css(‘display’) == ‘block’) {
    $(this).css(‘background-image’,’url(‘+src+’)’);
    }

    just before the var tempImage = new Image(); statement.

    Since the helperElement is the div that the plugin creates and toggles in and out in front of your original element (via z-index), I checked if the helperElement has “display:block” and then if so, changed the background-image to the original div (in my case). Seems to work! Now to test it in IE… =(

  34. Rytis Lukoševičius Says:

    Hello Georgi,

    The first comment of Nik was that it “pulsates” and I’ve stumbled on the same issue after fidling around with dom inspector and console.log I’ve realised that this happens because when the fading starts another element – helperelement is layered on top of original element. So the original element shoots “mouseleft the house” so it starts the fading back effect and it looks like “pulsate”.

    So this transition cannot be used with hover on the same element.

    The solution for hover was to add the .hover for the parent element then find the child element and fade it’s background to hover state and fade it back when mouse leaves.

    Example:

    $(‘#menu li’).hover( function() {
    $(this).find(‘a’).BgImageTransition(‘image-hover.png’);
    }, function() {
    $(this).find(‘a’).BgImageTransition(‘image.png’);
    }

Leave a Reply