Animate background images within one data attribute - javascript

I try to create a nice animation between these background images urls, which are live in one data attribute (first image loads immediately, after 5 second the next images, after the next etc. After last one it starts from the beginning).
<div data-images="/media/jtjglhbb/main-bg-01.jpg,/media/u2bitolk/main-bg-02.jpg,/media/iasbuo5n/main-bg-04.jpg,/media/f00jm2va/main-bg-03.jpg,"></div>
var $dataImages = $('[data-images]');
var imagesList = $dataImages.data('images').split(',');
$.each(imagesList, function (index, value) {
setTimeout(function () {
$dataImages.stop().animate({ opacity: 0 }, 1000, function () {
$(this).css({ 'background-image': 'url(' + imagesList[index] + ')' })
.animate({ opacity: 1 }, { duration: 1000 });
});
}, 5000);
});
But it doesn't set up the first image, it only starts after 5 second and it runs altogether not one by one with 5 sec delay.
Obviously the logic is wrong, some help would be great.

Try like below. It should work.
image count will required to get mode value to start from beginning again.
index will hold index of image to show in background
changeImage function will be called recursively from inside so it will continuously update background.
use index = (index + 1) % imageCount; so index will start from 0 again from last index.
var $dataImages = $('[data-images]');
var imagesList = $dataImages.data('images').split(',');
// image count will required to get mode value to start from beginning again.
var imageCount = imagesList.length - 1;
// index of image to show in background
var index = 0;
// function will be called recursively from inside so it will continuously update background.
function changeImage() {
$dataImages.stop().animate({
opacity: 0
}, 1000, function() {
$(this).css({
'background-image': 'url(' + imagesList[index] + ')'
})
.animate({
opacity: 1
}, {
duration: 1000
});
});
// update index to next image url
index = (index + 1) % imageCount;
// declare timeout to call function after required time
setTimeout(changeImage, 5000);
}
changeImage();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script>
<div style="height: 150px;" data-images="https://www.w3schools.com/howto/img_nature_wide.jpg,https://www.w3schools.com/howto/img_snow_wide.jpg,https://www.w3schools.com/howto/img_lights_wide.jpg,https://www.w3schools.com/howto/img_mountains_wide.jpg"></div>

Related

Javascript array is not recognizing called variable

function slideShow() {
var pageSplash = document.getElementById('splash');
var image = ["pic1.jpg", "pic2.jpg", "pic3.jpg", "pic4.jpg"];
var i = 0;
while (i <= image.length) {
if (i > image.length) {
i = 0;
}
i += 1;
pageSplash.innerHTML = '<img id ="splashImage" src="file:///C:/JonTFS/JonGrochCoding/Javascript%20Practical%20Test/' + image[i] + '">';
setTimeout('slideShow', 5000);
}
}
I'm unsure why my i variable is not being recognized as the i variable from the rest of the function, so when ever I try to run my while loop it get's an error message saying that it's undefined.
I think you want setInterval instead of setTimeout, and you want you be careful that you increment i after you you update innerHTML.
function slideShow() {
var pageSplash = document.getElementById('splash');
var image = ["pic1.jpg", "pic2.jpg", "pic3.jpg", "pic4.jpg"];
var i = 0;
setInterval(function () {
if (i === image.length) {
i = 0;
}
pageSplash.innerHTML = '<img id ="splashImage" src="file:///C:/JonTFS/JonGrochCoding/Javascript%20Practical%20Test/' + image[i] + '">';
i++;
}, 5000)
}
slideShow();
You don't need a while loop. You don't need to reset i. You don't need to set innerHTML.
Click Run code snippet... to see how this works. More explanation below the code
function slideShow(elem, images, delay, i) {
elem.src = images[i % images.length];
setTimeout(function() {
slideShow(elem, images, delay, i+1);
}, delay);
}
// setup slideshow 1
slideShow(
document.querySelector('#slideshow1 img'), // target element
[ // array of images
'http://lorempixel.com/100/100/animals/1/',
'http://lorempixel.com/100/100/animals/2/',
'http://lorempixel.com/100/100/animals/3/',
'http://lorempixel.com/100/100/animals/4/',
'http://lorempixel.com/100/100/animals/5/',
'http://lorempixel.com/100/100/animals/6/'
],
1000, // 1000 ms delay (1 second)
1 // start on slide index 1
);
// setup slideshow 2
slideShow(
document.querySelector('#slideshow2 img'), // target element
[ // array of images
'http://lorempixel.com/100/100/nature/1/',
'http://lorempixel.com/100/100/nature/2/',
'http://lorempixel.com/100/100/nature/3/',
'http://lorempixel.com/100/100/nature/4/',
'http://lorempixel.com/100/100/nature/5/',
'http://lorempixel.com/100/100/nature/6/'
],
500, // 500 ms delay
1 // start on slide 1
);
#slideshow1, #slideshow2 {
width: 150px;
display: inline-block;
}
<div id="slideshow1">
<h2>Animals</h2>
<p>(1000 ms delay)</p>
<!-- initial image -->
<img src="http://lorempixel.com/100/100/animals/1/">
</div>
<div id="slideshow2">
<h2>Nature</h2>
<p>(500 ms delay)</p>
<!-- initial image -->
<img src="http://lorempixel.com/100/100/sports/1/">
</div>
This is a huge improvement because your slideshow function is reusable. It means you can use the same function for any slideshow you want. You can even run multiple slideshows on the same page, as I have demonstrated here.
As others have pointed out, the while loop is unnecessary and, as I pointed out, the setTimout was incorrectly written. The following simplifies your code significantly:
var i = 0;
function slideShow() {
var pageSplash = document.getElementById('splash');
var imageArray = ["pic1.jpg", "pic2.jpg", "pic3.jpg", "pic4.jpg"];
if(i < imageArray.length) {
pageSplash.innerHTML = '<img title='+ imageArray[i] + ' id ="splashImage" src="file:///C:/JonTFS/JonGrochCoding/Javascript%20Practical%20Test/' + imageArray[i] + '">';
}
i++;
}
setInterval(slideShow, 2000);
See: https://jsfiddle.net/dauvc4j6/8/ for a working version.
setTimeout calls the function again so you're re-initializing i to 0 every time you call it. Since you can use setTimeout to call the function recursively you don't need the while loop. Pull i out of the function altogether and make it a global variable.
//i should be global
var i = 0;
function slideShow() {
var pageSplash = document.getElementById('splash');
var image = ["pic1.jpg", "pic2.jpg", "pic3.jpg", "pic4.jpg"];
if (i >= image.length) {
i = 0;
}
i += 1;
pageSplash.innerHTML = '<img id ="splashImage" src="file:///C:/JonTFS/JonGrochCoding/Javascript%20Practical%20Test/' + image[i] + '">';
//set timeout is going to call slideShow again so if it's in the function it will call recursively, if you wanted to stop after a certain point you could nest setTimeout in an if
setTimeout(slideShow, 5000);
}
//you need to initially call the function
slideShow();

