fadeOut, fadeIn and stop - javascript

How do I make my image fade in and stop using the code below? what do I add to it?
Thanks in advance for any correct answers it is much appreciated!
HTML:
<div class="fadeImg" >
<img src="images/25sprout.jpg">
<img style="display:none;" src="images/alex.jpg">
<img style="display:none;" src="images/thundersha.jpg">
<img style="display:none;" src="images/cathy.jpg">
<img style="display:none;" src="images/david.jpg">
</div>
JQuery:
<script type="text/javascript" src="js/package/jquery-1.7.2.min.js"></script>
<script type="text/javascript">
$next = 1; // fixed, please do not modfy;
$current = 0; // fixed, please do not modfy;
$interval = 4000; // You can set single picture show time;
$fadeTime = 800; // You can set fadeing-transition time;
$imgNum = 5; // How many pictures do you have
$(document).ready(function(){
//NOTE : Div Wrapper should with css: relative;
//NOTE : img should with css: absolute;
//NOTE : img Width & Height can change by you;
$('.fadeImg').css('position','relative');
$('.fadeImg img').css({'position':'absolute','width':'332px','height':'500px'});
nextFadeIn();
});
function nextFadeIn(){
//make image fade in and fade out at one time, without splash vsual;
$('.fadeImg img').eq($current).delay($interval).fadeOut($fadeTime)
.end().eq($next).delay($interval).hide().fadeIn($fadeTime, nextFadeIn);
// if You have 5 images, then (eq) range is 0~4
// so we should reset to 0 when value > 4;
if($next < $imgNum-1){ $next++; } else { $next = 0;}
if($current < $imgNum-1){ $current++; } else { $current =0; }
};
</script>

