tags:

views:

77

answers:

4

I have the following javascript. It works well when I am cycling between 2 images, but when I add a third it does not work correctly.

Here is my CSS:

img {
    -webkit-transition-property: opacity;
    -webkit-transition-duration: 2s;
    position: absolute;
    width: 320px;
    height: auto;
}

img.fade-out {
    opacity: 0;
}

img.fade-in {
    opacity: 1;
}

Here is my javascript, which seems to work but seems laggy and definately not an elegant solution.

</head><body style="color: black">
<img id="one" class="fade-out" src="Wallpaper.png"/>
<img id="two" class="fade-out" src="Wallpaper0.png"/>
<img id="three" class="fade-out" src="Wallpaper1.png"/>

    <script>
        var images = ['Wallpaper.png', 'Wallpaper0.png', 'Wallpaper1.png'];
        var index = 0;

        var fade_in = one;
        var fade_out = two;
        var fade_foo = three;

        fade_in.src = images[0];
        fade_out.src = images[images.length - 1];

        var fade = function () {
            fade_in.src = images[index];
            index = (index + 1) % images.length;

            fade_in.className = 'fade-out';
            fade_out.className = 'fade-in';
            fade_foo.className = 'fade-out';

            var fade_tmp = fade_in;
            fade_in = fade_out;
            fade_out = fade_foo;
            fade_foo = fade_tmp;

            setTimeout(fade, 15000);
        };

        fade();
</body></html>
+1  A: 

For one thing, you're not changing fade_out.src. Try something like this:

fade_in.src = images[0];
fade_out.src = images[1]; // let's use image next to current for fade-out

var fade = function () {
    fade_in.src = images[index];
    index = (index + 1) % images.length;
    fade_out.src = images[index]; // put next to current image into fade-out

    // Code below does something misterious. 
    // You first switch classes between two img's, then switch variables themselves
    // Why?
    //fade_in.className = 'fade-out';
    //fade_out.className = 'fade-in';

    //var fade_tmp = fade_in;
    //fade_in = fade_out;
    //fade_out = fade_tmp;

    setTimeout(fade, 15000);
};

Can't tell more since I don't know what exactly you're doing.

Nikita Rybak
I edited my original post to show almost the entire thing (minus the css). All I would like to do is cycle through the 3 images with a fade.
you only need to change the source for one element per iteration- in this case it's always (what will be) the invisible element.
lincolnk
A: 

you're not waiting for you transitions to finish before you swap the source. we just need to rearrange the order of things.

    var fade = function() {

        fade_in.className = 'fade-out';
        fade_out.className = 'fade-in';

        setTimeout(function() {

            index = (index + 1) % images.length;
            fade_in.src = images[index]; // should be completely invisible at this time

            var fade_tmp = fade_in;
            fade_in = fade_out;
            fade_out = fade_tmp;

        }, 2000); // 2 seconds, same as your transition time

        setTimeout(fade, 15000);
    };

    setTimeout(fade, 15000);

here the only work that the fade method does is to change the classes, which initiates the transitions. we set a delay that matches your transition time to update the index and swap the image source.

edits: i guess i'm not making it clear what's going on and the assumptions i'm making. here's my complete html except for the provided css which is the same. i also fixed an issue with image order since the last example.

<body>
    <img id="one" class="fade-out" /><img id="two" class="fade-out" />
    <script>
        var images = ['16jog8h.jpg', '20_11_2007_0044537001195507712_joe_baran.jpg', '400davesrig.jpg'];
        var index = 0;
        var fade_in = document.getElementById('one');
        var fade_out = document.getElementById('two');
        // fade_in.src = images[0];
        fade_out.src = images[0];

        var fade = function() {
            fade_in.className = 'fade-out';
            fade_out.className = 'fade-in';
            setTimeout(function() {
                index = (index + 1) % images.length;
                fade_in.src = images[index];
                var fade_tmp = fade_in;
                fade_in = fade_out;
                fade_out = fade_tmp;
            }, 2000);
            setTimeout(fade, 5000);
        };
        fade();
    </script>
</body>
lincolnk
The OP said he is cross-fading the images, so you don't need to wait for the transition to complete.
casablanca
@casablanca he has to wait for the outgoing image to be invisible before he swaps the source, otherwise it's going to load a new image and fade it out immediately, which doesn't make sense.
lincolnk
I assumed he already had the images preloaded. Otherwise you couldn't possibly cross-fade.
casablanca
It is my understanding that var images = ['Wallpaper.png', 'Wallpaper0.png', 'Wallpaper1.png']; accomplishes the preloading, but I may very well be incorrect.
@nerbles just creating an array with filenames won't preload anything, but setting the source of the invisible element should take care of that. that wasn't your original problem anyway.
lincolnk
@lincolnk - Thank you.I added: <img id="one" class="fade-out" src="Wallpaper.png"/> <img id="two" class="fade-out" src="Wallpaper0.png"/> <img id="three" class="fade-out" src="Wallpaper1.png"/>but still the only solution that seems to work at all is the second one I posted in my original question, the rest of these just flash one image and thats it. Working through them with firebug now.
A: 

It seems you're only displaying one image at a time, so you don't need two variables, one will do. You just need to fade out the current image and bring in a new image:

var index = -1, count = /* total number of images */;
var image = null;

function fade() {
  if (image != null)
    image.className = 'fade-out';

  index = (index + 1) % count;
  image = document.getElementById('image-' + index);
  image.className = 'fade-in';

  setTimeout(fade, 15000);
}

fade();

This assumes that you have set up all the images in HTML as follows:

<img id="image-0" class="fade-out" src="..." />
<img id="image-1" class="fade-out" src="..." />
<img id="image-2" class="fade-out" src="..." />
...

Note that you can achieve cross-fading only if you have several images preloaded, as in the above example. If you use only one image and change the source, the previous image will be lost when you try to fade in the new one.

casablanca
The images in my array are the actual filenames. Wallpaper.png, Wallpaper0.png and Wallpaper1.png
@nerbles: I've updated my answer, which should work if you don't mind putting all the images into your HTML code.
casablanca
@casablanca: I've updated the second version of my code in the original post to incorporate the images in the html. Thank you.
@nerbles: Did you try the JavaScript I posted as well?
casablanca
This solution worked. Though I had to add the setTimeout(fade, 15000); to it.
A: 

The question has been answered. Thank you all for your assistance!