I am having some troubles trying to crossfade a slideshow with images. These images are displayed by the background-img attribute.
When I use the .fadeOut() and .fadeIn() functions the image first fades into nothing before it displays the next image.
I have tried solving this with the .load() function but that didn`t seem to work.
Here is my code:
mySlider.js:
var slides = [
{
url: "#",
src: "http://localhost:8888/Imprez_v2/wp-content/uploads/2018/11/slider13.png"
},
{
url: "#",
src: "http://localhost:8888/Imprez_v2/wp-content/uploads/2018/11/slider10.jpg"
},
{
url: "#",
src: "http://localhost:8888/Imprez_v2/wp-content/uploads/2018/11/slider9.jpg"
},
{
url: "#",
src: "http://localhost:8888/Imprez_v2/wp-content/uploads/2018/11/slider3.jpg"
},
{
url: "#",
src: "http://localhost:8888/Imprez_v2/wp-content/uploads/2018/11/slider4.png"
},
{
url: "#",
src: "http://localhost:8888/Imprez_v2/wp-content/uploads/2018/11/slider2.png"
},
{
url: "#",
src: "http://localhost:8888/Imprez_v2/wp-content/uploads/2018/11/slider11.jpg"
},
{
url: "#",
src: "http://localhost:8888/Imprez_v2/wp-content/uploads/2018/11/slider12.jpg"
},
{
url: "#",
src: "http://localhost:8888/Imprez_v2/wp-content/uploads/2018/11/slider1.png"
},
{
url: "#",
src: "http://localhost:8888/Imprez_v2/wp-content/uploads/2018/11/slider5.jpg"
},
{
url: "#",
src: "http://localhost:8888/Imprez_v2/wp-content/uploads/2018/11/slider7.jpg"
},
{
url: "#",
src: "http://localhost:8888/Imprez_v2/wp-content/uploads/2018/11/slider8.jpg"
}
]
myScript.js:
const initiateSlider =()=> {
console.log("initiateSlider");
$("#mySlider").css('background-image', 'url(' + slides[0].src + ')');
$("#mySlider").data('sld','0');
setTimeout(nextSlide, 5000); // voert nextSlide 1x uit na x seconden
}
const nextSlide =()=> {
console.log("nextSlide");
let currentSlide = $("#mySlider").data('sld');
$("#mySlider").data('sld', parseInt(currentSlide) + 1);
let newSlideIndex = $("#mySlider").data('sld');
console.log(newSlideIndex);
if(newSlideIndex < slides.length)
{
$("#mySlider").css('background-image', 'url(' + slides[newSlideIndex].src + ')');
setTimeout(nextSlide, 5000);
}
else {
initiateSlider();
}
}
As you've said, the main issue is that when the image fades out, nothing is behind it. You will need to position the next image under the first image, so that when the first image fades out, you can slowly see the image behind it. Then, after the fade out is complete, move that image to the back of the line.
So in this example, what I do is have two divs who are position exactly on top of one another. This is done with position: absolute;
. Then I fade out the top one, so the bottom one is showing, then move the top one to the bottom, change it's image, and reset it's styles. At this point the other image is on top, and I just fade that one out.
<style>
.frame {
border: 2px solid grey;
position: relative;
height: 400px;
width: 400px;
}
.image {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-size: cover;
background-position: center;
z-index: 1;
}
.image:nth-child(1) {
z-index: 2;
}
</style>
<div class="frame">
<div class="image"></div>
<div class="image"></div>
</div>
<script>
let current_image = 0;
const images = [
'https://picsum.photos/200/300?image=0',
'https://picsum.photos/200/300?image=1',
'https://picsum.photos/200/300?image=2',
'https://picsum.photos/200/300?image=3',
'https://picsum.photos/200/300?image=4',
'https://picsum.photos/200/300?image=5',
'https://picsum.photos/200/300?image=6',
];
// keep track of current image
// increment by one
// if at end of array, start over
const update_counter = function(){
if (images[current_image] === undefined){
current_image = 0;
} else {
current_image += 1;
}
}
// get first image
// fade it out
// move it under the newly visible image
// update it's src to be new image
// remove it's style tag (which was applied by fadeOut() ) so it can be visible
// update current_image counter
const transition_images = () => {
const top_image = $('.image:nth-child(1)');
const bottom_image = $('.image:nth-child(2)');
const new_image = images[ current_image ];
top_image.fadeOut(2000, function(){
top_image.insertAfter(bottom_image);
top_image.removeAttr('style');
top_image.css('background-image', 'url('+ new_image +')');
update_counter();
});
}
// set up initial images
// get all .image elements and assign them an image attr
// each time one is assigned, update the current_image counter
$('.image').each(function(){
const new_image = images[ current_image ];
$(this).css('background-image', 'url('+ new_image +')');
update_counter();
});
// set timer in motion
const time = 2500;
setInterval(transition_images, time)
</script>