views:

431

answers:

5

I'm trying to get the background image of a legacy div (by which I mean it already has a background image, which I cannot control & thus have to initially over-write) to smoothly fade between new images indefinitely. Here's what I have so far:

var images = [
 "/images/home/19041085158.jpg",
 "/images/home/19041085513.jpg",
 "/images/home/19041085612.jpg"
 ];

var counter = 0;
setInterval(function() {
$(".home_banner").css('backgroundImage', 'url("'+images[counter]+'")');
 counter++;
 if (counter == images.length) {
     counter = 0;
 }
}, 2000);

Trouble is, it's not smooth (I'm aiming for something like the innerfade plugin).

EDIT: question originally said "and it's not indefinite (it only runs once through the array).", but Mario corrected my stupid naming error.

EDIT2: I'm now using Reigel's answer (see below), which works perfectly, but I still can't find any way to fade between the images smoothly.

All help greatfully appreciated :)

+1  A: 

You need to first load the image then switch to it

jQuery fade to new image: http://stackoverflow.com/questions/1977557/jquery-fade-to-new-image

Glennular
+2  A: 

Pre-load the images before you set the backgroundImage and also replace

if (counter == colours.length) {

with

if (counter == images.length) {

EDIT: Fading between images (note I'm not talking background images) is done by using two images and changing the opacity until one is invisible and the other isn't. This means you need to have two images visible at the same time for a short while. This is not possible if you just use one background image.

You could try removing the background image on the existing div

$(".home_banner").css({'backgroundImage':''});

and placing img elements behind it (using a lower z-index) and fade these in and out. You could probably even use the innerfade plugin on these and let that handle the fading and looping for you.

Mario Menger
Thanks for catching that Mario, I'm going to edit the question to reflect it. Now I just need to take care of the smoothness.
da5id
It should be smoother if you preload the images, you could preload only the first one before the call to setInterval and then preload the "next image" after you've set the backgroundImage (essentially after you've updated the counter)
Mario Menger
Added an idea for fading "background" images
Mario Menger
Thanks again Mario, I am aware of that technique, but was hoping someone would have a tricksy way to apply something like fadeout followed by fadein to the background image. Seems not though :(
da5id
+1  A: 

try this...

var images = [
    "/images/home/19041085158.jpg",
    "/images/home/19041085513.jpg",
    "/images/home/19041085612.jpg"
    ];

var counter = 0;
setInterval(function() {
$(".home_banner").css('backgroundImage', 'url("'+images[counter]+'")');
    $('<img>').attr('src',images[++counter]); // preload the next image
    if (counter == images.length) {
        counter = 0;
    }
}, 2000);
Reigel
Thanks Reigel, that's now working perfectly, except I want to fade between the images. I've edited my question to be more clear, apologies for any confusion.
da5id
+1  A: 
var bgrotate = function(imgpool, tg){
    var imgs        = imgpool,
        loader      = new Image(),
        domelements = new Array(),
        current     = 0,
        target      = tg;

    return {
        preload: function(){
           for(var i=0; i<imgs.length; i++){
               loader = new Image();

               loader.src = 'url("' + imgs[i] + '")';
               alert(loader);
               domelements.push(loader);                   
           }
        },
        rotate: function(speed){
           tg.delay(speed).show(1, function(){
              tg.css('backgroundImage', domelements[current].src);
              current = (current < domelement.lenght ? current++ : 0);
           }
        },
        stop: function(){
              tg.stop(true, false);
        }
    }
}



      $(document).ready(function(){
           var myobj = new bgrotate(['http://static.jquery.com/files/rocker/images/logo_jquery_215x53.gif', 'http://sstatic.net/so/img/logo.png'], $('#mydiv'));

           myobj.preload();
           myobj.rotate();
      }

myobj.stop() ends the loop. It's untested but something simliar to this should work.

Kind Regards

--Andy

jAndy
Thanks Andy, that looks like a very nice way to rotate my images, but it's still not fading between them (at least I don't think it is?).
da5id
A: 

After much experimentation, I'm forced to answer my own question in the negative - i.e. at this point I'm 99% sure it can't be done.

I should say that my situation is not ideal in that the div that I'm trying to fade the background for has other html content inside it. If it didn't, then a combination of Reigel's code & Mario's last suggestion would certainly work, namely:

  • After Reigel's code,
  • Remove the background of the legacy div.
  • Insert a new div with a lower z index.
  • Add images in the foreground of this new div.
  • Transition away using the library of your choice.

Though it would be simpler still to just use jQuery to remove the legacy div background & then insert images into the div 'foreground'.

Anyway, just leaving this in case someone else is trying to do the same thing. Plus I hate unanswered questions :)

da5id