How make a fade slideshow loop? - javascript

I am using javascript to change my css class background image every few seconds. It is working great the problem is it just stops after it shows the last image. Can anyone show me what to add to this code so that it will continuously loop itself?
$(window).load(function() {
$(document).ready(function() {
setInterval(fadeDivs, 5000); //call it every 2 seconds
function fadeDivs() {
var visibleDiv = $('.bckgnd:visible:first'); //find first visible div
visibleDiv.fadeOut(400, function() { //fade out first visible div
var allDivs = visibleDiv.parent().children(); //all divs to fade out / in
var nextDivIndex = (allDivs.index(visibleDiv) + 1) % allDivs.length; //index of next div that comes after visible div
var nextdiv = allDivs.eq(nextDivIndex); //find the next visible div
var lastDiv = $('.backgnd3');
var firstDiv = $('.backgnd1');
if (currentDiv != lastDiv) {
var nextdiv = allDivs.eq(nextDivIndex); //find the next visible div
} else {
var nextdiv = firstDiv; //the next div will be the first div, resulting in a loop
}
nextdiv.fadeIn(400); //fade it in
});
};
});
});
.backgnd1 {
width: 100%;
height: 452px;
background: url ('http://quaaoutlodge.com/sites/all/themes/marinelli/img/backgrounds/backgnd1.jpg');
background-size: cover;
background-repeat: no-repeat;
background-color: #000;
}
.backgnd2 {
width: 100%;
height: 452px;
background-image: url ('http://quaaoutlodge.com/sites/all/themes/marinelli/img/backgrounds/the_lodge.jpg');
background-size: cover;
background-repeat: no-repeat;
background-color: #000;
}
.backgnd3 {
width: 100%;
height: 452px;
background-image: url('http://quaaoutlodge.com/sites/all/themes/marinelli/img/backgrounds/getting_here.jpg');
background-size: cover;
background-repeat: no-repeat;
background-color: #000;
}
.index_roof_background {
background-color: #000;
width: 1600px;
height: 452px;
margin: 0px;
padding-top: 0px;
margin-left: auto;
margin-right: auto;
}
<div class="index_roof_background">
<div style="position:absolute; z-index: 2;display:block; background-color:#000;" class="bckgnd backgnd1"></div>
<div style="position:absolute; z-index: 2;display:none; background-color:#000;" class="bckgnd backgnd2"></div>
<div style="position:absolute; z-index: 2;display:none; background-color:#000;" class="bckgnd backgnd3"></div>
</div>

A better approach:
You don't need all those backgnd2 classes since you have only those DIVs inside a common parent.
Don't use inline styles! Use your stylesheet.
Don't use fixed width (px). Use % for responsive design.
2000*1331px images are
not suited for the web. Specially not for mobile devices. Care about
your user's bandwidth. When setting a background-image to cover you
don't need to worry about it being repeated.
Make your JS more flexible to element's indexes, count your elements using length.
Create a "current index counter", iterate over it increment it and
resetting using % (reminder).
For a better UX, allow the user to pause on hover.
Here's an eample:
jQuery(function($) { // DOM ready. $ alias in scope.
$('.gallery').each(function() {
var $gal = $(this),
$sli = $gal.find(">*"),
tot = $sli.length,
c = 0,
itv = null;
$sli.hide().eq(c).show(); // Hide all but first slide
function anim() {
c = ++c % tot; // increment/reset counter
$sli.fadeOut().eq(c).stop().fadeIn();
}
function play() {
itv = setInterval(anim, 3000);
}
function pause() {
clearInterval(itv);
}
$gal.hover(pause, play); // Pause on hover
play(); // Start loop
});
});
.gallery {
position: relative;
height: 200px;
}
.gallery>* {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: none 50%;
background-size: cover;
}
<div class="gallery">
<div style="background-image:url(http://placehold.it/800x600/0bf?text=1)"></div>
<div style="background-image:url(http://placehold.it/800x600/f0b?text=2)"></div>
<div style="background-image:url(http://placehold.it/800x600/0fb?text=3)"></div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

First put the firstDiv, lastDiv in their own variables.
Then you will need something like this
if (currentDiv != lastDiv) {
var nextdiv = allDivs.eq(nextDivIndex); //find the next visible div
} else {
var nextdiv = firstDiv; //the next div will be the first div, resulting in a loop
}
nextdiv.fadeIn(400); //fade it in
Tell me if you need more help.

