Fade in a class before fading out completely - javascript

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

Related

Animate sequence going haywire

I have a sequence of images fading out and then back in which appears to work well for about 2 loops. Unfortunately after that it goes crazy and the sequences appears to go completely random.
I have done a fiddle so you can see what's going on https://jsfiddle.net/MichaelCaley/Lmm3kp4m/
var imgshow = function(){
$(".img1").delay(2000).animate({
opacity: 0
}, 3000, function(){
$(".img2").delay(2000).animate({
opacity: 0
}, 3000, function(){
$(".img3").delay(2000).animate({
opacity: 0
}, 3000, function(){
$(".img1").delay(2000).animate({
opacity: 1
}, 3000, function(){
$(".img2, .img3").animate({
"opacity": "1"
}, 0, function(){
imgshow();
});
});
});
});
});
}
imgshow();
After the first run through I've done a sort of reset step which is supposed to be the only time 2 classes are changing at the same time, but when I watch the loop go through I start to see that multiple divs begin fading throughout the process which I just cannot understand.
Thank you for your help
It's very easy to get confused or lost in callback hell, especially with jQuery animations and especially especially when using delay. May I suggest something a bit more clean, in my opinion at least.
// Get all images that need to be looped.
var images = $('.some-class-all-images-share');
// Create an array to store images that have already been shown.
var cycled = $([]);
// Start an interval, which calls the same function every 5 seconds.
setInterval(function(){
// Get the first image from the images array.
var image = images.unshift();
// If the images array is empty, reset everything.
if (images.length === 0) {
images = cycled;
cycled = $([]);
images.removeClass('transparent');
}
// Add a the class 'transparent' to the image.
image.addClass('transparent');
// Add the image to the cycled images array.
cycled.add(image);
}, 5000);
In the CSS:
.some-class-all-images-share {
/* This means that whenever the opacity of the element changes, it will do so gradually, over three seconds, instead of instantly.*/
transition: opacity 3s;
}
.transparent {
opacity: 0;
}
Now every image will get the transparent class applied to it, one by one. This will trigger a three second long animation, and when all images except for the last one have been animated, it will restart.
This way you don't need another callback for each image and it should be, overall much more manageable.

JavaScript/jQuery: Animated Cursor/Light Effect

Recently, I found an SVG with an animated cursor element (like the kind of cursor you see when you're typing text on a screen, like I am now). The JavaScript behind this basically switches the visibility of the target element between on and off. The "cursor" element was the only part of the SVG file that the JavaScript affected. I've found that it can target HTML document objects, too.
Here's the original JavaScript, with id="cursor" (#cursor) marking the target element:
var visible = true;
setInterval(function () {
document.querySelector('#cursor').style.opacity = visible ? 0 : 1;
visible = !visible;
}, 550);
What I want to do is alter this code to make it fade in and out. The resulting effect would be like this:
Fade in quickly (250 ms)
Stay visible for less than half a second (500 ms)
Fade out (250 ms)
Repeat 1.~3.
In other words, steps 1 through 3 would all take place in one second, every second.
The question I have about this is: how do I do this in either JavaScript or jQuery?
(P.S.: is there a jQuery equivalent to the above code?)
Using jQuery, you could do the following
setInterval(function () {
$("#cursor").fadeIn(500, function(){
$(this).fadeOut(500);
});
}, 1000);
Using an interval like you mentioned to start the fade in (utilizing jQuery functions). Passing a callback to fade back out. You can mess with the timing to fit your feel

Jquery auto sliding lists

I have here a slider, built only with HTML and CSS, but it's not auto sliding.
I thought maybe some Jquery will help.
I have a Fade In, Fade Out function but it it's turning the black background while it's changing. And I don't like that!
function InOut(elem) {
var delayOn = 3000, // time each <li> should be visible
delayOff = 0, // time between revealing each <li>
fade = 1000; // fade duration
// Pause, fade in, pause again, fadeout, then fire the callback
elem.delay(delayOff).fadeIn(fade).delay(delayOn).fadeOut(function() {
// If we're not on the last <li>
if (elem.next().length > 0) {
// Call InOut on the next <li>
InOut(elem.next());
}
else {
// Else go back to the start
InOut(elem.siblings(':first'));
}
});
}
$(function() {
// Hide all the li's
$('#slider li').hide();
// Call InOut to loop through them
InOut($('#slider li:first'));
});
Please look at this JSFiddle and let me know how I can do this, a sliding animation will work also, thanks!
PS: If you want to look how is sliding only with CSS, just delete de JS function!
If I understand your question correctly, this may be a solution for you:
Demo Fiddle
It looks like your #slideshow-inner CSS has the background set to black, simply change it to the color you want.
CSS:
#slideshow-inner {
//current styles
background-color: rgba(255,255,240,1);
}

Visual Delay when Hiding and Showing Images successively at a fast speed

I have about 50 Images that should be shown one after another inside a div.
The delay between showing one image then another is about 750 milliseconds and decreasing with each image.
I made sure that all images are loaded before this animation kicks in, by using:
(window).load(function() { });
The animaton is done using setTimeout
var index = 1;
function newImage(index) {
var interval = setTimeout( function(){
$("#image-container .image").css("display","none");
$("#image-container .image:nth-child("+index+")").css("display","block");
clearTimeout(interval);
index = index + 1;
newImage(index);
},delay[index-1]);
}
Where delay is an array of delays, something like [750,750,650,...].
The animation works fine, but there's a visual delay as fast as a blink of an eye, where no image is shown and only the background is visible, how can I avoid it?
try to use visibility css property instead of display