Your simplest option is to stop when $current matches $imgNum:
function nextFadeIn() {
if ($current >= $imgNum) return;
//make image fade in and fade out at one time, without splash vsual;
Although purists might not like this as it means an extra iteration of nextFadeIn(), it should cover what you need with minimal changes.

Related

jQuery .each() method doesn't iterate over all images

I am trying to make an image carousel. I am using the jQuery .each() method to iterate over all the images in the div with class="slideshow".
HTML code
<div class="slideshow">
<img src="images/page-1-hero-image.jpg" alt="school's image" class="img-responsive page-one-pic mySlides">
<img src="images/Capture2.PNG" alt="school pic" class="img-responsive mySlides">
<img src="images/Capture.PNG" alt="school pic" class="img-responsive mySlides">
<img src="images/Capture3.PNG" alt="school pic" class="img-responsive mySlides">
</div>
CSS code
.mySlides {
display: none;
position: fixed;
left: 0;
top: 0;
z-index: 1;
/* to make pic responsive */
min-height: 100%;
min-width: 1024px;
width: 100%;
height: auto;
}
Javascript:
function carousel() {
$(".slideshow > img").each(function(index, element) {
$(element).fadeIn(1000).delay(2000);
setTimeout(carousel, 1000);
});
}
The function only fades in the first image and then stops. The other images are not displayed.
here is the link to the hosted project:
https://rimildeyjsr.github.io/St.Anthony-Website/
This code:
function carousel() {
$(".slideshow > img").each(function(index,element){
$(element).fadeIn(1000).delay(2000);
setTimeout(carousel,1000);
});
}
Says: "For each img element, spend a second fading in, then delay by two seconds before doing nothing, and reschedule this entire process (not per element, for all of them) to run again a second from now."
That doesn't make much sense, you'll be calling carousel several times again roughly at the time the first image finishes fading out.
Given the term "slideshow" I'd guess what you're trying to do is show each image for two seconds before spending a second having the next one fade in, looping when you get to the end. If so, you want to call carousel once, two seconds after the last image has finished fading in. You can do that by delaying the fades and the next call.
function carousel() {
var imgs = $(".slideshow > img");
imgs.each(function(index,element){
// Don't make the first one (index = 0) wait at all;
// make the second (index = 1) wait 3 seconds, the third
// (index = 2) wait 6 seconds, etc. And then fade in
$(element).delay(index * 3000).fadeIn(1000);
});
// Start the entire process again two seconds after the last image fades in
setTimeout(carousel, imgs.length * 3000);
}
Just an improvement to the previous answer, you can do it in the form of a callback(which ensures you that the function is called only after the fadeIn has occurred or happened, so you wont need a setTimeout) as follows
function carousel() {
var imgs = $(".slideshow > img");
imgs.each(function(index, element) {
$(element).delay(index * 2000).fadeIn(1000, function() {
if (index + 1 >= imgs.length) {
carousel(); // call the function only after all images are fadeIn completed
}
});
});
}
See if that helps and if not drop a comment below
Edit:
After .fadeIn() does it's job, it sets the display value to block what you have to do here is, hide the elements before continuing the slideshow animation, for simplicity we'll set all the img elements display to hidden by using .hide(0). This sets the elements display to none
function carousel() {
var imgs = $(".slideshow > img");
imgs.stop().hide(0); // hide all the images whenever the carousel() is called
imgs.each(function(index, element) {
$(element).delay(index * 2000).fadeIn(1000, function() {
if (index + 1 >= imgs.length) {
carousel(); // call the function only after all images are fadeIn completed
}
});
});
}
Let me know if you need anything else

Fade In / Fade Out background images without white background

I want to create a website with background images that change over time with a fade in/fade out effect, but I don't want to use the existing jQuery fade in/fade out effect because with when one image faded out, a white background appeared before other image faded in. I found a plugin named Maximage that suits my request but it uses img tags while I want to work with background-image CSS (I have a good reason for doing this). Does anyone know how to do this?
Here's my HTML code:
<div id="wrapper">
//My contain here
</div>
Here's my JavaScript code so far:
//Auto change Background Image over time
$(window).load(function() {
var images = ['img/top/bg-1.jpg','img/top/bg-2.jpg','img/top/bg-3.jpg'];
var i = 0;
function changeBackground() {
$('#wrapper').fadeOut(500, function(){
$('#wrapper').css('background-image', function () {
if (i >= images.length) {
i = 0;
}
return 'url(' + images[i++] + ')';
});
$('#wrapper').fadeIn(500);
})
}
changeBackground();
setInterval(changeBackground, 3000);
});
Example: http://www.aaronvanderzwan.com/maximage/examples/basic.html
AHH ! Finally ! I found a nice technique ! I'm using a double wrapper.
The problem in your code is a bit logical. You can't fadeOut and fadeIn at the same time a single wrapper.
So the idea is to create two wrapper and to switch between them back and forth. We have one wrapper called: "wrapper_top" that encapsulate the second wrapper called: "wrapper_bottom". And the magic was to put beside the second wrapper: your content.
Thus having the structure ready which is the following:
<div id='wrapper_top'>
<div id='content'>YOUR CONTENT</div>
<div id='wrapper_bottom'></div>
</div>
Then a bit of JS+CSS and voilĂ  ! It will be dynamic with any amount of images !!!
Here is the implementation: http://jsbin.com/wisofeqetu/1/
<html>
<head>
<script src="http://code.jquery.com/jquery-1.10.2.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(window).load(function() {
var i =0;
var images = ['image2.png','image3.png','image1.png'];
var image = $('#slideit');
//Initial Background image setup
image.css('background-image', 'url(image1.png)');
//Change image at regular intervals
setInterval(function(){
image.fadeOut(1000, function () {
image.css('background-image', 'url(' + images [i++] +')');
image.fadeIn(1000);
});
if(i == images.length)
i = 0;
}, 5000);
});
</script>
</head>
<body>
<div id="slideit" style="width:700px;height:391px;">
</div>
</body>
</html>
If it doesn't have to be background-image, you can place all the images in your #wrapper, in <img>, it will work like a charm:
<div id="wrapper">
<img src="firstImage" class="imageClass"></img>
<img src="secoundImage" class="imageClass"></img>
<img src="thirdImage" class="imageClass"></img>
</div>
then some style. Every image has to be in same spot, so add position relative to #wrapper, and position absolute to .imageClass:
#wrapper{
position: relative;
}
.imageClass{
position: absolute;
top: 0;
left: 0;
display: none;
}
display: none; will hide every image.
Now some JQuery. To appear first image when window load write this:
$(window).load(function() {
$('.imageClass').eq(0).show();
});
by the .eq() "command" you can specify which one element with class '.imageClass' you want to use exactly. Starts with 0. After that just do something like that:
function changeBackground() {
var current = 0;
//tells which image is currently shown
if(current<$('.imageClass').length){
//loop that will show first image again after it will show the last one
$('.imageClass').eq(current).fadeOut(500);
current++;
$('.imageClass').eq(current).fadeIn(500);
} else {
$('.imageClass').eq(current).fadeOut(500);
current=0;
$('.imageClass').eq(current).fadeIn(500);
}
}
changeBackground();
setInterval(changeBackground, 3000);
});
That should work, hope you will like it.
You may also use jQuery plugin backstretch.

