October 29, 2012

Animate/Ease an element to position when other elements disappear

Question by Jonathan

Please take a look at this fiddle: http://jsfiddle.net/dhcyA/

Try clicking on a block. What I want is that when the other elements disapear, the selected block will animate/ease to his giving position instead of just jumping like it does now. Then the same animation repeats itself when clicking again on the box, but then back to place.

Maybe to keep in mind:
I’m using a reponsive design, which means those blocks can be vertical and horizontal after scaling the window.

Any redevisions on the fiddle or suggustions would be great!

Answer by Starx

Here is my solution & features it offers:

  • Remembers the last position and gradually animate to/from this position
  • Block positions are calculated and animated on load and every resize
  • Repositioning happens on $(window).resize() thus maintaining the fluid nature of the block, despite the use of position absolute
  • Support variable heights
  • Minor change on existing markup & CSS

On your existing markup, I added a wrapper division.

<div id="wrapper">
    <div class="block">
        <h2>I'm block 1</h2>
    </div>
    ....
</div>

To maintain the fluidness of the block, I created a function to position the block on the wrapper. Here is the function for position of the blocks:

var reposition = function() {
    wrapper = $("#wrapper");
    pLeft = 0; //The starting point of all repositioning
    pTop = 0;

    maxRowHeight = 0;

    $(".block").each(function(){
        $(this).stop(0,0).animate({
          'top' : pTop + 'px',
          'left' : pLeft + 'px'
        });

        pLeft += $(this).width(); //Add the left position for next block

        if($(this).height() > maxRowHeight) maxRowHeight = $(this).height(); //Find out the longest block on the row

        //If the next block will exceed the width of the wrapper
        if(pLeft + $(this).next().width() >= wrapper.innerWidth()) {
           pLeft = 0; //reset the left
           pTop += maxRowHeight;
           maxRowHeight = 0; 
        }
    });    
};

Finally, the script to toggle the block

$(".block").click(function() {

    $(this).siblings().slideToggle('slow'); //Toggle other blocks

    if(!$(this).data('active')){ //if the block is not active
        $(this).data('left', $(this).position().left); //sets its left
        $(this).data('top', $(this).position().top);   // and top position
        $(this).animate({ //animate at the top and bottom
            top:0,
            left:0
        },'slow');

        $(this).data('active',true);

    }else{

        $(this).animate({ //animate to its last known position
            top:$(this).data('top'),
            left:$(this).data('left')
        },'slow');

        $(this).data('active',false);
    }
});

Demos

  • Demo[Full] (Resize this to see the fluidness maintained)
  • Demo[Full] (version supporting variable heights)

Author: Nabin Nepal (Starx)

Hello, I am Nabin Nepal and you can call me Starx. This is my blog where write about my life and my involvements. I am a Software Developer, A Cyclist and a Realist. I hope you will find my blog interesting. Follow me on Google+

...

Please fill the form - I will response as fast as I can!