How do you create a loop of image animations in javascript - 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);

Related

Animate background images within one data attribute

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>

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();

slider won't work properly

I am trying to animate my list item towards right but it animate all item towards right at once but I want it to be one after another ..here is my jQuery
var I,
total_slide = $('#slide li').length,
slide = $('#slide li');
function run() {
for (I = 1; I <= total_slide; I++) {
var total = total_slide - I
$(slide).eq(total).animate({
left: '700px'
}, 4000);
}
}
run()
You have to use setTimeout function to make pauses between animations:
function run(){
var timeout = 0, delay = 4000;
$("#slide li").each(function(){
var $li = $(this);
setTimeout(function(){
$li.animate({ left: 700 }, delay);
}, timeout);
timeout += delay;
});
}
Example
Also I would recommend to use CSS-animations whenever it's possible:
Example with CSS-animations

Shift in course each of div

I'm trying to animate the margin-left of each div one after another:
var array = ['#lazer', '#ergonomic', '#myagkaya-chast', '#krepkost'];
var i = 0;
while (i < array.length) {
array[i].animate({
marginLeft: '40px'
}, 1000, function () {
i++;
});
}
FIDDLE
You need to remove the i++ from the animate callback since it is asynchronous, also rather then extend the animate effect use jQuery.delay() to offset the start time.
var array = ['#lazer', '#ergonomic', '#myagkaya-chast', '#krepkost'];
var i = 0;
var delay = 100;
while (i < array.length) {
$(array[i]).delay(delay * i).animate({
marginLeft: '40px'
}, "linear");
i++;
}
Demo
You forgot your jQuery object wrapper $(array[i]). Also, if you're not going to use a for loop like shown, put your i variable outside the animate() function.
var array = ['#lazer', '#ergonomic', '#myagkaya-chast', '#krepkost'];
for (var i = 0; i < array.length; i++) {
$(array[i]).animate({
marginLeft: '40px'
}, 1000);
}
JSFiddle

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);
});

Categories

Resources