JS Image Cycler - Load in Background

I've got a tricky little problem. I'm just starting out the design for a website with a cycling background image. At the minute it's working fine, although you can see the alternate background images loading with the first image which looks a little messy. I could pretty easily hide these images, but I feel a better solution would be to allow the first image to load before the others to speed up the page load. Unfortunately I cant work out how to incorporate this into my existing JS.
The beginnings of the site are here (it might be broken at some point, I'm still experimenting).
My current JS:
function cycleImages(){
var $active = $('#background-cycler .active');
var $next = ($('#background-cycler .active').next().length > 0) ? $('#background-cycler .active').next() : $('#background-cycler img:first');
$next.css('z-index',2);//move the next image up the pile
$active.fadeOut(1500,function(){//fade out the top image
$active.css('z-index',1).show().removeClass('active');//reset the z-index and unhide the image
$next.css('z-index',3).addClass('active');//make the next image the top one
});
}
$(window).load(function(){
$('#background-cycler').fadeIn(1500);//fade the background back in once all the images are loaded
// run every 7s
setInterval('cycleImages()', 7000);
})
HTML:
<div id="background-cycler" >
<script type="text/javascript">
$('#background_cycler').hide();//hide the background while the images load, ready to fade in later
</script>
<img class="active" src="images/bg1.jpg" alt=""/>
<img src="images/bg2.jpg" alt=""/>
<img src="images/bg3.jpg" alt=""/>
<img src="images/bg4.jpg" alt=""/>
<img src="images/bg5.jpg" alt=""/>
</div>
Any help you could give would be greatly appreciated!! :)
EDIT: The other problem I have is I need this on every page, but I'd rather not reload the images each time. Am I right in thinking the images will still be cached?
Here's my take at it:
http://jsfiddle.net/bortao/9TxED/
You hide the image element and only fade it in when the onload event is triggered.
And yes, all images will be cached by the browser throughout your site.
HTML
<div id="background-cycler" class="background-cycler">
<img id="imgPrev" />
<img id="imgNext" />
</div>
CSS
.background-cycler {
width: 1000px;
height: 600px;
}
.background-cycler img {
position: absolute;
left: 0px;
top: 0px;
}
JS
var imgs = [
'http://ravenstudio.co.uk/izzy/images/bg1.jpg',
'http://ravenstudio.co.uk/izzy/images/bg2.jpg',
'http://ravenstudio.co.uk/izzy/images/bg3.jpg',
'http://ravenstudio.co.uk/izzy/images/bg4.jpg',
'http://ravenstudio.co.uk/izzy/images/bg5.jpg']
var imgNext = document.getElementById("imgNext");
var imgPrev = document.getElementById("imgPrev");
var currentImg = -1;
var MAX_IMAGES = 5;
var CYCLE_DELAY = 2000;
var FADE_DELAY = 1500;
imgNext.onload = function () {
// When finished loading:
$(this).fadeIn(FADE_DELAY, function() {
// When fadeIn ends:
imgPrev.src = imgs[currentImg]; // Send current image to back
}); // Fade in loaded image
window.setTimeout('cycleImages()', CYCLE_DELAY + FADE_DELAY); // Set next cycle
};
cycleImages = function () {
currentImg++;
if (currentImg == MAX_IMAGES) currentImg = 0;
imgNext.style.display = "none"; // Hide before loading
imgNext.src = imgs[currentImg]; // Load new image.
// After imgNext finish loading, onload above will be called
}
cycleImages(); // Call the first cycle

