user4893295
user4893295

Reputation: 651

Animate append to list

How could I animate the moving from one list to another, ideally using Jquery animate? Given the following code I know I should be able to use animate to move the listitem to the position it would take up in the receiving list... but how do I get the coordinates, and translate them into css values?

$('#list1').on('click', 'li', function() {
 // $(this).animate( ??? )
 $(this).appendTo($('#list2'));
})

$('#list2').on('click', 'li', function() {
 // $(this).animate( ??? )
 $(this).appendTo($('#list1'));
})
ul {
  background-color: grey;
  color: black;
  padding: 10px;
  margin: 50px;
  width: 20%;
  display: inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="list1">
  <li>one</li>
  <li>two</li>
  <li>three</li>
</ul>

<ul id="list2">
  <li>four</li>
  <li>five</li>
  <li>six</li>
</ul>

jsfiddle

Upvotes: 1

Views: 338

Answers (1)

Blauharley
Blauharley

Reputation: 4256

It's Saturday evening (local-time) and I want to help someone, I took your question seriously and provided an example along with explanations at each step below.

The most important thing in this example is to use an absolute positioned list-element (in this example #animatedList) so that this animated list-element does not interact with other elements. Furthermore getting the correct coordinates you have to take margins/paddings of the original elements into consideration as well.

You have to click on the Button "Run code snippet" to execute this example. Hope this helps you:

$('#list1').on('click', 'li', function() {
  var startElement = $(this);
  var endElement = $('#list2');
  startAnimation(startElement, endElement);
})

$('#list2').on('click', 'li', function() {
  var startElement = $(this);
  var endElement = $('#list1');
  startAnimation(startElement, endElement);
})

function startAnimation(startElement, endElement){
  var clickedListElement = startElement;
  // copy content of original element into animated list-element 
  var contentCopy = clickedListElement.text();
  var startCoords = getCoordsOfElement(clickedListElement);
  // if there are no li-elements anymore take the position of the whole list instead otherwise take last list-element
  var endCoords;
  if(endElement.find('li:last').length)endCoords = getCoordsOfElement(endElement.find('li:last'));
  else endCoords = getCoordsOfElement(endElement);
  // hide original element because the animated list-element will be shown 
  clickedListElement.css('visibility','hidden');
  showAnimation(contentCopy,startCoords,endCoords,function(){
   // the last step: copy the original element to it's destination and show it again because the animation is over
   clickedListElement.appendTo(endElement).css('visibility','visible');
  });
}

function getCoordsOfElement(element){
  var endCoords = element.offset();
  // because the margin and paddings of these lists distorts the calculated position you have to take them into consideration
  // and therefore we subtract them for top and left
  var marginOffsetTop = 50;
  endCoords.top -= marginOffsetTop;
  var marginOffsetLeft = 50;
  endCoords.left -= marginOffsetLeft;
  // the same happens with padding 
  var paddingOffsetTop = 10;
  endCoords.top -= paddingOffsetTop;
  var paddingOffsetLeft = 10;
  endCoords.left -= paddingOffsetLeft;
  return endCoords;
}

function showAnimation(contentCopy,startCoord,endCoord,callback){
 var list = $('#animatedList');
 // copy text of originel element into animated-list-element
 list.find('li').text(contentCopy);
 // set animated-list/element at the same position as the original clicked element
 list.css('top',startCoord.top+'px').css('left',startCoord.left+'px').show();
 list.animate({
   top: endCoord.top+'px',
   left: endCoord.left+'px'
 }, 1000, function(){
    // animation is finished here
    list.hide();
    callback();
 });
}
ul {
  background-color: grey;
  color: black;
  padding: 10px;
  margin: 50px;
  width: 20%;
  display: inline-block;
}

#animatedList{
  display:none;
  position:absolute;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="list1">
<li>one</li>
<li>two</li>
<li>three</li>
</ul>

<ul id="list2">
<li>four</li>
<li>five</li>
<li>six</li>
</ul>

<ul id="animatedList">
<li></li>
</ul>

Upvotes: 3

Related Questions