How can I crossfade multiple images on hover with jQuery?

47 Views Asked by At

I'm trying to create a smooth transition of a stack of images on hover; what's the best way to do this with jQuery?

The issue is that the first hover image transition goes nicely, but the next two transitions happen too fast. What should happen is that each image should crossfade into the next image after 3 seconds.

Another question is, how can I repeat the image transitions after that last item?

jQuery(document).ready(function($) {
    const items = $('.items .item');
    items.hover(function() {
            const el = $(this);
            const images = el.find('img');
            const imagesAmount = images.length;
            for (let i = 0; i < imagesAmount - 1; i++) {
                setTimeout(function(images) {
                    if (i == 0) {
                        const nextEl = images.first().next().addClass('selected');
                    } else {
                        const selected = $('.selected');
                        selected.removeClass('selected');
                        const nextEl = selected.next();
                        nextEl.addClass('selected');
                    }
                    i++;
                }, i * 3000, images)
            }
        },

        function() {
            clearTimeout()
            const el = $(this);
            const images = el.find('.item img');
            images.removeClass('selected');
        })
})
.items {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1em;
}

.item img {
    display: none;
    width: 100%;
    animation: fadeOut 0.5s;
    cursor: pointer;
}

.item img:first-child {
    display: block;
    animation: none;
}

.item {
    position: relative;
}

.item img.selected {
    position: absolute;
    z-index: 10;
    display: block;
    top: 0;
    animation: fadeIn 0.5s;
}

@keyframes fadeIn {
    from {
        opacity: 0;
    }

    to {
        opacity: 1;
    }
}

@keyframes fadeOut {
    from {
        opacity: 1;
    }

    to {
        opacity: 0;
    }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="items">
  <div class="item">
    <img src="https://picsum.photos/200/300?random=1" alt="" />
    <img src="https://picsum.photos/200/300?random=2" alt="" />
    <img src="https://picsum.photos/200/300?random=3" alt="" />
  </div>
  <div class="item">
    <img src="https://picsum.photos/200/300?random=4" alt="" />
    <img src="https://picsum.photos/200/300?random=5" alt="" />
    <img src="https://picsum.photos/200/300?random=6" alt="" />
  </div>
  <div class="item">
    <img src="https://picsum.photos/200/300?random=7" alt="" />
    <img src="https://picsum.photos/200/300?random=8" alt="" />
    <img src="https://picsum.photos/200/300?random=9" alt="" />
  </div>
</div>

0

There are 0 best solutions below