junkystu
junkystu

Reputation: 1487

Jquery animate image source replacement left to right and vicersa

I have an image gallery where I'm replacing the source when clicking next/previous and I want the images to slide when doing so. Something like:

 function next(){
    imageNr++;
    image.animate({left: -1000}, 'slow',function() {
        image.attr('src', imageURL + imageNr + imgExt);
    });
    image.animate({right: 1000}, 'slow');
}

So when clicking next, the current image should move to the left and bring the next image from the right and the other way around when clicking previous. How can one go about doing that? Thank you in advance.

jsfiddle: http://jsfiddle.net/sDZ9j/

Upvotes: 0

Views: 1733

Answers (2)

Valamas
Valamas

Reputation: 24759

Thanks to junkystu, this is the code I used. Note the settimeout which aids the transition (so you dont see the new image leaving the gallery). The figure 95 is based on the animate speed of 100 and is via eye adjustment only. I also added a reverse animation if the user clicked previous image.

I also have thumbnails the user can click on which does not perform any animation. Hence, the if next else if prev is skipped when direction == "none"

Old code - don't use this.

if (direction == "next")
    image.animate({ 'left': '-1000' }, 100, function () { image.css({ 'left': '1000px' }); });
else if (direction == "prev")
    image.animate({ 'left': '1000' }, 100, function () { image.css({ 'left': '-1000px' }); });

setTimeout(function() {
    image.attr('src', largerImage);
}, 95);

if (direction == "next")
    image.animate({ 'left': '0' }, 100);
else if (direction == "prev")
    image.animate({ 'left': '0' }, 100);

Another tip is have the img tag inside a div where overflow: hidden;

New Code!

Here are my document.ready control event hookups

$(document).on("click", ".gallery-thumbnail", function (e)
    {
        var gallery = $(this).closest('.gallery');
        GallerySetFeature(gallery, $(this).attr("data-gallery-id"), "none");
    });

    $(document).on("click", ".gallery-prev", function (e) { GalleryNextPrev(this, e); });
    $(document).on("click", ".gallery-next", function (e) { GalleryNextPrev(this, e); });
    //-- only showing the next/prev controls on hover.
    $(document).on("mouseenter", ".gallery-feature", function (e)
    {
        $(this).find('.gallery-next').removeClass('invisible');
        $(this).find('.gallery-prev').removeClass('invisible');
    });
    $(document).on("mouseleave", ".id-gallery-feature", function (e)
    {
        $(this).find('.gallery-next').addClass('invisible');
        $(this).find('.gallery-prev').addClass('invisible');
    });

Here is my function for when the next/prev control is clicked. This handles doing the reverse animation when exceeding direction before first image or after last image.

function GalleryNextPrev(control, e)
{
    var gallery = $(control).closest('.gallery');
    var ubound = parseInt(gallery.attr('data-gallery-ubound'));
    var current = parseInt(gallery.attr('data-gallery-currentid'));
    var directionIsNext = $(control).hasClass('gallery-next');

    var newIndex = (directionIsNext ? current + 1 : current - 1);
    if (newIndex > ubound)
    {
        newIndex = 0;
        directionIsNext = false;
    } 
    else if (newIndex < 0)
    {
        newIndex = ubound;
        directionIsNext = true;
    }

    GallerySetFeature(gallery, newIndex, (directionIsNext ? "next" : "prev"));
}

Here is my function that does the animation. Note the imagesLoaded function (get http://desandro.github.io/imagesloaded/)! Oh, plus I add an ajax spinner on top of the image if it does not load in a certain time.

var ajaxSpinnerId;
function GallerySetFeature(gallery, thumbIndex, direction)
{
    thumbIndex = parseInt(thumbIndex);
    gallery.attr('data-gallery-currentid', thumbIndex);
    var thumbnail = gallery.find('[data-gallery-id=' + thumbIndex + ']');
    var thumbnailImg = thumbnail.find('img');

    var largerImage = thumbnail.attr('data-gallery-larger');
    var downloadLink = thumbnail.attr('data-gallery-download');
    var thumbTitle = thumbnail.attr('data-gallery-title');

    var feature = $(gallery).find('.gallery-feature');
    var feature_img = $(gallery).find('.gallery-feature img');

    if (direction == "next")
        feature_img.animate({ 'left': '-1000' }, 100, function() { feature_img.css({ 'left': '1000px' }); });
    else if (direction == "prev")
        feature_img.animate({ 'left': '1000' }, 100, function() { feature_img.css({ 'left': '-1000px' }); });


    feature_img.attr('src', largerImage);
    feature_img.attr('width', feature_img.width);
    feature_img.attr('height', feature_img.height);

    //-- IsUndefined is my function, but you know what it is anyway. Just checking Is Undefined!
    if (IsUndefined(ajaxSpinnerId))
    {
        ajaxSpinnerId = setTimeout(function() {
            //-- ajax spinner start
            feature.addClass("gallery-ajax");
        }, 150);
    }

    imagesLoaded(feature_img, function() {
        //-- ajax spinner end
        clearTimeout(ajaxSpinnerId);
        ajaxSpinnerId = undefined;
        feature.removeClass("gallery-ajax");

        if (direction == "next")
            feature_img.animate({ 'left': '0' }, 100);
        else if (direction == "prev")
            feature_img.animate({ 'left': '0' }, 100);
    });

    //-- Just setting labels like title, image size and download link all storted client side as attributes.
    $(gallery).find('.gallery-download').attr('href', downloadLink);
    $(gallery).find('.gallery-title').text(thumbTitle);
    $(gallery).find('.gallery-position').text(thumbIndex + 1);

    //-- because I have little thumbnails the user can directly click on. I put a color border around the thumbnail to indicate the current showing. This works for prev/next image link too.
    gallery.find('.gallery-thumbnail-img-selected').removeClass('gallery-thumbnail-img-selected').addClass('gallery-thumbnail-img');
    thumbnailImg.addClass('gallery-thumbnail-img-selected').removeClass('gallery-thumbnail-img');
}

Upvotes: 0

junkystu
junkystu

Reputation: 1487

Managed to get it working with:

    image.animate({'left' : '-1000'},'fast', function(){image.css({'left': '1000px'});});       
    image.attr('src',imageURL + imageNr + imgExt);      
    image.animate({'left' : '0'},'fast');   

Upvotes: 1

Related Questions