You need to use 2 timeouts to make it loop. A timeout only fires once. The FadeOutDivs function counts down, each time setting a timeout to call itself. Then at zero it fades sets a timeout the call fadeInDivs which start the whole cycle over.
I've got this running on codepen.
$(document).ready(function () {
var interval = 2000;
var fadeDuration = 400;
var allImages = $('.bckgnd');
var count = allImages.length - 1;
var imageCount = allImages.length;
setTimeout(fadeOutDivs, interval);
function fadeOutDivs() {
allImages.eq(count).fadeOut(fadeDuration);
console.log(count);
if (count > 1) {
count--;
setTimeout(fadeOutDivs, interval);
} else {
count = allImages.length - 1;
setTimeout(fadeInDivs, interval)
}
}
function fadeInDivs() {
allImages.fadeIn(fadeDuration);
setTimeout(fadeOutDivs, interval);
}
});

Related

How to get the same function to execute for each element of the same class one after the other?

I have one outer box and an inner box and there are some identical boxes with the same class names inside the second box. I want all of these boxes to appear one after the other with this fade-in effect. So far I have done it for the outer and inner div, and I wanted to use the same function for all the identical boxes inside. I tried to do the same for outer and inner div since they too just need the exact same function. But I wasn't successful. Here is my code :
html:
<div class="div1">
<div class="div2">
<div class="div3"></div>
<div class="div3"></div>
<div class="div3"></div>
<div class="div3"></div>
<div class="div3"></div>
</div>
</div>
javascript:
let div1 = document.getElementsByClassName("div1")[0];
let div2 = document.getElementsByClassName("div2")[0];
let div3 = document.getElementsByClassName("div3");
div1.style.visibility = "hidden";
div2.style.visibility = "hidden";
function first() {
return new Promise(function (resolve, reject) {
setTimeout(function () {
div1.style.animation = "fadein 5s";
div1.style.visibility = "visible";
resolve("div1 worked!");
}, 1000);
});
}
function second() {
return new Promise(function (resolve, reject) {
setTimeout(function () {
div2.style.animation = "fadein 5s";
div2.style.visibility = "visible";
resolve("div2 worked!");
}, 1000);
});
}
function abc(element) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
element.style.animation = "fadein 5s";
element.style.visibility = "visible";
resolve("third");
}, 1000);
});
}
first()
.then(second)
.then((div3) => {
div3.forEach((element) => {
abc(element);
});
});
css
.div1 {
width: 400px;
height: 500px;
background-color: yellow;
}
.div2 {
width: 350px;
height: 400px;
background-color: green;
}
.div3 {
width: 300px;
height: 50px;
background-color: grey;
margin: 10px;
}
#keyframes fadein {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
The first two works and I don't know how I can reuse the function for the remaining div3 class divs. I tried to reuse the function for the first two as well, but it didn't work and ended up writing same functions again and again. I want to call function abc for each element in div3 and only execute the next one after the first element is done - like how it executes for first and second but using the same function. Not sure how to do that and I'm stuck. Here is a codepen link. As of now all the div3 divs appear together with the second div.
You can use loops and animation-delay to apply the animation as per your need. The following code will work for this case. Code is full with comments to explain what is happening at each point. I have also slightly modified the css so that we don't get any weird blinking effect while executing the code.
//Declare all the classes -
let divs = ["div1", "div2", "div3"];
//Initiate a delay for each iteration
let delay = 0;
//Run a loop for each class
for(let i = 0; i<divs.length; i++){
//Get the element
let div = document.getElementsByClassName(divs[i]);
//Run a loop for element with the class
//(We only have one div with the classes div1 and div2. So it will run one time for them.
//We have 5 divs with div3 class. It will run 5 times in that case
for(let j = 0; j<div.length; j++){
//Get the individual element and add animation with delay
//The delay will also ensure that the animation starts only when the previous element has finished the animation
div[j].style.animation = `fadein 5s ${delay}s forwards` ;
div[j].classList.add("show");
//Increase delay with every iteration
delay+=5;
}
}
div {
visibility: hidden;
}
.div1 {
width: 400px;
height: 500px;
background-color: yellow;
}
.div2 {
width: 350px;
height: 400px;
background-color: green;
}
.div3 {
width: 300px;
height: 50px;
background-color: grey;
margin: 10px;
}
.show {
opacity: 0;
visibility: visible;
}
#keyframes fadein {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
<div class="div1">
<div class="div2">
<div class="div3">1</div>
<div class="div3">2</div>
<div class="div3">3</div>
<div class="div3">4</div>
<div class="div3">5</div>
</div>
</div>
The script may seem very long but it is only 10 lines long without the comments. This will also work if you increase or decrease the number of divs
This is one way to solve the problem using setInterval for executing a piece of code every x seconds.
The function fadeIn takes an array of elements that will be faded in by adding the class "show" (se details for "show" in CSS-code below). This will animate the given elements.
The function start collects the elements that will be faded and fades in the first collection of element, then countinuesly fades in the rest of the elements in the array "elements" every 3 seconds.
function fadeIn(el) {
// For every element in the collection
for (var i = 0; i < el.length; i++) {
// Add the class "show"
el[i].classList.add('show');
}
}
function start() {
/*
Collects all the elements that we want to fadeIn in order. First collection of elements will be animated firstly, second collection of elements will be animated secondly, etc.
*/
var elements = [];
elements.push(document.getElementsByClassName("div1"));
elements.push(document.getElementsByClassName("div2"));
elements.push(document.getElementsByClassName("div3"));
// Show the first collection of elements
fadeIn(elements[0]);
// Show the rest of the element collections in array "elements"
var i = 1;
fadeInInterval = setInterval(function() {
fadeIn(elements[i]);
// If there is no more collections to fade in, end the setInterval
if (i == elements.length-1) {
clearInterval(fadeInInterval)
}
i++
}, 3000) // Every 3 seconds
}
start();
div {
visibility: hidden;
}
.div1 {
width: 400px;
height: 500px;
background-color: yellow;
}
.div2 {
width: 350px;
height: 400px;
background-color: green;
}
.div3 {
width: 300px;
height: 50px;
background-color: grey;
margin: 10px;
}
.show {
animation: fadein 5s;
visibility: visible;
}
#keyframes fadein {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
<div class="div1">
<div class="div2">
<div class="div3"></div>
<div class="div3"></div>
<div class="div3"></div>
<div class="div3"></div>
<div class="div3"></div>
</div>
</div>

