12

I want a simple image crossfade, similar to http://malsup.com/jquery/cycle/, but with a pre-loader. Is there a good jQuery plugin that does both? Also, I'm not looking for a load bar.

This question is close, but not the same => jQuery Crossfade Plugin

It would be great if it was a solution that defaulted to CSS3, but would otherwise fall back to JS to keep the processing native as possible.

Looking for something that..

  • will autoplay
  • without controls
  • will go to the next image based on time setting, ie. 5 seconds, unless the next image isn't loaded in which case it finishes loading the image and then displays it.
  • crossfade transition, not fade to black or white, but cross-fade. from the start it would fadein.
  • no thumbnails or galleries, etc. just the image
  • If images could be CSS background images, that would be best, so users can't drag out the image simply
  • Each panel needs to be clickable so a user could click the image and go to a part of the website.
Community
  • 1
  • 1
Kirk Strobeck
  • 17,984
  • 20
  • 75
  • 114
  • for preloading and to hijack image loading to indicate progress you will need to construct the img tags on the front end... Are you ok with this? ie passing a json object of images? – samccone Oct 07 '11 at 17:59
  • here is an example of what I am talking about http://jsfiddle.net/samccone/QTEk6/ – samccone Oct 07 '11 at 18:08

4 Answers4

6

Well, here's my poke at it. The preloader is in vanilla js and the slideshow loop is in jQuery. It's very simple to implement and the concept is even simpler.

Demo

a very simple Demo that illustrates the DOM manipulation approach


HTML

<!-- not much here... just a container -->
<div id="content"></div>

CSS

/* just the important stuff here.  The demo has example styling. */
#content
{
    position:relative;
}
#content img
{
    position:absolute;
}

javascript/jQuery

// simple array
var images = [
    "http://imaging.nikon.com/lineup/dslr/d90/img/sample/pic_003t.jpg",
    "http://imaging.nikon.com/lineup/dslr/d90/img/sample/pic_005t.jpg",
    "http://imaging.nikon.com/lineup/dslr/d90/img/sample/pic_001t.jpg"
];

// some adjustable variables
var delay = 2000;
var transition = 1000;

// the preloader
for(var i in images)
{
    var img = document.createElement("img");
    img.src = images[i];
    img.onload = function(){
        var parent = document.getElementById("content");
        parent.insertBefore(this,parent.childNodes[0]);
        if(i == images.length - 1)
        {
            i = 0;
            startSlides();
        }
    }
}

// and the actual loop
function startSlides()
{
    $("#content img:last").delay(delay).fadeTo(transition,0,function(){
        $(this).insertBefore($(this).siblings(":first")).fadeTo(0,1);
        startSlides();
    });
}

The concept in brief is to fade the first image in a container, once complete change it's position in the DOM (effectively hiding it behind equal tree level siblings), and call the function again. The reason why this works is because it only fades the first child of the container, but on callback it changes what node that is constantly looping the nodes. This makes for a very small source file that is quite effective.

EDIT 1:


and 32 minutes tweaking later...

Demo 2

EDIT 2:


My oh so simple script is now very complicated :P I added in some scaling features that only work on modern browsers but are there if needed. This one also has a loading bar as it preloads the images (may or may not be desirable :P)

small images demo

large images demo

Joseph Marikle
  • 76,418
  • 17
  • 112
  • 129
2

I think you can still do this with the jQuery cycle plugin; other than image preloading, even the jQuery cycle lite version does everything you want by default out-of-the-box.

