8

I'm trying to get this to crossfade, but I'm not entirely sure how.

How can I make this jQuery method crossfade the images?

$('a.thumb').click(function () {
    var src = $(this).attr('href');
    if (src != $('div#imageDisplay > img').attr('src')) {
        $('div#imageDisplay > img').stop().animate({ opacity: '0', duration: 500 }, function () {
            $(this).attr('src', src);
        }).load(function () {
            $(this).stop().animate({ opacity: '1', duration: 500 });
        });
    }
    return false;
});
Eric J.
  • 147,927
  • 63
  • 340
  • 553
Chase Florell
  • 46,378
  • 57
  • 186
  • 376
  • I believe what you are looking for is referenced here: http://stackoverflow.com/questions/727604/jquery-crossfade-plugin –  Mar 16 '12 at 23:40
  • yeah I looked at that. I don't want a bloated plugin when I'm sure there's a simple way to just punch out a cross fade. – Chase Florell Mar 16 '12 at 23:41
  • A simple way to do it is to set the background image of the element as the fade-to image and then animate the opacity of the image over it to zero. Otherwise you're juggling element and/or sprites. – j08691 Mar 16 '12 at 23:48

2 Answers2

13

A cross fade between two images (where one fades out and the other fades in) requires two images, each with their own animation. You can't do it with just one image tag. You will need two images. There are ways to use a background image for one of the images, but frankly that's just more complicated than using two <img> tags.

Here's some jQuery that implements a cross fade using two image tags:

// precache all images so they will load on demand
var imgs = [];
$('a.thumb').each(function() {
    var img = new Image();
    img.src = this.href;
    imgs.push(img);
}).click(function () {
    var oldImg = $("#fadeContainer img");

    var img = new Image();
    img.src = this.href;
    var newImg = $(img).hide();
    $("#fadeContainer").append(img);

    oldImg.stop(true).fadeOut(500, function() {
        $(this).remove();
    });
    newImg.fadeIn(500);
    return false;
});​

You can see it work here: http://jsfiddle.net/jfriend00/frXyP/

This is basically how it works:

  1. Get the current image
  2. Create new image object
  3. Fetch URL from the clicked on link and assign to new image tag
  4. Hide the new image
  5. Insert the new image into the fadeContainer
  6. Initiate fadeOut of existing image and fadeIn or new image
  7. When fadeOut finishes, remove that image so it's ready for the next cycle
Andiih
  • 12,285
  • 10
  • 57
  • 88
jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • This works great, only issue I'm having is getting the image to fade directly over the old image.... getting close. – Chase Florell Mar 17 '12 at 00:37
  • @ChaseFlorell - you can see how I did it in the jsFiddle using `position:absolute` inside a `position:relative` container. – jfriend00 Mar 17 '12 at 02:13
  • yeah, I'm still working on it. It sort of works, but unfortunately when I'm dealing with portrait as well as landscape images, it's not as easy. – Chase Florell Mar 17 '12 at 03:03
  • Here's the fiddle I'm working through - http://jsfiddle.net/rockinthesixstring/cX3y9/ – Chase Florell Mar 17 '12 at 03:11
  • 1
    Here's a version that centers the images with javascript: http://jsfiddle.net/jfriend00/DXKVn/ – jfriend00 Mar 17 '12 at 05:05
  • Yeah, that's cool for sure! Thanks for all the help. Sometimes I don't know if I should look for a CSS solution or a Javascript solution. – Chase Florell Mar 17 '12 at 16:09
  • 1
    @ChaseFlorell - In this case, it's hard to mix absolute positioning with CSS centering so I just went the few lines of code to use JS to center. I generally look for the CSS solution first. – jfriend00 Mar 17 '12 at 16:23
3

You cannot crossfade with one img element, you need two at-least. One to be opaque, and the other to fade. Please consider putting positioning one img over the other, setting to 'display:none' in css, then calling 'fadeIn'.

Fresheyeball
  • 29,567
  • 20
  • 102
  • 164