JQuery: How to change image after time with fadeIn?

I want to change an image automatically after 2000ms. The image should fade in.
My HTML:
<div class="nile-slider large-12 column">
<img alt="landing page 3" src="assets/Startseite/Slider/Slider_2.jpg">
</div>
My JS:
// change header image after 2 seconds
var images = ['Slider_1.jpg','Slider_2.jpg','Slider_3.jpg', 'Slider_4.jpg'],
index = 0, // starting index
maxImages = images.length - 1;
var timer = setInterval(function() {
var currentImage = images[index];
index = (index == maxImages) ? 0 : ++index;
$('.nile-slider img').attr('src','assets/Startseite/Slider/'+currentImage).fadeIn('slow');
}, 2000);
With this code the images changes but it does not fade in. How can I force the images to fade in (and even fade out)?
You can combine fadeOut and fadeIn() using fadeOut callback function, to achieve this.
// change header image after 2 seconds
var images = ['Slider_1.jpg','Slider_2.jpg','Slider_3.jpg', 'Slider_4.jpg'],
index = 0, // starting index
maxImages = images.length - 1;
var timer = setInterval(function() {
var currentImage = images[index];
index = (index == maxImages) ? 0 : ++index;
$('.nile-slider img').fadeOut(200, function() {
$('.nile-slider img').attr("src", 'assets/Startseite/Slider/'+currentImage);
$('.nile-slider img').fadeIn(200);
});
}, 2000);
Providing the new source as callback of fadeOut may do the trick:
$('.nile-slider img')
.fadeOut('fast',
function () {
$('.nile-slider img')
.attr('src','assets/Startseite/Slider/'+currentImage)
.fadeIn('slow');
}
);

How to get around javascript timeout of 0

Here is a fiddle: http://jsfiddle.net/hB7gY/16/
I have the following code which controls a slideshow with four quadrants. The idea is to rotate through the slideshow and dynamically change the slides based upon a predefined time frame. For instance, many times a slide has a value of 0, which means instantly load the next slide in the series.
The problem is that when using fadeIn() or animate(), they take longer than the timeout of 0. I've tried incrementing my counters when this happens, but that doesn't work.
EDIT: I think I may not have been clear in my question, but the goal is to be able to load the next image instantly, but still maintain the animation effect on the previous image, so essentially it will appear as if both images are animating simultaneously.
var slide_array = <?php echo json_encode( $slides ); ?>;
jQuery(document).ready(function(){
var c =0;
var slide = 0;
var counter = 1000;
for (var i=0;i<slide_array.length;i++){
jQuery('#slide_'+i).attr('src', slide_array[i]["url"]);
}
var intFn = function(){
clearTimeout(interval);
c++;
slide++;
if (slide == slide_array.length) { slide = 0; }
if (c == 4){ c = 0; }
jQuery('#slide_'+c).attr('src',slide_array[slide]['url']).animate({
opacity: 0.5
}, 100, function() {
jQuery('#slide_'+c).attr('src',slide_array[slide]['url']).animate({
opacity: 1
}, 100);
});
counter = slide_array[slide]['duration'] * 1000;
//if (counter < 1000 ) { counter = 400; }
interval = setTimeout(intFn, counter);
}
var interval = setTimeout(intFn, 2500);
});

