Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Insert inline element and animate shift to left

I've been trying to solve this problem for a week now and it seems basic, so maybe I'm missing something.

I want to have a div centered on the screen (or its container), and then insert a second div to the right of it, so that afterwards the two of them are centered (space on each side is equal).

Inserting the second div is not a problem, but I need the first block to slide over to where its going to be after the new block is inserted.
http://jsfiddle.net/rdbLbnw1/

.container {
   width:100%;
   text-align:center;
}

.inside {
   border:solid 1px black;
   width:100px;
   height:100px;
   display:inline-block;
}

$(document).ready(function() {
    $("#add").click(function() {
        $(".container").append("<div class='inside'></div>");
    });
});

<div class="container">
    <div class="inside"></div>
</div>
<input id="add" type="button" value="add"/>

Do I need to explicitly calculate where the original box is going to end up and then animate that, or is there a better way to do it?

like image 458
Jeremy Miller Avatar asked Sep 01 '14 07:09

Jeremy Miller


2 Answers

I like your question so decide to write this:

$(document).ready(function() {
    var isInAction = false;
    var intNumOfBoxes = 1;
    var intMargin = 10;
    $containerWidth = $(".container").width();
    $insideWidth = $(".inside").width();
    $(".inside").css('margin-left',($containerWidth - $insideWidth - intMargin)/2 + 'px');
    $("#add").click(function() {
        if (!isInAction){
            isInAction = true;
            intNumOfBoxes +=1;
            $(".current").removeClass("current");
            $(".container").append("<div class='inside current'></div>");
            $('.inside').animate({
                'margin-left': '-=' + ($insideWidth + intMargin)/2 + 'px'
            }, 300, function () {
                $(".current").css('margin-left',($containerWidth + ((intNumOfBoxes - 2) * ($insideWidth + intMargin)))/2 + 'px');
                $(".current").fadeIn(500,function(){
                    isInAction = false;
                });
            });
        }
    });
});

Also add this class in CSS:

.current {
    display:none;
}

You don't need to change variables in JS code except intMargin. you can change this var to set margin between boxes.

Note: This code works fine on older browsers too and not need to support CSS3 features like transition.

Update: Some bugs like repeated clicks fixed.

Check JSFiddle Demo

like image 187
Moshtaf Avatar answered Nov 19 '22 03:11

Moshtaf


First, we can animate only things that have explicit numerical values such as width, left or margin. We can't animate things like alignment (which actually use the same margin property but implicitly, never mind). So if we know width of inserted div let's just add it to our container.

1) Let's centre container itself and add transition to it

.container {
    width: 102px; /* set explicit width; 102 - because of borders */
    margin: auto; /* set margin to 'auto' - that will centre the div */
    transition: width 0.5s;
}

2) Then increase the width when add div

$(".container").width($(".container").width() + 102);

3) But wait! If we add div to too narrow container it will be added to bottom not to right. So we need another container set to appropriate width before.

See final example on JSFiddle.

BTW, remove all line breaks and tabs from your code when you use inline-block, because it will cause spaces between your blocks.

like image 3
Roman Bekkiev Avatar answered Nov 19 '22 04:11

Roman Bekkiev