Last active
November 16, 2016 07:06
-
-
Save ahallora/d1a78879c86982e1e9aaab7125de4a2d to your computer and use it in GitHub Desktop.
Rearrange List with smooth-sliding animations
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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'); | |
}); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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