Rotate images as well as the description and link

I would like to make some changes on a code and add some more options:
1- Rotate the images with the description of each one as well as the link,
2- Add the effect fadeOut while the image is disappearing.
Here is my little code:
var images = new Array ('BMW.png', 'Maybach.png', 'Mercedes-Benz.png', 'Mini.png', 'Jaguar.png', 'Toyota.png');
var descs = new Array ('BMW', 'Maybach', 'Mercedes-Benz', 'Mini', 'Jaguar', 'Toyota');
var links = new Array ('www.url1.com', 'www.url2.com', 'www.url3.com', 'www.url4.com', 'www.url5.com', 'www.url6.com');
var index = 1;
function rotateImage()
{
$('#myImage').fadeOut('fast', function()
{
$(this).attr('src', images[index]);
$(this).fadeIn(2000, function()
{
if (index == images.length-1)
{
index = 0;
}
else
{
index++;
}
});
});
}
$(document).ready(function()
{
setInterval (rotateImage, 7000);
});
</script>
</head>
<body>
<div id="test">
<a href="www.url1.com">
<img class="rotate" id="myImage" src="BMW.png" width="800" height="300" alt="image test" />
</a>
<div class="rotate" id="myDesc" style="margin-top: -30px; margin-left: 30px;"></div>
</div>
uhm... something like this?
(Array is ZERO base so... initial index is 0 [with 1 you start with "Maybach.png" not "BMW.png" ]).
"Add the effect fadeOut while the image is disappearing" - if the image is disappearing is already doing a fade out... you should explain this point...
However...
var images = ['http://placehold.it/150x100', 'http://placehold.it/120x150', 'http://placehold.it/90x120', 'http://placehold.it/100x100', 'http://placehold.it/100x150', 'http://placehold.it/150x100'],
descs = ['BMW', 'Maybach', 'Mercedes-Benz', 'Mini', 'Jaguar', 'Toyota'],
links = ['www.url1.com', 'www.url2.com', 'www.url3.com', 'www.url4.com', 'www.url5.com', 'www.url6.com'],
index = 0; //start from first image
function rotateImage()
{
$('#test').fadeOut('fast', function() //fadeout all block (if display none collapse your graphics use animate and "opacity") to hide without change display
{
$(this).find("a").attr('href', links[index]); //add href to url
$(this).find("img").attr('src', images[index]); //add src to image
$(this).find("#myDesc").text(descs[index]); //add description in desc div
$(this).delay(500).fadeIn(2000, function() //delay (a little bit) to wait image load (for bigger image you need longer delay)
{
if (index == images.length-1)
{
index = 0;
}
else
{
index++;
}
});
});
}
$(document).ready(function()
{
rotateImage(); //fire first time and then use Setinterval for loop
setInterval (rotateImage, 7000);
});
Example HERE jsfiddler
I hope this can help.
Simple image preload:
<img src="path/placeholder.gif" data-src="path/realImage.jpg" style="display:none" />
so the image that be loaded is a gif of trasparent singol pixel. when you need to preload you only need to place data-src in src and than show image... (do this when the prev image of your animation was displayed for prevent the load gap when this image will display)

Jquery image cycling issues

