Skip to content

Instantly share code, notes, and snippets.

@ahallora
Last active November 16, 2016 07:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ahallora/d1a78879c86982e1e9aaab7125de4a2d to your computer and use it in GitHub Desktop.
Save ahallora/d1a78879c86982e1e9aaab7125de4a2d to your computer and use it in GitHub Desktop.
Rearrange List with smooth-sliding animations
<h1>Rearrange List with smooth-sliding animations</h1>
<p>Click on the tiles to randomly make them move among each other with a smooth 3D-like effect. Transitions are hardware accelerated with CSS3 and accompanied with under the hood DOM-manipulation.</p>
<p>Author: Anders Holm-Jensen, allora.dk - License: MIT</p>
<ul id="list">
<li>Anders And</li>
<li>Andersine And</li>
<li>Joakim von And</li>
<li>Fætter Højben</li>
<li>Rip, rap og Rup</li>
</ul>
var fixedItemHeight = 50;
function positionAllListItems(sel) {
$(sel).each(function(i,item) {
$(item).css({
'top': (fixedItemHeight * i)+'pt',
'height': fixedItemHeight + 'pt'
});
});
}
$(function() {
positionAllListItems('#list li');
$('#list').on('click','li',function(e) {
var rnd = Math.floor(Math.random() * 5);
animateListChange( this, 'li:eq('+rnd+')', '#list li' );
});
});
function animateListChange( fromSelector, toSelector, listSelector ) {
var $el = $(fromSelector) || null;
var $target = $(toSelector) || null;
var $list = $(listSelector) || null;
if(!$el || !$target || !$list) return false; // do nothing
var currentIndex = $list.index( $el );
var newIndex = $list.index( $target[0] );
if(parseInt(currentIndex) === parseInt(newIndex)) return false; // do nothing
var direction = (newIndex > currentIndex) ? 'down' : 'up';
var animationDuration = parseFloat(getComputedStyle($el[0])['transitionDuration']);
if(animationDuration <= 1) animationDuration = animationDuration * 1000; // webkit shows duration in seconds, not ms
var $others = (direction === 'up') ? $el.prevUntil($target).add($target) : $el.nextUntil($target).add($target);
var newPos = (direction === 'up') ? Math.max(0,(newIndex - currentIndex)) : 0;
var otherPos = (direction === 'up') ? (newIndex * fixedItemHeight) + fixedItemHeight : (currentIndex * fixedItemHeight);
$others.removeClass('focusAnimation otherAnimation');
$others.each(function(i,item) {
$(item).addClass('otherAnimation')
.css('z-index','-1').css('top', otherPos + (i * fixedItemHeight) +'pt')
.delay(animationDuration)
.queue(function() {
$(this).dequeue();
$(this).css('z-index','0').removeClass('focusAnimation otherAnimation');
})
;
});
$el.removeClass('focusAnimation otherAnimation')
.addClass('focusAnimation')
.css('z-index','3').css('top', (newIndex * fixedItemHeight) + (newPos * fixedItemHeight)+'pt')
.delay(animationDuration)
.queue(function() {
console.log('done!');
if(direction==='up') {
$others.first().before($el);
} else {
$others.last().after($el);
}
$(this).dequeue();
positionAllListItems(listSelector);
$el.css('z-index','0').removeClass('focusAnimation otherAnimation');
});
}
body {
font-family: 'Roboto', 'Open Sans', sans-serif;
margin: 0;
}
h1 {
font-size: 12pt;
margin: 16pt 8pt;
}
p {
margin: 16pt 8pt;
}
#list {
position: relative;
box-sizing: border-box;
width: 50%;
margin: auto;
}
#list li {
cursor: pointer;
position: absolute;
top: 0;
left: 0;
right: 0;
display: block;
height: 50pt;
width: auto;
line-height: 50pt;
text-align: center;
background-color: #eee;
border-bottom: 1pt solid #808080;
box-sizing: border-box;
color: #000;
transition: top 800ms cubic-bezier(0.3, 0.5, 0, 1), background-color 800ms cubic-bezier(0.3, 0.5, 0, 1);
}
.votes {
width: 50%;
float: left;
}
.timestamp {
width: 50%;
float: left;
}
#list li:nth-child(2n) {
background-color: #dedede;
}
#list li:last-child {
border-bottom: 0;
}
.otherAnimation {
animation: scaleDown 800ms;
}
.focusAnimation {
animation: scaleUp 800ms;
}
@keyframes scaleDown {
0% {
transform: scale(1);
}
60% {
transform: scale(0.9);
}
100% {
transform: scale(1);
}
}
@keyframes scaleUp {
0% {
transform: scale(1);
box-shadow: 0 0 0 rgba(0,0,0,0);
}
60% {
transform: scale(1.1);
box-shadow: 0 0 12px rgba(0,0,0,0.2);
}
100% {
transform: scale(1);
box-shadow: 0 0 0 rgba(0,0,0,0);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment