Adding delay to DIV animation - javascript

I'm trying to create div boxes step by step and animate them for several times when a button is pressed. I have a running code, and everything is going well. It goes right to the endhost, then it goes left again to its original place. This is mainly what I do, and also the demo is found here: http://jsfiddle.net/54hqm/3/
Now I want to happen after each click, is basically to move each DIV one after another, with a delay, instead of moving the whole stack of DIVs at once. I don't exactly know what to do. Can anyone help me with that?
$(document).ready(function () {
var count = 0;
var items = 0;
var packetNumber = 0;
var speed = 0;
$("button").click(function () {
if (count < 4) {
items = items + 1;
count++;
} else {
items = items * 2;
}
speed = $("#speed").val();
createDivs(items);
animateDivs();
});
function createDivs(divs) {
packetNumber = 1;
var left = 60;
for (var i = 0; i < divs; i++) {
var div = $("<div class='t'></div>");
div.appendTo(".packets");
$("<font class='span'>" + packetNumber + "</font>").appendTo(div);
packetNumber++;
div.css("left",left+"px");
div.hide();
left += 20;
}
}
function animateDivs() {
$(".t").each(function () {
var packet = $(this);
packet.show();
packet.animate({
left: '+=230px'
}, speed);
packet.animate({
left: '+=230px'
}, speed);
packet.animate({
top: '+=20px',
backgroundColor: "#f09090",
text: '12'
}, speed / 4, "swing", function () {
$('.span').fadeOut(100, function () {
$(this).text(function () {
return 'a' + $(this).text().replace('a', '');
}).fadeIn(100);
});
});
packet.delay(1000).animate({left:'-=230px'}, speed);
packet.animate({left:'-=230px'}, speed);
}).promise().done(function(){
$(".packets").empty();});
}
});

