1

I need to animate opacity of 3 images one by one in a loop ... I write the code below and its working fine but is this code good or we can optimise it. Any sugessions please.

function animateit(play){
            if(play==false){
                $(".img2", obj).stop(true, true).fadeTo('800', 0);
                $(".img3", obj).stop(true, true).fadeTo('800', 0);              
                $(".img4", obj).stop(true, true).fadeTo('800', 0);                              
            }
            if(play==true){
                $(".img2", obj).animate({opacity:"1"}, s, e,
                    function(){
                        $(".img3", obj).delay(p).animate({opacity:"1"}, s, e,
                            function(){
                                $(".img2").css({opacity:"0"});

                                $(".img4", obj).delay(p).animate({opacity:"1"}, s, e,
                                    function(){
                                        $(".img3").css({opacity:"0"});
                                        $(".img4", obj).delay(p).animate({opacity:"0"}, s, e,
                                            function(){ 
                                                $(".img4", obj).delay(p).animate({opacity:"0"}, s, e,
                                                    function(){ 
                                                        if(play==true)animateit(true);                                  
                                                    });                                         

                                            });
                                    });
                                });
                        });
                }
            }
Shawn Chin
  • 84,080
  • 19
  • 162
  • 191
Imran
  • 1,094
  • 1
  • 21
  • 41

1 Answers1

2

For a version that's easier to read and maintain, you can use the jquery-fxQueues plugin which overloads the $.animate() function to support global animation queues. This means that your code can be written simply as:

function animation() {
    var o2 = $(".img2", obj),
        o3 = $(".img3", obj),
        o4 = $(".img4", obj);
    o2.animate({opacity: "1"}, {duration:s, queue: "global", postDelay:p});
    o3.animate({opacity: "1"}, {duration:s, queue: "global"});
    o2.animate({opacity: "0"}, {duration:0, queue: "global", postDelay:p});
    o4.animate({opacity: "1"}, {duration:s, queue: "global"});
    o3.animate({opacity: "0"}, {duration:0, queue: "global", postDelay:p});
    o4.animate({opacity: "0"}, {duration:s, queue: "global", postDelay:p, 
                                complete:animation}); // repeat when done
}

Demo to show this in action: http://jsfiddle.net/RMVtU/2/

For a reference, here's your version as a fiddle as well: http://jsfiddle.net/dEfY7/

Important Note: There is a potentially huge drawback to this plugin though. As far as I know, the latest version of fxQueues (2.0.3) only works with jQuery 1.3.x.


Update (non-plugin version)

If the limitations of fxQueues is a deal breaker, it is still possible to roll your own global animation queue using $.queue() and $.dequeue() on a proxy object.

Here's an example: http://jsfiddle.net/mAfFW/

/* functions to emulate a global queue */
var Q = $({}); // empty object to store global queue
var enQ = function(func) { Q.queue("global", func); } // add to queue
var deQ = function() { Q.dequeue("global"); }  // pop next animate
var stopQ = function() { Q.clearQueue("global"); }  // clear animation

function animate() {
    enQ(function() {
        o2.animate({opacity: "1"}, s, e, deQ);
    });
    enQ(function() {
        o3.delay(p).animate({opacity: "1"}, s, e, deQ);
    });
    enQ(function() {
        o2.css("opacity", "0");
        o4.delay(p).animate({opacity: "1"}, s, e, deQ);
    });
    enQ(function() {
        o3.css("opacity", "0");
        o4.delay(p).animate({opacity: "0"}, s, e, deQ);
    });
    enQ(function() {
        o3.css("opacity", "0");
        o4.delay(p).animate({opacity: "0"}, s, e, deQ);
    });
    enQ(animate); // repeat when done
    deQ();  // start the animation by dequeueing an entry
}

It's not as clean as using fxQueues, but it's certainly more readable than a series of nested callbacks.

For a comprehensive explanation of $.queue() and $.dequeue() with examples, check out this answer: What are queues in jQuery?

Community
  • 1
  • 1
Shawn Chin
  • 84,080
  • 19
  • 162
  • 191
  • I really love the plugin you referred but unfortunately the site I am working on is using jQuery 1.6.x. ... Thanks Shawn for your support – Imran Sep 13 '11 at 19:40
  • @Imran Answer updated with a version that does not require plugins and works for 1.6.3 – Shawn Chin Sep 14 '11 at 08:35
  • Yes this works great. I appreciate your efforts. Two thumbs up. – Imran Sep 15 '11 at 14:39