use jQuery setInterval to decreases the width of element but from only one side (left or right )

here are my codes for decreasing the width of an selected element(class = "life_bar"), but as my attached pictures show, I want it to decrease its width from left or right( let's do left as example), but it always goes from both side, what should I do?
here are jQuery codes
$(function () {
var timmer;
gocount();
function gocount(){
timmer = setInterval(function () {
var life_bar_width = $(".life_bar").width();
life_bar_width -= 100;
$(".life_bar").css( {width: life_bar_width,
left: '-50px'})
},1000);
}
});
here are css codes
.life_bar{
width: 500px;
height: 10px;
background: crimson;
margin: 100px auto;
}
here are html codes
<body>
<div class="life_bar"></div>
</body>
using translate negative on X every interval tick:
$(function () {
var timmer;
gocount();
let counter = 1
function gocount(){
timmer = setInterval(function () {
var life_bar_width = $(".life_bar").width();
life_bar_width -= 100;
$(".life_bar").css({
width: life_bar_width,
left: '-50px',
transform: `translate(${-50*counter}px)`
})
counter++
},1000);
}
});
.life_bar{
width: 500px;
height: 10px;
background: crimson;
margin: 100px auto;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="life_bar"></div>

resizing images for slideshow

I'm trying to resize my images for a slideshow. When I plug them into an array and code them into a slideshow, the cropping is kind of off. I tried using object-position in CSS but that changes all the images in one shot and what works for one image doensn't necessarily work for others.
Here is the HTML:
<container class="main-img-cont">
<img class="main-img" alt="">
</container>
Here is the CSS:
.main-img-cont {
width: 100%;
height: 650px;
display: flex;
img {
width: 100%;
object-fit: cover;
object-position: 0 30%;
} // closes img
} // closes .main-img
Javascript:
window.onload = () => {
var mainImg = document.querySelector('.main-img');
let slideshow = [
'../img/jevon_cochran_pelourinho.jpg',
'../img/me_in_Pernambues.JPG',
'../img/quibdo_boat_ride.jpg'
];
var index = 0;
var interval = 1000;
function slide() {
mainImg.src = slideshow[index];
index++;
if (index >= slideshow.length) {
index = 0;
}
}
setInterval(slide, interval);
}

How can I fade in images on page load one after the other?

I have created the following code that on page load adds opacity: 1 to all divs on the page. In doing so all the images are seen on pageload, but I want each to fade in slowly and after one has completely loaded/is visible I want the 2nd image to load exactly the same then followed by the third.
How can I accomplish this via the code below; what needs to be changed/added? Please note it must use pure Javascript; no CSS3 or jQuery as the proprietary framework I'm working in requires pure JS.
var imageOne = document.getElementById('imageOne');
var imageTwo = document.getElementById('imageTwo');
var imageThr = document.getElementById('imageThr');
function fadeIn() {
imageOne.style.opacity = '1';
imageTwo.style.opacity = '1';
imageThr.style.opacity = '1';
}
#imageOne {
background: url('https://thingiverse-production-new.s3.amazonaws.com/renders/16/04/2d/b5/ed/smiley_face_thumb_small.jpg');
background-repeat: no-repeat;
width: 50px;
height: 50px;
margin-right: 20px;
float: left;
opacity: 0;
}
#imageTwo {
background: url('http://www.mpaart.org/wp-content/uploads/2015/07/twitter-logo-round-50x50.png');
background-repeat: no-repeat;
width: 50px;
height: 50px;
margin-right: 20px;
float: left;
opacity: 0;
}
#imageThr {
background: url('http://orig08.deviantart.net/24c1/f/2009/238/d/8/small_50x50__png_clock_pic_by_counter_countdown_ip.png');
background-repeat: no-repeat;
width: 50px;
height: 50px;
float: left;
opacity: 0;
}
<body onload="fadeIn()">
<div id="wrapper">
<div id="imageOne"></div>
<div id="imageTwo"></div>
<div id="imageThr"></div>
</div>
</body>
You can use CSS transitions, which is faster and won't require jQuery.
.fadeIn {
transition: opacity 1.25s;
}
Add the class fadeIn to your image elements, and now it'll fade.
To make it fade one after the other, use JavaScript timers to space out setting opacity to 1. Example:
var elements = [ /* Image elements to fade */ ];
for (var i = 0; i < elements.length; i++) {
setTimeout(function() {
elements[i].style.opacity = 1;
}, 1250 * i);
}
You can use callback function of fadeIn to load other image
function fadeIn() {
$("#imageOne").fadeIn("fast",function(){
$("#imageTwo").fadeIn("fast", function(){
$("#imageThr").fadeIn("fast");
});
});
}
This is what I came up with so far. Unfortunately, I haven't figure how to have them fade in, as the below just makes them appear one after the other. Though it's pure Javascript.
Any suggestions?
var imageOne = document.getElementById('imageOne');
var imageTwo = document.getElementById('imageTwo');
var imageThr = document.getElementById('imageThr');
function fadeIn(element) {
element.style.opacity += 0.9;
if (element.style.opacity < 1) {
setTimeout(function() {
fadeIn(element);
}, 100);
}
}
setTimeout(function() {
fadeIn(document.getElementById("imageOne"));
}, 1000);
setTimeout(function() {
fadeIn(document.getElementById("imageTwo"));
}, 5000);
setTimeout(function() {
fadeIn(document.getElementById("imageThr"));
}, 10000);

