I am trying to make a image slideshow that chooses a random image, fades out the current image, and fades in the randomly selected image. If that makes sense. If not, the code might explain what I'm trying to do:
function cycleImages(){
var images = [
"gallery-1.jpg",
"gallery-2.jpg",
"gallery-3.jpg"
];
var randomImg = images[Math.floor(Math.random()*images.length)]
$("#switch").attr("src",randomImg).fadeOut(4000).stop(true,true).hide().fadeIn(4000)
}
$(document).ready(function(){
setInterval('cycleImages()', 7000);
})
This is my first time using Jquery. I want it to fade out before it selects a randomly selected image, but it simply disappears with a hard transition and fades in the next image. Please help me out, thank you!
fadeOut takes a second parameter. A callback function when fading out is complete.
Something like this:
$("#switch").attr("src",randomImg).fadeOut(4000, () => {
//this will run after fading out.
$("#switch").fadeIn(4000);
});
fiddle: https://jsfiddle.net/17w3edgv/1/
Related
I am using JavaScript to change a background image on a page. It works, but there is a minor problem. For a split second, between images there is nothing (just white screen). Again it lasts just a split second but it is annoying.
How can I get one image to fade out while the other is fading in?
I've tried adjusting the fadeIn and fadeOut time, but I realized the second image doesn't start to fadeIn until the first completely fades out.
$(document).ready(function(){
var imgArr = new Array(
'images/home/background_image_1.jpg',
'images/home/background_image_2.jpg',
'images/home/background_image_3.jpg'
);
var preloadArr = new Array();
var i;
/* preload images */
for(i=0; i < imgArr.length; i++){
preloadArr[i] = new Image();
preloadArr[i].src = imgArr[i];
}
var currImg = 1;
var intID = setInterval(changeImg, 20000);
/* image rotator */
function changeImg(){
$('#background-image').fadeOut(1500, function(){
$(this).css('background','url(' + preloadArr[currImg++%preloadArr.length].src +')')
.css("background-position", "center").css("background-repeat", "no-repeat").css("background-size", "cover");
}).fadeIn(1500);
}
});
Any help would be greatly appreciated
Jquery's .fadeOut() has optional parameters .fadeOut( [duration ] [, complete callback ] ).
Where complete callback is the function that will run when the fading animation is done. So that split second is actually the duration you've passed to your .fadeOut() function.
Your code takes 1.5s to perform the animation and then only when it's done then it calls your function that fades in another background image. That's what causing the delay.
An alternative option would be to create seperate executions of .fadeOut() and .fadeIn(). And please don't apply the images on the same element, because you won't achieve it that way. You will need to create an <img> for each picture and set position: absolute on them to position them on top of each other. and then apply fade animation on each <img>
You might need this for revision here
I'm trying to crossfade an array of images, that transfer smoothly between each one, for a slideshow. I've tried fadeIn and fadeOut, and fadeTo but none seem to create the crossfade effect. None of the other articles on here could answer my question exactly.
The function isn't entirely finished, so I know the images won't reset, I'm just trying to get the crossfade to work.
$(function() {
var slides = ["images/slideshow1.jpg", "images/slideshow2.jpg", "images/slideshow3.jpg", "images/slideshow4.jpg", "images/slideshow5.jpg"];
var slidePos = 0;
setInterval(function() {
slidePos++;
$("#slideshow-image").fadeOut(500).fadeIn(1000).attr("src", slides[slidePos]);
}, 3000);
});
Actual: Image switches to next then fades out, then fades in
Expected: Cross-Fade
You must make a second image element with the opacity of zero and have it overlap by having its position set to absolute.
Then animate its opacity to 1.0 and remove the old image element which is now hidden underneath the new one.
Then repeat this process.
You don't have to create new elements if you just have two and cycle between them.
I have created a sliding image gallery and when the button is pushed it slides the picture across and updates the image attribute for the relevant sections.
However this works perfectly like 50% of the time. The other times there is a second glitch and the images then go in place as expected.
I have attached the javascript methods for the animate method and the array change method. I have looked elsewhere and cannot see anyone else with a similar issue or where I am going wrong, especially when it doesn't happen often.
imageGallery.leftSelect.onclick = function () {
window.setTimeout(imageGallery.rightClick, 250);
imageGallery.animateImages('.image1', '.imageRight');
imageGallery.animateImages('.imageRight', '.imageNoneRight');
imageGallery.animateImages('.imageLeft', '.image1');
imageGallery.animateImages('.imageNoneLeft', '.imageLeft');
};
animateImages: function (classFrom, classTo) {
var classMoving = $(classFrom);
var classGoingTo = $(classTo);
classMoving.animate({
top: classGoingTo.css('top'),
left: classGoingTo.css('left'),
width: classGoingTo.css('width'),
opacity: classGoingTo.css('opacity'),
}, 258, function () {
console.log('Animated');
classMoving.css({"width":'', "opacity":'', "top":'', "left":'', });
});
},
rightClick: function () {
imageGallery.imagesDisplay.push(imageGallery.imagesDisplay.shift());
imageGallery.imageNoneLeft.setAttribute('src', imageGallery.imagesDisplay[2]);
imageGallery.imageLeft.setAttribute('src', imageGallery.imagesDisplay[1]);
imageGallery.imageMain.setAttribute('src', imageGallery.imagesDisplay[0]);
imageGallery.imageRight.setAttribute('src', imageGallery.imagesDisplay[10]);
imageGallery.imageNoneRight.setAttribute('src', imageGallery.imagesDisplay[9]);
},
Can someone assist, I really need this to work?
If there is anything not clear or you need more code let me know.
Thanks,
First things first, the culprit was the setAttribute of all images i.e. whatever you were doing inside the rightClick and leftClick functions were the reasons why you were seeing a glitch. Changing src of an img tag produces the glitch.
But then we cannot simply remove it because your approach relies heavily on this swapping of images.
I had to breakdown and really understand your approach first. The way it worked was that you would animate, for example, image1 (the centered one) to move to the position of imageLeft upon click on the rightCarousel button. On that same click, you had a setTimeout of almost the duration of the animation to call rightClick function. This rightClick function then swaps the images so that image1 can always remain at the center and only images can come and go after animation. This was the problem.
What I had to change was that all image tags i.e. imageNoneLeft, imageLeft, image1, imageRight & imageNoneRight would change each others classes such that their position remains changed after animations.
Also, I had to add another animateImages line inside your leftSelect and rightSelect callbacks to animate the furthest images i.e. imageNoneLeft & imageNoneRight to animate to each other's positions with respect to the click of the buttons.
Take a look at this jsFiddle. It will help you understand a lot better. And let me know if you have any questions.
JavaScript:
var imageGallery={
prefix:'https://dl.dropboxusercontent.com/u/45891870/Experiments/StackOverflow/1.5/',
imagesDisplay:['JS.jpg','PIXI.jpg','GSAP.jpg','JS.jpg','PIXI.jpg','GSAP.jpg','JS.jpg','PIXI.jpg','GSAP.jpg','JS.jpg','PIXI.jpg'],
rightSelect:document.querySelector('.rightCarousel'),
leftSelect:document.querySelector('.leftCarousel'),
imageMain:document.querySelector('.image1'),
imageLeft:document.querySelector('.imageLeft'),
imageRight:document.querySelector('.imageRight'),
imageNoneLeft:document.querySelector('.imageNoneLeft'),
imageNoneRight:document.querySelector('.imageNoneRight'),
init:function(){
imageGallery.imagesDisplay.push(imageGallery.imagesDisplay.shift());
imageGallery.imageNoneLeft.setAttribute('src',imageGallery.prefix+imageGallery.imagesDisplay[2]);
imageGallery.imageLeft.setAttribute('src',imageGallery.prefix+imageGallery.imagesDisplay[1]);
imageGallery.imageMain.setAttribute('src',imageGallery.prefix+imageGallery.imagesDisplay[0]);
imageGallery.imageRight.setAttribute('src',imageGallery.prefix+imageGallery.imagesDisplay[10]);
imageGallery.imageNoneRight.setAttribute('src',imageGallery.prefix+imageGallery.imagesDisplay[9]);
},
animateImages:function(classFrom,classTo){
var classMoving=$(classFrom);
var classGoingTo=$(classTo);
classMoving.animate({
top:classGoingTo.css('top'),
left:classGoingTo.css('left'),
width:classGoingTo.css('width'),
opacity:classGoingTo.css('opacity')
},258,function(){
$(this).removeClass(classFrom.substr(1));
$(this).addClass(classTo.substr(1));
$(this).removeAttr('style');
});
}
};
imageGallery.init();
imageGallery.leftSelect.onclick=function(){
imageGallery.animateImages('.imageNoneRight','.imageNoneLeft');
imageGallery.animateImages('.imageRight','.imageNoneRight');
imageGallery.animateImages('.image1','.imageRight');
imageGallery.animateImages('.imageLeft','.image1');
imageGallery.animateImages('.imageNoneLeft','.imageLeft');
};
imageGallery.rightSelect.onclick=function(){
imageGallery.animateImages('.imageNoneLeft','.imageNoneRight');
imageGallery.animateImages('.imageLeft','.imageNoneLeft');
imageGallery.animateImages('.image1','.imageLeft');
imageGallery.animateImages('.imageRight','.image1');
imageGallery.animateImages('.imageNoneRight','.imageRight');
};
I would like to change an image in my site with fading effect. The thing is that I am using two different classes for the same div, so actually I want to fade out one class and in the meanwhile start fading in the second class, before the first one has been completely removed.
HTML:
<div id="background_image" class="day"></div>
CSS:
.day{
background: url(day.png);
}
.night {
background: url(night.png);
}
JQuery:
setTimeout(function(){
if($("#background_image").hasClass("day")){
$("#background_image").fadeOut(function() {
$(this).removeClass("day");
});
$("#Landscape").fadeIn(function() {
$(this).addClass("night");
});
}else{
$("#background_image").fadeOut(function() {
$(this).removeClass("night");
});
$("#Landscape").fadeIn(function() {
$(this).addClass("day");
});
}
}, 5000);
But this code makes the image "day.png" first to disappear completely and then the "night.png" comes which is not what I want.
Is there a way to fade out the class "day" and start fade it "night" without having a blank space between the fading? Thanks in advance
It seems that what you're trying to do is cross-fading. This is normally done using 2 divs. If this is for the entire background, then I suggest http://srobbin.com/jquery-plugins/backstretch/. You can take a look at their implementation to narrow it down to just a div if you don't need it to cover the entire background.
This is how I solved it for a similar case.
var images = [
"/content/images/crane1.jpg",
"/content/images/crane2.jpg",
"/content/images/crane-interior.jpg"
];
// The index variable will keep track of which image is currently showing
var index = 0;
// Call backstretch for the first time,
// In this case, I'm settings speed of 500ms for a fadeIn effect between images.
$.backstretch(images[index], { speed: 500 });
// Set an interval that increments the index and sets the new image
// Note: The fadeIn speed set above will be inherited
setInterval(function () {
index = (index >= images.length - 1) ? 0 : index + 1;
$.backstretch(images[index]);
}, 5000);
EDIT:
For non-full background, take a look at this post Crossfade Background images using jQuery
Also take a look at this, might be closer to your scenario Cross fade background-image with jQuery
the following code which is called periodically by setInterval performs the following sequence:
1. fade in an image for 750 msec
2. diplay it for 6 secs
3. fade out the image for 750 msec
4. randomly select another image (function randomPic)
5. fade in for 750 msec and so on:
$("#_fadee_").fadeIn(750, function() {
$("#_fadee_").delay(6000).fadeOut(750, randomPic);
});
You can see the effect here. How can I get the fadeOut of the old image and the fadeIn of the new one to run simultaneously?
Thanks, Ralf
Basically, you need to load the new image in another div that has a z-index beneath the image fading out. It's not that it's fading in simultaneously, it's just uncovered as the initial is fading out. Once the top div is faded out completely, you load the mew image into it and return its opacity to 1 so that it covers the div that you will load the next image into. In pseudocode it would look something like this:
var fadeO = function () {
var $fo = $('#_fadeO_');
var $fi = $('#_fadeI_');
var newImg = // load image here;
$fi.html(newImg);
$fo.fadeOut(1500, function() {
// put #_fadeO_ back on top with new image
$fo.html(newImg);
$fo.css({'display':'block', 'opacity':1});
// call function again after 6 seconds
setTimeout(fadeO, 6000);
});
};
fadeO();
...but I made a fiddle of it so you could see it in action, switching background colors instead of image contents. You should be able to get the idea of how to do the same with loaded images based on the above pseudo-code and how the HTML, CSS, and JS is set up here:
http://jsfiddle.net/UbmS9/
If you aren't doing anything else you could do this:
$("#_fadee_").fadeIn(750, function() {
setTimeout(function() {
$("#_fadee_").fadeOut(750, randomPic);
// Start fading in your other pic
}, 6000);
});
Alternatively, if they're both being displayed in the same area, you could fade in, and once faded in set the background image to the next image. Then, once that's faded out, set the background to the next, and so on.