How do you create a loop of image animations in javascript

I have a series of images I want to display one after the other. The kicker is they need to have a set time between each image displaying.
here is my code
setTimeout(function() {
images[0].transitionTo({
opacity: 1,
duration: 0
});
}, 200);
setTimeout(function() {
images[1].transitionTo({
opacity: 1,
duration: 0
});
}, 400);
setTimeout(function() {
images[2].transitionTo({
opacity: 1,
duration: 0
});
}, 600);
..etc (I have about 35 images)
How can express the same thing in a loop? I'm using the KinetciJS library
I tried using set interval or set timeout but the loop keeps iterating while the timer waits and the array goes out of bounds.
Thanks for any help you can give.
Like this:
/**
* Loop images every second.
*/
(function() loopImages() {
var interval = 1000,
numOfImage = 35,
currImage = 1;
function loop() {
if (currImage > numOfImage) {
currImage = 1;
}
// display current image in your way.
}
setInterval(loop, interval);
})()
try this...
var numberOfImages = 35;
for(var i = 0; i < numberOfImages; i++) {
setTimeout(function() {
images[i].transitionTo({
opacity: 1,
duration: 2
});
}, (200 * (i + 1)) );
}
Hope this helps.
Another option is to use an incrementor instead of a traditional loop.
Knowing that your image collection is an array, I used the 'currentIteration' variable to
keep track of current index position, and initiated by calling the initAnimation() function. This keeps everything pretty generic and should work regardless of the number of images.
This would allow you to control when the next image animation method is called without being confined to a loop, and could be extended to only be called once the transition is complete if a duration was assigned.
var images = ['pic1','pic2','pic3','pic4','pic5'];
var currentIteration = 0;
function initAnimation(){
animate();
}
function animate(){
if(currentIteration < image.length){
window.setTimeout(
function(){transition()}
,800)
}
}
function transition(){
images[currentIteration].transitionTo({
opacity: 1,
duration: 0
});
currentIteration++;
animate();
}
Something like this might do the trick (please note this is untested)
var images; // your images
var idx = 0; //start index
function transition(){
if(idx < images.length){
var image = images[i];
image.transitionTo({
opacity: 1,
duration: 0
});
idx++;
}else{
window.clearInterval(intVal);
}
}
var intVal = window.setInterval(transition,200);

jQuery called with setInterval isn't animating on first interval

I have two images stacked. With setInterval(), the top one fades away, exposing the second. Then the top image switches to the bottom's src while invisible, and becomes opaque again. The second image changes to the next image and waits for the setInterval() to fade the top image and do it all over again.
It all works great, except the first time around; There's no fade. What am I not seeing?
This happens on all firefox and chrome and I assume all others.
HTML
<script type="text/javascript">
setInterval('swapImage()', 5000);
var galleryCount = 3;
</script>
...
<img id="image" src="images/gallery/01.jpg" />
<img id="imagenext" src="images/gallery/02.jpg" />
Javascript
function swapImage(imageToFadeID)
{
$("#image").animate
(
{ "opacity": "0" },
"slow",
"linear",
changeImage()
);
};
var i = 1;
function changeImage()
//counter +1
{
i = i + 1;
//add "0" to image number "j" if less than 10.
if (i < 10)
{
var j = "0" + i;
}
else
{
j = i;
}
//change top image to match bottom
var topImage = document.getElementById("imagenext").src;
document.getElementById("image").src = topImage;
//make top image reappear
document.getElementById("image").style.opacity = '1';
//change out bottom image to next
var btmImage = "images/gallery/" + j + ".jpg";
document.getElementById("imagenext").src = btmImage;
//reset counter if at end
if (i > galleryCount - 1)
{
i = 0;
}
}
I looks like you're invoking changeImage instead of passing it as a callback to animate:
Wrong:
function swapImage(imageToFadeID)
{
$("#image").animate
(
{ "opacity": "0" },
"slow",
"linear",
changeImage() // <--- !!! Remove the parentheses from this line!
);
};
Right:
function swapImage(imageToFadeID)
{
$("#image").animate
(
{ "opacity": "0" },
"slow",
"linear",
changeImage
);
};

Categories

Resources