Reputation: 2520
I have this following jquery text fly-in animation.Here is my code before I explain further:
<script type="text/javascript">
$(document).ready(function(){
$('.flying1 .flying-text').css({opacity:0});
$('.flying1 .active-text').animate({opacity:1, marginLeft: "0px"}, 1200); //animate first text
var int = setInterval(changeText, 3500); // call changeText function every 5 seconds
function changeText(){
var $activeText = $(".flying1 .active-text"); //get current text
var $nextText = $activeText.next(); //get next text
if ($activeText.is('.end')) {
$activeText.stop().delay(5000);
$('.flying1').html('<div class="flying-text active-text">Text4<div>
<div class="flying-text">Text5</div>
<div class="flying-text end2">Text6</div>');
$('.flying1 .flying-text').css({opacity:0});
$('.flying1 .active-text').animate({opacity:1, marginLeft: "0px"}, 1200); //animate first text
};
if ($activeText.is('.end2')) {
$activeText.stop().delay(5000);
$('.flying1').html('<div class="flying-text active-text">Text1<div>
<div class="flying-text">Text2</div>
<div class="flying-text end">Text3</div>');
$('.flying1 .flying-text').css({opacity:0});
$('.flying1 .active-text').animate({opacity:1, marginLeft: "0px"}, 1200); //animate first text
};
$nextText.css({opacity: 0}).addClass('active-text').animate({opacity:1, marginLeft: "0px"}, 1200, function(){
$activeText.removeClass('active-text');
});
}
});
</script>
HTML
<div class="flying-text active-text">Text1<div>
<div class="flying-text">Text2</div>
<div class="flying-text end">Text3</div>
Now as you can see, Text1-3 animates/flies in first, then when Text3 is reached, they are replaced by Text4-6 in the animation, when Text6 is reached again, it loops back to Text1-3 again...Now basically what I want to do is pause/delay the animation for longer when it reaches the end of the Text, that is at Text3(class="flying-text end") and Text6(class="flying-text end2". So I want Text3 and Text6 to animate longer than all the others. how do I do that? The code I used :
$activeText.stop().delay(5000);
does not work...
Thank You
Upvotes: 5
Views: 977
Reputation: 11936
Queue your animations, and use .delay()
on, a common queue object (demo):
var text = [
[ 'Text1', 'Text2', 'Text3' ],
[ 'Text4', 'Text5', 'Text6' ]
],
reset = {
opacity: 0,
marginLeft: -50
},
flyout = {
opacity: 1,
marginLeft: 0
},
flyoutDuration = 1200,
changeTextDelay = 5000,
q = $({}), // can also be a common element, e.g. $('.flying1')
pos = 0;
function changeText() {
$('.flying1 .flying-text').each(function(i) {
var div = $(this);
// setup text
div.css(reset).text(text[pos][i]);
// queue
q.queue(function(next) {
div.animate(flyout, flyoutDuration, next);
});
});
q.delay(changeTextDelay).queue(function(next) {
pos = (pos + 1) % text.length;
changeText();
next();
});
}
changeText();
Upvotes: 1
Reputation: 339836
I think you've made things over-complicated for yourself.
You just need to use normal setTimeout
to trigger the next animation, but do that within the animation "complete" function to ensure that you're not mixing animation timers with normal timers.
You should also avoid setInterval
for the same reason - it'll fall out of sync with any animation timers, particularly when the jQuery authors revert back to using requestAnimationFrame
.
Here's my solution:
var text = [
['Text1', 'Text2', 'Text3'],
['Text4', 'Text5', 'Text6']
];
var n = 0,
page = 0;
var $f = $('.flying-text');
function changeText() {
$f.eq(n).text(text[page][n]).css({
opacity: 0,
marginLeft: '-50px'
}).animate({
opacity: 1,
marginLeft: "0px"
}, 1200, function() {
if (++n === 3) {
page = 1 - page;
n = 0;
setTimeout(function() {
$f.empty();
changeText();
}, 6000);
} else {
setTimeout(changeText, 2000);
}
});
};
changeText();
working demo at http://jsfiddle.net/alnitak/GE2gN/
Note that this completely separates the text content from the animation logic.
Upvotes: 3
Reputation: 2989
There is a similar question here:
In the comments of the second answer down it states that delay doesnt work with stop.
Hope this page is useful to you.
EDIT OK i have found a solution. Try this and let me know if its suitable.
Replace your delay lines with this:
$(this).animate('pause').delay(5000).animate('resume');
Upvotes: 1