I have multiple lists on a page. The number of lists that could exist is arbitrary, but would likely be limited to 10.
There are two views of this page:
A user should be able to toggle between the two modes. I have this [roughly] working - they are collapsed into a single list, but they lose their styling from their parent/origin list.
Ideally, I'd love the transition between the two modes to be animated; that is, when the user clicks the mode toggle button, all of the list items from each lane animate/collapse into a single, alphabetized list. Once in Mode 2 (single list mode), clicking the toggle again would, ideally, animate the list items back into their original lists.
Here's a Fiddle I've been working on.
In my code, I have four lists, with a hidden <ul>
that the items can collapse into. I'm having trouble figuring out how and where the animation goes.
$(function() {
$("button").on("click", function() {
if($(this).text() == "Mode 1") {
$("#list").show();
$("li").remove().clone().appendTo("#list");
$("ul:not(#list)").hide();
$("button").text("Mode 2");
}
});
});
<button>Mode 1</button>
// The hidden list
<ul id="list"></ul>
<ul id="red">
<li>A</li>
...
</ul>
<ul id="blue">
<li>K</li>
...
</ul>
<ul id="gray">
<li>U</li>
...
</ul>
<ul id="green">
<li>AA</li>
...
</ul>
EDIT: I guess I should specify the animation I'm aiming for. I'd like each individual list item to "fly" from its origin position into the single, collapsed list.
Alright Jon, for Each piece to animate from it's current position to a new position, you have get each element's offset, make them position:absolute;
then animate them to the correct place.
Here's the jQuery to accompany it. this also keeps your HTML layout the same:
$(function() {
$("button").on("click", function() {
if($(this).text() == "Mode 1") {
var elem = $('ul:not(#list) > li'),
elemH = elem.first().outerHeight(),
list1Last = {x:$('#red > li:last-of-type').offset().left,
y:$('#red > li:last-of-type').offset().top},
oElem = {x:0, y:0, w:0, h:0}
$('ul:not(#red)').each(function(e){
$(this).find('li').each(function(i){
oElem = {x:$(this).offset().left,
y:$(this).offset().top,
w:$('#red').width(),
h:$(this).outerHeight()}
console.log(oElem.x, oElem.y);
$(this).css({"position":"absolute",
"top":oElem.y+(oElem.h*i)+"px",
"left":oElem.x+"px",
"width":oElem.w+"px"});
$(this).delay(200*i).animate({"top":(list1Last.y+elemH)*e+(i*elemH)+"px",
"left":list1Last.x+"px"}, 200);
});
})
} else {
}
});
});
What this does is it gets each elements current position using offset()
, then I change the CSS to make them position:absolute;
and give them a left
and top
value. This seamlessly makes them absolutely positioned without any bumping. Then right away, I animate them to their new spot, almost like they're flying as you say. There's ways to get them to fly one by one, but that will require a bit more editing.