How to use queue in jQuery animate? - javascript

I want to increase/decrease the font of and element, then the next element of that class and so forth, for a set of elements as <div class="test"></div> <div class="test"></div> ..... I mean
step 1: enlarging the first element and returning to normal size
step 2: enlarging the second element and returning to normal size
....
My basic code is
$(document).ready(function() {
$('.test').animate({
left:50,
fontSize: "2em"},
"slow")
.animate({
left:-50,
fontSize: "1em"},
"slow");
This will affect all the elements at once. How can I make a queue to make the changes one by one. Having one enlarged element at a time.

You could do it with
$('.test').each(function(idx){
var duration = 1200; // duration for all animations (2 x slow)
$(this)
.delay(duration*idx)
.animate({ left:50, fontSize: "2em" }, 'slow')
.animate({ left:-50, fontSize: "1em" }, 'slow');
});
Demo at http://jsfiddle.net/gaby/rz5Es/
For more precise control and more freedom on queuing look at my answer at a similar question:
A non-nested animation sequence in jQuery?

You need to use callbacks and an array of the elements you want to sequentially animate...
function animateSequence(elements){
var element = $(elements).first();
var originalSize = $(element).css('font-size');
elements = $(elements).not($(element));
$(element).animate(
{ fontSize: "2em" },
"slow",
function(){
$(this).animate(
{ fontSize: originalSize },
"slow",
function(){
if(elements.length > 0)
animateSequence(elements);
}
)
}
);
}
animateSequence($('.test'));
If you want to play with it: http://jsfiddle.net/xS7X7/

You will need to loop thru all elements and execute animate on each of them sequentially, here is sample code to do that recursively
function animate_sequential(elems, css, delay, index){
if(index===undefined) index = 0;
if(index >= elems.length) return;
$(elems[index]).animate(css, delay, function(){
animate_sequential(elems, css, delay, index+1)
})
}
animate_sequential($('div'), {'font-size':'30px'}, 500)
animate_sequential($('div'), {'font-size':'15px'}, 500)
See it in action http://jsfiddle.net/anuraguniyal/QJc9L/
It can be easily converted to a jQuery plugin, so that you can do $('div').animate_sequential and keep same interface as jQuery animate, you can also further enhance it so that it brings back to original css by passing the original css or getting it from element.

As I understand you are trying to do something like this,
$(document).ready(function() {
(function mycallback(i) {
var elems = $('.test');
elems.eq(i).animate({
left:50,
fontSize: "2em"}, function () {
mycallback(i + 1 < elems.length ? i + 1 : 0);
});
}(0));
});
​DEMO
UPDATE:
It was an example code, you can change it like this if you want to reverse effects,
$(document).ready(function() {
(function mycallback(i) {
var elems = $('.test');
elems.eq(i).animate({
left:50,
fontSize: "2em"}, function () {
$(this).animate({
left:-50,
fontSize: "1em"},
"slow");
if (i + 1 < elems.length)
mycallback(i+1);
});
}(0));
});
​UPDATED DEMO

So much simpler, readable, and scalable with Frame.js:
$('.test').each(function(i){
var element = $(this);
var originalSize = element.css('font-size');
Frame(function(next){
element.animate({ fontSize: "2em" }, "slow", next);
});
Frame(function(next){
element.animate({ fontSize: originalSize }, "slow", next);
});
});
Frame(function(next){
// add a callback after all the animations have finished
next();
});
Frame.start();

Related

How to replace a CSS3 transition

I'm trying to apply a CSS transition to an element, but at some point before it completes, remove the transition entirely and start another one.
This question answers how to stop a transition in its tracks, but I modified the jsFiddle there to illustrate the issue:
http://jsfiddle.net/zXVLd/
var $div = $('div');
$div.click(function(){
$div.css({
left: 0,
transition: 'none'
});
$div.transit({
top: 600,
},5000);
});
function complete(){
$div.css('backgroundColor', 'blue');
}
$div.transit({left: 600}, 5000, 'linear', complete);
What I want to happen is for the box to reset its position and move down when clicked, and for the completed handler on the first transition to not fire.
What does happen is the box resets its position when clicked, but doesn't move down until the first transition completes (even though the motion from the first transition is no longer happening). The completed handler still fires on the first transition as well.
I've updated your fiddle with the clearQueue method: http://jsfiddle.net/zXVLd/1/
var $div = $('div');
$div.click(function(){
$div.clearQueue().css('left', $div.css('left')).transit({
top: 600,
},5000);
});
function complete(){
$div.css('backgroundColor', 'blue');
}
$div.transit({left: 600}, 5000, 'linear', complete);
That does the trick. See http://api.jquery.com/clearQueue/ for more information on the clearQueue method.
To do this kind of animations, you can try to use GSAP's TweenLite. It's incredible what you can achieve with it. http://www.greensock.com/jump-start-js/ If you include this on your page and add the following code:
div.bind('click', function(e) {
// note that you can animate two directions, from and to
TweenLite.from(div /*element*/, 0.2 /*easing in seconds*/, {
// the css, but for positioning elements you can also use x and y.
x: 600,
easing: linear,
onStart: function() {
Stuff you want to do before the animation
},
onComplete: function() {
Stuff you want to do after animationg
}
});
});
The plugin which you use is using queue. So, it is just enough to call $div.dequeue(); I.e.
var $div = $('div');
$div.click(function(){
$div.dequeue();
$div.css({
left: 0,
top: 0,
transition: 'none'
});
$div.transit({
top: 600,
},5000);
});
function complete(){
$div.css('backgroundColor', 'blue');
}
$div.transit({left: 600}, 5000, 'linear', complete);
fiddle -> http://jsfiddle.net/krasimir/zXVLd/2/

tooltip is shown after the 2nd hover

I have a problem, I'm trying to add a tooltip to some already rendered elements. The code that I have makes the tooltip appear after the 2nd hover which is kind of normal because on the first one is not set yet, do you know what can I do to have it displayed from the first hover?
Thanks in advance!
I have the following code:
$(".checkWidth").live("mouseenter",function() {
var size = measureText($(this).text(), 12, 'Tahoma')
var limit = $('#my_container').width() - 67;
if( size.width > limit){
$(this).attr('title', $(this).text());
$('#tiptip_content').css('font-size', '13px');
$(this).tipTip({
maxWidth: "auto",
defaultPosition: "right",
fadeIn: 100,
fadeIn: 100,
attribute: "title"
});
}
});
Calling $(this).tipTip({...}); sets up the tooltip, it doesn't show it. So you don't actually set up the tooltip until you mouseover the element, and the tooltip is shown the next time you mouse over (handled by the plugin).
You'll need to call that on DOM ready. I think you may need something like this:
$(document).ready(function () {
$('#tiptip_content').css('font-size', '13px');
var limit = $('#my_container').width() - 67;
$('.checkWidth').each(function () {
var size = measureText($(this).text(), 12, 'Tahoma');
if (size.width > limit) {
$(this).attr('title', $(this).text());
$(this).tipTip({
maxWidth: "auto",
defaultPosition: "right",
fadeIn: 100,
fadeIn: 100,
attribute: "title"
});
}
});
});
Edit another possibility:
$('#tiptip_content').css('font-size', '13px'); //this should be able to be done elsewhere...
$("document").on("mouseenter", '.checkWidth', function () {
var $this = $(this);
if ($this.data('tipInit') === true) { return; }
$this.data('tipInit', true);
var size = measureText($(this).text(), 12, 'Tahoma')
var limit = $('#my_container').width() - 67;
if (size.width > limit) {
$this.attr('title', $this.text());
$this.tipTip({
maxWidth: "auto",
defaultPosition: "right",
fadeIn: 100,
fadeIn: 100,
attribute: "title"
});
$this.trigger('mouseenter');
}
});
it depends on your code structure. But I will try the following:
Try changing the .live() to .on()
I would try to change the function to .on('hover', function)
I would also try to use mousenter and mouseleave

JQuery animate .css() rather then using .anmiate()?

I want to aniamte the change of the margin-top of a div.
Normally I would so this as such:
$("#mydiv").animate({ marginTop: '+='+myvar}, 200);
But this always adds (or subtracts) the value. I want a way to simply aniamte the change in value.
For example: if the div starts of with a margin top of 100 and myvar value is 50 I want to animate the div so it shrinks back to 50. Likewise if the myvar value is 200 I want to animate the change so grows to 200.
I can achieve this somewhat but resetting the CSS, eg:
$("#mydiv").css("margin-top", "0px");
$("#mydiv").animate({ marginTop: '+='+myvar}, 200);
each time but that makes it a bit clunky.
Does anyone know of a may to achieve this?
(Ps: without using CSS transitions)
EDIT: Added my code below
$("#info1tab").click(function() {
$(".textbox").slideUp('200');
$("#info1").delay(300).slideDown('200');
var itemheight = $("#info1").css("height");
var itemheightint = parseInt(itemheight);
$("#photobox").animate({ marginTop: itemheightint }, 200);
});
$("#info2tab").click(function() {
$(".textbox").slideUp('200');
$("#info2").delay(300).slideDown('200');
var itemheight = $("#info2").css("height");
var itemheightint = parseInt(itemheight);
$("#photobox").animate({ marginTop: itemheightint }, 200);
});
what is wrong with $('#mydiv').animate({marginTop: myvar});?
http://jsfiddle.net/muVsE/
Create additional CSS classes that has the CSS properties you want and then do:
$("#mydiv").addClass("classname", 1000);
OR
$("#mydiv").removeClass("classname", 1000);
Try this code:
$("#mydiv").css("margin-top", "0px");
$("#mydiv").animate({ marginTop: topMargin+myvar}, 200);
I hope this helps JSFiddle
$('#left-bg, #right-bg').click(
function(){
$(this).animate({'width': '100%'},600).siblings().animate({'width':'0'},600);
});
Or you can use this JSfiddle
$('#left-bg, #right-bg').click(
function(){
$(this).animate({'width': '100%'},600).siblings().animate({'width':'0'},600);
$('<button class="show">Show all</button>')
.appendTo('#wrapper');
});
$('.show').live('click',
function(){
$('#left-bg').animate(
{
'width': '50%'
},600);
$('#right-bg').animate(
{
'width': '50%'
},600);
$(this).remove();
});
Or you can use this to expand one div and shrink other at the same time:
$('.cell')
.on('mouseenter', function(){
$(this).animate ({width:"75%"},"slow").siblings('.cell').animate({'width': '15%'}, "slow");
})
.on('mouseleave', function(){
$(this).add($(this).siblings('.cell')).animate ({width:"45%"},"slow");
});
Regards.

animate every char of an html element text using jquery?

i want to animate a string of text taken from an html element using jquery:
<h1>Animate</h1>
for the jquery part:
$(document).ready(function() {
$( "h1" ).animate({ fontSize: "90px" }, 1500 )
.animate({ fontSize: "50px" }, 1500 );
});
this animates the whole h1 text value, however i want to animate each character in the h1 text.
the second jquery part:
$(document).ready(function () {
var animateChar = $("h1").text();
for(i=0; i<animateChar.length; i++) {
//alert(i + ': ' + animateChar.charAt(i));
// for every animateChar.charAt[i] want to run this
//jquery animation.
//$( "h1" ).animate({ fontSize: "90px" }, 1500 )
//.animate({ fontSize: "50px" }, 1500 );
}
});
this is the bit where im stuck. thanks
You can use jQuery functions on DOM elements. Not on characters apart. You should use different DOM elements for each character:
<span>A</span><span>N</span><span>I</span>...
with something like this must do the trick
$('span').each(function() {
var that = $(this);
setTimeout(function() {
that.animate({ fontSize: "90px" }, 1500 )
.animate({ fontSize: "50px" }, 1500 );
},that.index()*100);
});​
-edit-
working jSFIDDLE
-edit 2-
without messy HTML JSFIDDLE(well it's still messy, but javascript makes it messy ;) )
If you want to keep your HTML clean, I'd add the following method to wrap your characters in span tags. Execute this onLoad using wrapCharacters($("h1")) before you animate anything, then animate characters returned by $(".animate").
function wrapCharacters(obj)
{
var html = '';
var text = obj.text();
for (var i = 0; i < text.length; i++)
{
html += '<span class="animate">' + text[i] + '</span>';
}
obj.html(html);
}
<span class="animate">A</span><span class="animate">n</span><span class="animate">i</span><span class="animate">m</span><span class="animate">a</span><span class="animate">t</span><span class="animate">e</span>
$(document).ready(function() {
var count = 0;
function animation(elm) {
if(count == $(".animate").length)
{
clearInterval(id);
return;
}
$( elm ).animate({ fontSize: "90px" }, 1500 )
.animate({ fontSize: "50px" }, 1500 );
count++;
}
var id = setInterval(animation($(".animate")[count]), 3200);//Give time for animation to run.
});
This will animate each character.

get height of LI using jQuery so news ticker scrolls up the exact amount needed

I am using a script from
http://www.yourinspirationweb.com/en/jquery-how-to-create-a-news-ticker-with-just-a-few-javascript-lines/
which is a great newsticker, designed to scroll up just one article at a time, then append it again at the end in a continuous loop. But the limitation of this script is that the news items in each have to be the same height as eachother, which isn't always possible.
I have been trying to modify the script so that it will automatically get the outerheight of '#ticker li:first'. and scroll it so that marginTop equals the negative of that outerheight. rather than the default '-120px'. But i've realised it's written as CSS style, i don't know how to rewrite it. Help!
here's the original script:
$(function()
{
var ticker = function()
{
setTimeout(function(){
$('#ticker li:first').animate( {marginTop: '-120px'}, 800, function()
{
$(this).detach().appendTo('ul#ticker').removeAttr('style');
});
ticker();
}, 4000);
};
ticker();
});
This should do the trick. Just put the height into a variable, multiply by -1 (to make the negative number you need), and then drop it into the marginTop property:
$(function() {
var ticker = function() {
setTimeout(function() {
// get the height of the li element, multiply by -1 to be negative
var h = parseInt($("#ticker li:first").outerHeight()) * -1;
$('#ticker li:first').animate( {marginTop: h + 'px'}, 800, function() {
$(this).detach().appendTo('ul#ticker').removeAttr('style');
});
ticker();
}, 4000);
};
ticker();
});
To retrieve the outerHeight (including border, padding, and optionally margin) of an html element using jQuery, do $(element).outerHeight()
To retrieve the innerHeight of an html element using jQuery, do $(element).innerHeight()
$(function()
{
var ticker = function()
{
setTimeout(function(){
var oHeight = $('#ticker li:first').outerHeight();
$('#ticker li:first').animate( {marginTop: -oHeight}, 800, function()
{
$(this).detach().appendTo('ul#ticker').removeAttr('style');
});
ticker();
}, 4000);
};
ticker();
});
The default unit is pixels so you don't have to worry about appending px to the value.

Categories

Resources