You can make this with 2 small modifications:
In your each() function, add the index parameter to know the index of the currently animating packet:
$(".t").each(function (index) {
Before your animate calls, insert a packet.delay() with a delay increasing with every item:
packet.delay(index * 250);
I updated your fiddle to show results.
Update: I made a second version based on your comment.

Related

jQuery animate array skip to last

I am trying to animate an array of images using Jquery. When I have one element in the array it works fine but when I have more then one element it just animates the last element of the array.
I set the src of the img tag and move it to the right. The moveRight function move the image to the right and call moveLeft to move it to the left. The moveLeft function moves the image to the left and fade it.
$.each(imageArray, function (i, val) {
$("#b").attr("src", imageArray[i].src);
moveRight();
}
function moveRight(){
$("#b").animate({left: "+=500"}, 2000, moveLeft)
}
function moveLeft(){
$("#b").animate({left: "-=500"}, 2000,fade)
}
Is there a way each image can be moved right and left / or just left or right instead of having the last one moving only. I am trying to figure out what is wrong with my code.
I think the best thing you can do is to use a recursive method. Here is an example (check jsFiddle):
var MyApp = {
Items: {
Elements: $('div'),
Loaded: 0
},
Start: function(){
if( this.Items.Elements.length == this.Items.Loaded ) return; // return.. or play a sound, then return to stop iterations
this.Items.Elements.eq(this.Items.Loaded).animate({ left: '50%' }, {
duration: 1000,
complete: function(){
MyApp.Items.Loaded++;
MyApp.Start();
}
});
}
};
$(function(){
MyApp.Start();
});
It's an example but you can do it easily by this way.
How about this variant: http://jsbin.com/xezetuboye/1/edit?html,js,output ?
var arr = [
'http://e404.pw/pictures/evernote-logo.png',
'http://e404.pw/pictures/font-face.png',
'http://e404.pw/pictures/html-coder.jpg'
];
var count = 0;
function setImg(){
if(arr.length <= count){ return; }
$("#b").attr("src", arr[count]);
moveRight();
count++;
}
function moveRight(){
$("#b").animate({left: "+=500"}, 2000, moveLeft);
}
function moveLeft(){
$("#b").animate({left: "-=500"}, 2000, setImg);
}
setImg();
Try utilizing .queue(). Note, if changing src of same img element , would have to wait until each image loaded.
var imageArray = [
"http://lorempixel.com/100/100/cats",
"http://lorempixel.com/100/100/animals",
"http://lorempixel.com/100/100/technics",
"http://lorempixel.com/100/100/nature"
];
var b = $("#b");
var cycle = function cycle() {
return b.queue("slide", $.map(imageArray, function(val, i) {
return function(next) {
$(this).fadeOut(50).attr("src", val);
this.onload = function() {
return $(this).fadeIn(50, function() {
return moveRight.call(this).then(function() {
return moveLeft.call(this)
}).then(next);
});
}
}
})).dequeue("slide");
};
function moveRight() {
return $(this).animate({
left: "500"
}, 2000).promise()
}
function moveLeft() {
return $(this).animate({
left: 0
}, 2000).promise()
}
var infiniteCycle = function infiniteCycle() {
return cycle().promise("slide").then(infiniteCycle)
};
infiniteCycle();
#b {
position: relative;
left: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<img id="b" />
Here's a very basic example of what you're trying to achieve. From here you can try and animate the transition, switch it so buttons activate a left/right change. I would suggest playing around with this until you comfortable with the basic functionality. From there you can look into plugins/libraries that can help you. http://jsfiddle.net/306Lqov5/1/
HTML
<img id="b" src="http://placehold.it/100/100&text=Image 1" />
JavaScript
var images = [
'http://placehold.it/100/100&text=Image 1',
'http://placehold.it/100/100&text=Image 2',
'http://placehold.it/100/100&text=Image 3',
'http://placehold.it/100/100&text=Image 4'
];
var index = 1, //start at one since we have the first image in by defualt
img = $('#b');
setInterval(function(){
img.attr('src', images[index]);
index++; //index = index + 1;
if (index == images.length){ //if we've reached the length of the array reset to zero
index = 0;
}
},2000); //switch ever 2 seconds

Stop loop and fade in area that is hovered on

I have a bit of javascript/jquery I am trying to figure out. What I have already is three boxes that the content fades in and out and loops through the three and repeats. What I am trying to do is when "box x" is hovered over the loop fades out and stops never to start again, and the box that is hovered on, the content below the box fades in and stays... unless another box is hovered over, then the content that faded in from the other hovered box will fade out and the new box that was hovered on, the content that coincides with that box fades in and stays fade in, and so forth.
How would I go about doing this?
Here is a jsfiddle example: http://jsfiddle.net/q0htx0no/
javascript/jquery
var infoboxes = $(".count p");
var counter = 0;
function rotate() {
$(infoboxes[counter]).fadeIn(1000, function() {
setTimeout(function() {
$(infoboxes[counter]).fadeOut(1000, function() {
counter = counter < infoboxes.length - 1 ? counter + 1 : 0;
rotate();
})
}, 1000);
});
}
$(function() {
rotate();
});
Thanks for any help
One option would be to have a global variable (a 'flag') that would indicate if the rotation should be stopped. Once a box has been hovered over, it should set hovered to True and should fade in that specific box.
Yep, use a global variable. Something like this:
var infoboxes = $(".count p");
var counter = 0;
var goAhead = true;
function rotate() {
$(infoboxes[counter]).fadeIn(1000, function() {
setTimeout(function() {
$(infoboxes[counter]).fadeOut(1000, function() {
counter = counter < infoboxes.length - 1 ? counter + 1 : 0;
checkRotate();
})
}, 1000);
});
}
function checkRotate() {
if (goAhead) { rotate(); }
}
$('.about').on('mouseover', function() {
goAhead = false;
var index = $(this).index();
var boxesToClear = $(infoboxes).filter(function(i) { return i !== index; });
$(boxesToClear).fadeOut(1000, function() {
$(infoboxes[index]).fadeIn(1000);
});
});
checkRotate();
DEMO
Here's one way to do it. It can probably be improved.
http://jsfiddle.net/vbt67x0h/2/
var infoboxes = $(".count p");
var counter = 0;
var isrotating = false;
function rotate(){
isrotating = true;
$(infoboxes[counter]).fadeIn(1000).delay(1000).fadeOut(1000);
counter = counter < infoboxes.length - 1 ? counter + 1 : 0;
}
//immediately stop rotate and hide all
function stoprotate(){
clearInterval(tmrrotate);
isrotating = false;
for(var x=0;x<infoboxes.length;x++){
$(infoboxes[x]).stop();
$(infoboxes[x]).hide();
}
}
rotate();
//rotate every 3 seconds, 1 to fadein, 1 to pause, 1 to fadeout
var tmrrotate = setInterval(function() {
rotate();
}, 3000);
$(".about").on('mouseover', function() {
if(isrotating){stoprotate()}
$(infoboxes[$(this).index()]).fadeIn(1000);
})
.on('mouseleave', function() {
$(infoboxes[$(this).index()]).fadeOut(1000);
});
You should make a timed array:
var arTimer = [];
and push all timers into that array, clearTimeout on hover and show only hovered index:
var infoboxes = $(".count p");
var counter = 0;
var arTimer = [];
function rotate() {
$(infoboxes[counter]).fadeIn(1000, function() {
arTimer.push(setTimeout(function() {
$(infoboxes[counter]).fadeOut(1000, function() {
counter = counter < infoboxes.length - 1 ? counter + 1 : 0;
rotate();
})
}, 1000));
});
}
function cleararTimer(){
for (var i = 0; i < arTimer.length; i++) {
clearTimeout(arTimer[i]);
}
}
$(function() {
rotate();
$('.about').on('mouseover', function(){
cleararTimer();
var hovered = $(this).index();
$('.count p').not(':eq('+hovered+')').fadeOut(1000);
$('.count p:eq('+hovered+')').fadeIn(1000);
});
});
jsFiddle Example

Previous and Next functions for js slider

I have almost finished this slider, but I don't know how to implement the functionality for next() and prev(). How can I implement these functions?
http://jsfiddle.net/M4t4L/11/
$(function () {
var container = $("#scene"),
i = 0,
count = container.find("li").length,
j = container.find("li").length - 1,
isAnimating = false;
container.find("li:first").css({
"width": "100%"
});
$("#trigger").click(function (e) {
if (!isAnimating) {
isAnimating = true;
e.preventDefault(e);
i++; if (i >= count) { i = 0; }
j++; if (j >= count) { j = 0; }
container.find("li")
.finish()
.removeClass('active')
.last()
.width(0)
.addClass("active")
.animate({
"width": "100%"
}, 800,
function () {
container.find("li").first().appendTo(container);
isAnimating = false;
});
}
});
});
The problem is that when I implement these functions and press the next or prev. Displays the last slide on one second, and then switches to the desired
http://jsfiddle.net/M4t4L/9
If you want to get a Next or Prev function running, you want to take control of the number of the slider where you are. I'm afraid you will have to play around with your i/j and make the position go in both directions.
Right now you count up your i and j, where you might want to go is to have a position var and an array of slider objects, then the click only would have to call for the next/prev object to be loaded and the animation can begin.
Something like this maybe..
var pos = 0;
var container = $('#scene').find('li');
$('.back').click(function() {
pos = pos - 1;
moveIt(pos);
});
$('.forth').click(function() {
pos = pos +1;
moveIt(pos);
});
function moveIt(pos) {
container[pos]... // Your animation goes here
}

Stop timeOut and animation on mouseenter and continue on mouseleave

I wanted to get rid of a slider-plugin, so i tried to build my own,
everything works nice but i´m stuck to stop the whole thing on hover and restart it again on mouseleave,
here is my js :
function startPslider(val) {
if (!val) {
val = 0;
}
var holder = 'slideHolder';
var text = 'slideText';
startInterval(holder, text, val);
}
function startInterval(holder, text, val) {
var t;
var i = val;
if (i > 2) {
i = 0
}
$('#' + holder + i).animate({
opacity: 1,
}, function () {
$(this).addClass('active')
$('.' + text + i).animate({
opacity: 1,
left: 0
}, 1200);
t = setTimeout(function () {
$('.' + text + i).animate({
opacity: 0,
left: '-400px'
}, 1200);
$('#' + holder + i).animate({
opacity: 0,
}, 2200).removeClass('active');
startPslider(i + 1);
}, 4000)
});
// Here´s the not working hover-function
$('#hpCanvas').hover(function () {
clearTimeout(t);
}, function () {
var id = $('.active').attr('id');
var slide = id.substring(11, 22);
console.log(slide)
startPslider(slide);
});
}
$(function () {
startPslider();
});
tryed to solve this with adding class 'active' to the current holder and at hover-out try to catch the current-slide number (val) and restart it again, starting on the correct slide, but it´s not working as I wish,
have a look at this fiddle, http://jsfiddle.net/zDh76/ you will find html and css there, as you see everything works fine as long you do not hover.
Maybe anyone has a helping hint how to stop the animation, clear the timer and go on with the correct slide on mouseleave?
UPDATE
i separated start and end-interval
function startPslider(i) {
if(!i){
i=0;
}
if(i >2){
i=0
}
console.log('started Slider with slide:'+i)
var holder = 'slideHolder';
var text = 'slideText';
startInterval(holder, text, i);
}
function startInterval(holder,text,i) {
var t;
var v;
console.log('started Interval with slide:'+i);
$('#'+holder+i).animate({
opacity:1,
}, function(){
$('.'+text+i).animate({
opacity:1,
left:0
},1200);
t= setTimeout(function(){endInterval(holder,text,i); },4000);
});
}
function endInterval(holder,text,i,cont){
console.log('end Interval with slide:'+i);
$('.'+text+i).animate({
opacity:0,
left:'-400px'
},1200);
$('#'+holder+i).animate({
opacity:0,
},2200, function(){
$('.slideHolder').css('opacity',0);
i = i+1;
startPslider(i);
});
}
I found it out myself,
i needed to unbind the hover event on #hpCanvas inside the mouseleave function like
$('#hpCanvas').hover(function(){
$('.slideHolder, .slideText').stop(true,true);
clearTimeout(t)
},function(){
endInterval(holder,text,i);
$('#hpCanvas').unbind('mouseenter mouseleave')
})
as the next call to bind it with hover event is inside the mouseleave-part of the first hover event.
thanks anyway for everyone reading this

.next() not working as intended

So,
if($(this).hasClass('active')){
$(this).removeClass('active');
$(this).prev().addClass('active');
}
works fine, it adds the class "active" to this previous div of the same kind.
if($(this).hasClass('active')){
$(this).removeClass('active');
$(this).next().addClass('active');
}
However, adds the class to the next div (as i intend for it to do) for about 0.5 of a second BUT then removes it.
Here's ALL of the jQuery (as per your comments below) - Please do not comment on my horrible code organization
$(window).load(function () {
// Initial variables
var numberSlides = 0;
var currentSlide = 1;
var ready = true;
var pageWidthR = $(document).width() - 352;
var pageWidthL = $(document).width() - 352;
// Update number of slides by number of .slide elements
$('#features-slider .slide').each(function () {
numberSlides++;
});
// Go through each slide and move it to the left of the screen
var i = 0;
$($('#features-slider .slide').get().reverse()).each(function () {
if (i == 0) {
} else {
var newWidth = i * 115;
$(this).css('left', '-' + newWidth + '%');
}
i++;
});
// Animate the first slide in
$('#features-slider .slide:last-child').addClass('active').animate({
left: 0
}, 1500);
// Remove the loading message
$('#loading').fadeOut(1000, function () {
$('#loading').remove();
// Now that we're done - we can show it
$('#features-slider').show();
});
/***** Left and Right buttons *****/
/* Right */
$('#rightbutton').click(function () {
var numberSlides = 0;
$('#features-slider .slide').each(function () {
numberSlides++;
});
var index = $('.slide.active').index() + 1;
if (!$('.slide').is(':animated') && index != 1) {
$('#features-slider .slide').each(function () {
if ($(this).hasClass('active')) {
var currentLeft = $(this).css('left');
var newLeft = parseInt(currentLeft) + 115;
} else {
var currentLeft = $(this).css('left');
var newLeft = parseInt(currentLeft) + 115;
}
$(this).animate({
left: newLeft + '%'
}, 1500);
if ($(this).hasClass('active')) {
$(this).removeClass('active');
$(this).prev().addClass('active');
}
});
}
});
/* Left */
$('#leftbutton').click(function () {
var numberSlides = 0;
$('#features-slider .slide').each(function () {
numberSlides++;
});
var index = $('.slide.active').index() + 1;
if (!$('.slide').is(':animated') && index != numberSlides) {
$('#features-slider .slide').each(function () {
if ($(this).hasClass('active')) {
var currentLeft = $(this).css('left');
var newLeft = parseInt(currentLeft) - 115;
} else {
var currentLeft = $(this).css('left');
var newLeft = parseInt(currentLeft) - 115;
}
$(this).animate({
left: newLeft + '%'
}, 1500);
if ($(this).hasClass('active')) {
$(this).next().addClass('active');
$(this).removeClass('active').not($(this).next());
}
});
}
});
});
$(document).ready(function () {
// Hide the slider and show a loading message while we do stuff and the images / DOM loads - Also disable overflow on the body so no horizontal scrollbar is shown
$('body').css('overflow-x', 'hidden');
$('#features-slider').hide();
$('#loading').html('<center> <img id="loader" src="/wp-content/themes/responsive/library/images/ajax-loader.gif" /> Loading</center>');
});
RESOLVED
New left button function :
$('#leftbutton').click(function(){
var numberSlides = 0;
$('#features-slider .slide').each(function(){
numberSlides++;
});
var index = $('.slide.active').index()+1;
if( !$('.slide').is(':animated') && index != numberSlides ){
var done = false;
$('#features-slider .slide').each(function(){
if($(this).hasClass('active')){
var currentLeft = $(this).css('left');
var newLeft = parseInt(currentLeft)-115;
} else {
var currentLeft = $(this).css('left');
var newLeft = parseInt(currentLeft)-115;
}
$(this).animate({left: newLeft+'%'}, 1500);
if($(this).hasClass('active') && done == false){
$(this).next().addClass('active');
$(this).removeClass('active');
done = true;
}
});
});
If you're iterating forward through the elements, then it should be clear what's going on - you add the "active" class to the next element, and then the next iteration takes it away.
This is just a guess however as you did not post enough code for me (or anybody else) to be sure.
edit — ok now that you've updated the question, it's clear that the guess was correct. The .each() function will iterate forward through the elements. When an element has the "active" class, and the code removes it and adds it to the next element, then on the next iteration the work is undone.
Since you are referencing this and by the behavior you're describing, you are likely iterating a loop for a list of elements. As a result, you are completing the action you want but the next iteration is removing the previous changes due to your usage of removing a class and then adding the class back.
As it stands now, your code does not illustrate how this occurence can be happening.
Update:
As suspected, you seem to be looping as signified by: each(function(){. While iterating through your objects the class is being pushed forward and is not acting as desired. You are stating add the class to the next element, but remove it from the current element, and this behavior continues through your iteration.
On a side note, update your code to call removeClass() on the current object first, before adding it to the next object:
if ($(this).hasClass('active')) {
$(this).removeClass('active').next().addClass('active');
}

Categories