I\'m having an issue with my jQuery slideshow and I can\'t seem to figure it out. During the transition of images the slideshow will flash white instead of nicely fading int
you have to show the next image before you start fading out the current one, also you have to do this at the same time, just replace the fadeIn(1000)
of the .next() image to show()
, like this http://jsfiddle.net/nyXUt/6/
maybe minimizing fadeOut()
, and fadeIn()
time or fadeOut(slow)
The problem is you are fading out at the same time as fading in. Using the standard easing functions, there is a point in the middle where both images are barely visible and a white space is left where the images were.
To fix this, I have switched around the order of you images so that the visible image is on top of the stack. Now we can place the new image on top of the currently visible image and fade it in. Once the new image is fully visible we hide the previous image. This makes for a much smoother transition.
$('#slideshow img:first').appendTo('#slideshow');
$('#slideshow img:last').fadeIn(1000, 'swing', function() {
$('#slideshow img:last').prev().hide();
});
Here is a jsfiddle: http://jsfiddle.net/nyXUt/52/
You can try to use the delay function which works (only) with jQuery animations.
$('#slideshow img:first').fadeOut(1000).next().delay(1000).fadeIn(1000).end().appendTo('#slideshow');
But the best way if you use the provided callbacks as stated by other commenters here.
I have re-factored your code and posted it here:
http://jsfiddle.net/salman/nyXUt/44/
The main changes are as follows:
White flash workaround: you were using fade-out and fade-in. When the two animations are started together, both images become 50% transparent at one point and slide appears whitish (or background colorish). I have used another approach. Using z-index, I place the "to hide" image in front of "to show" image then fade out the "to hide" image:
#slideshow .current {
display: block;
z-index: 1;
}
#slideshow .animate {
display: block;
z-index: 2;
}
nextItem.addClass("current");
prevItem.removeClass("current").addClass("animate").fadeOut(animDuration, function () {
$(this).removeClass("animate").css("display", "");
});
setInterval vs setTimeout: I used setTimeout instead of setInterval which gives more control over timing. The automatic transition is re-scheduled when the user interrupts them with prev/next buttons.
Animation timings: I added callbacks and .stop() to animation to prevent overlapping animations.
When you click next or previous you should stop the interval and previous animations i.e.:
clearInterval(run);
$('#slideshow img').stop();
When the fade in for the next image is completed you restart the interval i.e.:
$('#slideshow img:last').fadeIn(1000, function() { run=setInterval("switchSlide()", speed);})
edit: If you click 10 times on a switch button within a second. About 20 animations will run simultaneously.
edit: If you click on next or previous while the image is switching (automatically or otherwise) and the fading is already in progress, the fade will proceed from almost faded to completely faded in a time span of an entire effect (so 1 second). In this time the image will be mostly white.
It might be better to set the fade-out on manual switching faster (like 300ms or even less). This will also improve the users experience.
edit: Here is the fiddle
Here is the code:
var speed = 4000;
run = setTimeout("switchSlide()", speed);
$(document).ready(function() {
$('#caption').html($('#slideshow img:last').attr('title'));
$('#previous').click(switchBack);
$('#next').click(switchSlide);
});
function switchSlide() {
clearInterval(run);
$('#slideshow img').stop(true,true);
var jq=$('#slideshow img');
jq.first().css({'opacity':0}).appendTo('#slideshow').animate({'opacity':1}, 1000, function() {
run = setTimeout("switchSlide()", speed); } );
$('#caption').html(jq.last().attr('title'));
}
function switchBack() {
clearInterval(run);
$('#slideshow img').stop(true,true);
var jq=$('#slideshow img');
jq.last().animate({'opacity':0},1000, function() {
$(this).prependTo('#slideshow').css({'opacity':1}); run = setTimeout("switchSlide()", speed);});
$('#caption').html(jq.get(1).title);
}