Search code examples
javascriptimageslideshowfade

Javascript Fade Into New Image When Clicked


Right now I have a code to switch between two images when clicking text, but I'd like to create a function where I can click on the image itself and it fades into the next one, and be able to do this with more than two images. Also the images I want to use vary in width and height, but all have a max height and width of 600px. Here's my current code:

HTML:

<div id="cf2" class="shadow">
<img class="bottom" src="/images/Cirques.jpg" />
<img class="top" src="/images/Clown%20Fish.jpg" />
</div>
<p id="cf_onclick">Click me to toggle</p>

CSS:

#cf2 {
    position:relative;
    height:281px;
    width:450px;
    margin:0 auto;
}
#cf2 img {
    position:absolute;
    left:0;
    -webkit-transition: opacity 1s ease-in-out;
    -moz-transition: opacity 1s ease-in-out;
    -o-transition: opacity 1s ease-in-out;
    transition: opacity 1s ease-in-out;
}

#cf2 img.transparent {
    opacity:0;
}
#cf_onclick {
    cursor:pointer;
}

JavaScript:

$(document).ready(function() {
    $("#cf_onclick").click(function() {
        $("#cf2 img.top").toggleClass("transparent");
    });
});

Solution

  • This will work for multiple images:

    $(document).ready(function() {
        $.fn.nextOrFirst = function (selector) {
            var next = this.next(selector);
            return (next.length) ? next : this.prevAll(selector).last();
        };
        $("#cf2 img").click(function() {
            $(this)
            .removeClass('visible')
            .nextOrFirst()
            .addClass('visible');
        });
    });
    #cf2 {
        position:relative;
        height:281px;
        width:450px;
        margin:0 auto;
    }
    #cf2 img {
        position:absolute;
        left:0;
        max-height: 600px;
        max-width: 600px;
        opacity: 0;
        z-index: 0;
        -webkit-transition: opacity 1s ease-in-out;
        -moz-transition: opacity 1s ease-in-out;
        -o-transition: opacity 1s ease-in-out;
        transition: opacity 1s ease-in-out;
    }
    
    #cf2 img.visible {
        opacity: 1;
        z-index: 1;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div id="cf2" class="shadow">
        <img class="visible" src="http://static.ddmcdn.com/gif/storymaker-best-hubble-space-telescope-images-20092-514x268.jpg" alt="1"/>
        <img src="http://economictimes.indiatimes.com/thumb/msid-45891755,width-640,resizemode-4/nasas-images-of-most-remarkable-events-you-cant-miss.jpg" alt="2"/>
        <img src="http://i.dailymail.co.uk/i/pix/2013/11/03/article-2486855-192ACC5200000578-958_964x682.jpg" alt="3"/>
        <img src="http://mstatic.mit.edu/nom150/items/199-HybridImage.jpg" alt="4"/>
    </div>

    Instead of having an .invisible class, I used a .visible class, which also has a z-index of 1, greater than that of the default images. So the image that has that class, will be visible, while the others will have opacity: 0 by default.

    I also extended the jQuery object to have a nextOrFirst method (which I stole from here), so that when the visible image is the last one of the images in the stack, the next one will be the first. So now, the order of the images, as they appear, goes from top to bottom.

    I decided to do it like this in order to keep your CSS transitions, but you can also use jQuery's fadeIn and fadeOut methods.