I'm working on a website for a family friend. On it they wanted to have logos from all their associates on one row, that subtly fade to get replaced with additional logos that didn't fit the first time.
To achieve this i've assigned the <img>'s classes, that represent what cycle they should appear in, depending on how many of those images will fit on the row given its current width. This happens in my assignCycleNumbers function.
Then to actually fade them in and out i have another function called cycleAssociates which recursively fades the appropriate classes in and out. Well in theory, however it doesn't seem to be working properly, which is particularly odd because i tested the function here and it works fine. The only difference between them is that now i'm trying to assign the cycle numbers dynamically.
I'm really stumped and could do with some help!
You can see the website hosted here and if you scroll down to the bottom of the content you'll see the logos at the bottom, not behaving as expected. (First cycle appears okay but then subsequent cycles get muddled, more observable if you resize to a smaller screen width).
You can inspect the code thoroughly through your browser but here's everything you need to know, again i'd really appreciate any insight.
EDIT: The whole javascript file as requested. But all the relevant stuff is below:
JS:
//single global variable to represent how many logo cycles there is
var totalCycles = 0;
...
$(window).load(function() {
...
totalCycles = assignCycleNumbers();
cycleAssociates();
});
// window is resized
$(function(){
$(window).resize(function() {
...
totalCycles = assignCycleNumbers();
});
});
...
function cycleAssociates(){
var cycle = 0;
var recursiveCycling = function(cycle, totalCycles){
var currentAssociate = ".cycle" + cycle;
//fade in all img with the current cyle class over a second,
//wait 3 seconds before fading out over a second.
$(currentAssociate).delay(100).fadeIn(1000).delay(3000).fadeOut(1000,
function(){
cycle++;
if(cycle > totalCycles){
cycle = 0;
}
recursiveCycling(cycle, totalCycles);
});
};
recursiveCycling(cycle, totalCycles);
}
function assignCycleNumbers(){
//first remove any old cycle# classes (resized window case)
$('[class*="cycle"]').removeClass( function(unusedIdx,c){
return c.match(/cycle\d+/g).join(" ");
});
//measure div width
var divSpace = $("#bodies").innerWidth();
//assign a cycle number to a number of logos until no more will fit in that div
var cycleNum = 0;
$(".associate").each(function(){
if( divSpace - $(this).width() > 0){
$(this).addClass("cycle" + cycleNum);
divSpace = divSpace - $(this).width();
}
else{ //next logo won't fit current cycle, create next cycle
cycleNum++
$(this).addClass("cycle" + cycleNum);
divSpace = $("#bodies").innerWidth() - $(this).width();
}
});
return cycleNum;
}
html:
<img class="associate" src="IMG/spare.png" alt=""/>
<img class="associate" src="IMG/bcs_professional.jpg" alt="BCS Professional Member"/>
<img class="associate" src="IMG/climate_savers.jpg" alt="Climate Savers Smart Computing"/>
<img class="associate" src="IMG/code_of_conduct.jpg" alt="Data Centres Code Of Conduct Endorser"/>
<img class="associate" src="IMG/spare.gif" alt=""/>
<img class="associate" src="IMG/enistic.gif" alt="Enistic"/>
<img class="associate" src="IMG/greentrac_authorised.png" alt="Greentrac Authorised Reseller"/>
<img class="associate" src="IMG/very_pc.jpg" alt="Very PC Approved"/>
<img class="associate" src="IMG/spare.jpg" alt=""/>
css:
#bodies img.associate{
float: left;
max-width: 120px;
max-height: 80px;
display:none;
}
The issue is that your fadeOut function's callback is being executed even before all elements in the current cycle are faded out. Here's a modified version of your function that works as expected:
function cycleAssociates(){
var cycle = 0;
var recursiveCycling = function(cycle, totalCycles){
var currentAssociate = ".cycle" + cycle;
var n = $(currentAssociate).length; //How many images in current cycle?
$(currentAssociate).each(function() {
$(this).delay(100).fadeIn(1000).delay(3000).fadeOut(1000, function() {
n --;
if(n <= 0) { //current cycle done?
cycle++;
if(cycle > totalCycles){
cycle = 0;
}
recursiveCycling(cycle, totalCycles);
}
});
});
};
recursiveCycling(cycle, totalCycles);
}
To fix the issues that come up on window resize, try replacing your current $(window).resize handler with this:
$(function(){
$(window).resize(function() {
parallelNavbar();
$(".associate").stop(); //if there are any animations, stop 'em
$(".associate").hide(); //hide all associates
totalCycles = assignCycleNumbers(); //update the assignment
cycleAssociates(); //let's get cyclin' again!
});
});
Although I think you have some issues with scrolling. This should resolve the main cycling problem, though -- so I hope that helped!

Categories

Resources