And if you look here, you'll see that it's pretty simple to add a little Javascript that will add images (after the first two) as they load. You would need to modify the code a little (instead of stack.push(this), you'd want something like stack.push("<div style="background-image:url("+img.src+")"></div>"), for example) but I think it's totally doable.

Edit: here's a link to a SO question about how to make a div into a clickable link.

Edit 2: I liked Joseph's idea to just move the elements to a hidden DIV, so I updated my code a bit. It now also preserves the links each div points to as well: http://jsfiddle.net/g4Hmh/9/

Edit 3: Last update! http://jsfiddle.net/g4Hmh/12/

Community
  • 1
  • 1
Joshua Conner
  • 882
  • 8
  • 21
  • i have to run to class! will do so in an hour or so. – Joshua Conner Oct 07 '11 at 18:21
  • credit where credit is most definitely due: the async code is adapted from here: http://groups.google.com/group/jquery-en/browse_thread/thread/a368b8563dbb8c5e/1948b4c8fff4c4d3?pli=1 – Joshua Conner Oct 07 '11 at 20:07
  • 1
    I tried to accommodate all of your requests: images are background images of div, divs are links, ss fades in and crossfades, autoplay, etc. – Joshua Conner Oct 07 '11 at 20:44
  • also note that with Joseph's answer as it is the images simply link to themselves; there's no functionality for an image to link somewhere else, as you can with mine. – Joshua Conner Oct 08 '11 at 06:04
  • I like this solution, but I can't get it to work in IE7 — It simply cycles between the first 2 images – Kirk Strobeck Oct 11 '11 at 16:00
  • I changed the JS just a little to alter the jquery.cycle params, the results are here => http://jsfiddle.net/g4Hmh/13/ – Kirk Strobeck Oct 11 '11 at 16:02
  • there's some weirdness with how jquery returns $(element).attr('background-image') in IE. it works fine in IE if you just use IMG tags like everyone else does, or else I can look at it tomorrow. – Joshua Conner Oct 14 '11 at 23:16
1

UPDATE Added the ability to load everything asynchronously.

A wrapper for the jQuery cycle plugin should suffice. You really just need something that monitors if the images loaded and then calls $(elem).cycle(/* options */). Here's my take:

$.fn.cycleWhenLoaded = function(options) {
    var target = this,
        images = options.images,
        loaded = 0,
        total  = 0,
        i;

    if(images) {
        for(i = 0; i < images.length; i ++) {
            $('<img/>').attr('src', images[i]).appendTo(target);
        }
    }

    this.find('> img').each(function(index) {
        var img = new Image(),
            source = this;

        total ++;

        if(index > 1)
            $(this).hide();

        img.onload = function() {
            loaded ++;
            if(loaded == total) {
                target.trigger('preloadcomplete');
                target.cycle(options);
            }
        };

        setTimeout(function() {img.src = source.src}, 1);
    });

    return this;
};

This allows you to either do a simple delay load:

$('.slideshow').cycleWhenLoaded({
    fx: 'fade'
});

Or you can do something more complicated and load your images in the script and capture the preload complete event:

$('.slideshow2').hide().cycleWhenLoaded({
    fx: 'fade',
    images: [
        "http://cloud.github.com/downloads/malsup/cycle/beach1.jpg",
        "http://cloud.github.com/downloads/malsup/cycle/beach2.jpg",
        "http://cloud.github.com/downloads/malsup/cycle/beach3.jpg",
        "http://cloud.github.com/downloads/malsup/cycle/beach4.jpg",
        "http://cloud.github.com/downloads/malsup/cycle/beach5.jpg"
    ]
}).bind('preloadcomplete', function() { $(this).show(); });

You can see it in action here: http://fiddle.jshell.net/vmAEW/1/

Brian Nickel
  • 26,890
  • 5
  • 80
  • 110
0

I don't know how close this is to what you are looking for, but I figured since no one else did I would at least try to help. http://galleria.aino.se/

It at least has a preloader and a fade transition.

watzon
  • 2,401
  • 2
  • 33
  • 65
  • My guess is that you will need to have a custom plugin made. There aren't any that I know of that have all of those features. It would be possible to take the galleria one and customize it to have no controls, timed slides, and instead of using images use fixed width divs with background images. – watzon Oct 07 '11 at 17:59
  • if you want the points, please provide a functional example on jsfiddle – Kirk Strobeck Oct 07 '11 at 18:17
  • @sun-tzu that is false.. anytime the My description is used the browser automatically begins loading the image ... thus you can not keep track of images loading or their progress – samccone Oct 07 '11 at 18:18