jQuery image crossfade with pre-loader

I want a simple image crossfade, similar to http://malsup.com/jquery/cycle/, but with a pre-loader. Is there a good jQuery plugin that does both? Also, I'm not looking for a load bar.
This question is close, but not the same => jQuery Crossfade Plugin
It would be great if it was a solution that defaulted to CSS3, but would otherwise fall back to JS to keep the processing native as possible.
Looking for something that..
will autoplay
without controls
will go to the next image based on time setting, ie. 5 seconds, unless the next image isn't loaded in which case it finishes loading the image and then displays it.
crossfade transition, not fade to black or white, but cross-fade. from the start it would fadein.
no thumbnails or galleries, etc. just the image
If images could be CSS background images, that would be best, so users can't drag out the image simply
Each panel needs to be clickable so a user could click the image and go to a part of the website.
Well, here's my poke at it. The preloader is in vanilla js and the slideshow loop is in jQuery. It's very simple to implement and the concept is even simpler.
Demo
a very simple Demo that illustrates the DOM manipulation approach
HTML
<!-- not much here... just a container -->
<div id="content"></div>
CSS
/* just the important stuff here. The demo has example styling. */
#content
{
position:relative;
}
#content img
{
position:absolute;
}
javascript/jQuery
// simple array
var images = [
"http://imaging.nikon.com/lineup/dslr/d90/img/sample/pic_003t.jpg",
"http://imaging.nikon.com/lineup/dslr/d90/img/sample/pic_005t.jpg",
"http://imaging.nikon.com/lineup/dslr/d90/img/sample/pic_001t.jpg"
];
// some adjustable variables
var delay = 2000;
var transition = 1000;
// the preloader
for(var i in images)
{
var img = document.createElement("img");
img.src = images[i];
img.onload = function(){
var parent = document.getElementById("content");
parent.insertBefore(this,parent.childNodes[0]);
if(i == images.length - 1)
{
i = 0;
startSlides();
}
}
}
// and the actual loop
function startSlides()
{
$("#content img:last").delay(delay).fadeTo(transition,0,function(){
$(this).insertBefore($(this).siblings(":first")).fadeTo(0,1);
startSlides();
});
}
The concept in brief is to fade the first image in a container, once complete change it's position in the DOM (effectively hiding it behind equal tree level siblings), and call the function again. The reason why this works is because it only fades the first child of the container, but on callback it changes what node that is constantly looping the nodes. This makes for a very small source file that is quite effective.
EDIT 1:
and 32 minutes tweaking later...
Demo 2
EDIT 2:
My oh so simple script is now very complicated :P I added in some scaling features that only work on modern browsers but are there if needed. This one also has a loading bar as it preloads the images (may or may not be desirable :P)
small images demo
large images demo
I think you can still do this with the jQuery cycle plugin; other than image preloading, even the jQuery cycle lite version does everything you want by default out-of-the-box.
And if you look here, you'll see that it's pretty simple to add a little Javascript that will add images (after the first two) as they load. You would need to modify the code a little (instead of stack.push(this), you'd want something like stack.push("<div style="background-image:url("+img.src+")"></div>"), for example) but I think it's totally doable.
Edit: here's a link to a SO question about how to make a div into a clickable link.
Edit 2: I liked Joseph's idea to just move the elements to a hidden DIV, so I updated my code a bit. It now also preserves the links each div points to as well: http://jsfiddle.net/g4Hmh/9/
Edit 3: Last update! http://jsfiddle.net/g4Hmh/12/
UPDATE Added the ability to load everything asynchronously.
A wrapper for the jQuery cycle plugin should suffice. You really just need something that monitors if the images loaded and then calls $(elem).cycle(/* options */). Here's my take:
$.fn.cycleWhenLoaded = function(options) {
var target = this,
images = options.images,
loaded = 0,
total = 0,
i;
if(images) {
for(i = 0; i < images.length; i ++) {
$('<img/>').attr('src', images[i]).appendTo(target);
}
}
this.find('> img').each(function(index) {
var img = new Image(),
source = this;
total ++;
if(index > 1)
$(this).hide();
img.onload = function() {
loaded ++;
if(loaded == total) {
target.trigger('preloadcomplete');
target.cycle(options);
}
};
setTimeout(function() {img.src = source.src}, 1);
});
return this;
};
This allows you to either do a simple delay load:
$('.slideshow').cycleWhenLoaded({
fx: 'fade'
});
Or you can do something more complicated and load your images in the script and capture the preload complete event:
$('.slideshow2').hide().cycleWhenLoaded({
fx: 'fade',
images: [
"http://cloud.github.com/downloads/malsup/cycle/beach1.jpg",
"http://cloud.github.com/downloads/malsup/cycle/beach2.jpg",
"http://cloud.github.com/downloads/malsup/cycle/beach3.jpg",
"http://cloud.github.com/downloads/malsup/cycle/beach4.jpg",
"http://cloud.github.com/downloads/malsup/cycle/beach5.jpg"
]
}).bind('preloadcomplete', function() { $(this).show(); });
You can see it in action here: http://fiddle.jshell.net/vmAEW/1/
I don't know how close this is to what you are looking for, but I figured since no one else did I would at least try to help. http://galleria.aino.se/
It at least has a preloader and a fade transition.

Categories

Resources