jquery slider responsive problems

I am a beginner with jQuery and I was trying to make an slider responsive and is working but I have some bugs that I want to fix, first of all when is passing to the next picture some times it just turn white and it does not working any more, and second some times it start to go faster and faster.
Any suggestions?
.mascara
{ width: 100%; height: 100%;
overflow: hidden;
}
.carrusel{ position: relative; width: 100%; height: 100%; }
.carrusel li{ width:25%; height: 100%; float: left; background-repeat: no-repeat; background-position: center; background-size: cover; }
<script src="jquery-2.0.3.min.js"></script>
<script>
var cantidadFotos = $('.carrusel li').size();
var incremento = $('.mascara').width();
var limite = (cantidadFotos-1) * incremento;
var velocidad = 550;
$('.carrusel').css('width', (cantidadFotos*100)+"%");
$('.carrusel li').css('width', incremento+"px");
var posX = 0;
resize();
function resize()
{
$(window).resize(function () {
incremento = $('.mascara').width();
$('.carrusel li').css('width', incremento+"px");
posX = -(incremento * imagenes);
$('.carrusel').css('left', posX+"px");
});
setInterval(function(){ nextFoto(); }, 3000);}
var imagenes = 0;
function nextFoto(){
imagenes++;
posX+= -incremento;
if (posX<-limite){
posX=0;
imagenes = 0;
$('.carrusel').css({ left: posX });
}
$('.carrusel').animate({ left: posX},350);
// $('.carrusel').css({ left: posX});
return false;
}
</script>
If you want to remove the blank page when sliding, change to this:
In .carrusel
Change:
position: relative;
To:
position: absolute;
And to make it faster, change:
setInterval(function () {
nextFoto();
}, 3000);
To
setInterval(function () {
nextFoto();
}, 1000);
Change according to your needs to make it faster!
Demo

Categories

Resources