<link href='//fonts.googleapis.com/css?family=Signika+Negative:300,400' rel='stylesheet' type='text/css'>
<h1>GSAP FLIP Demo</h1>
<div id="flex">
<div id="container1">
<div>1</div><div>2</div><div>3</div><div>4</div><div>5</div><div>6</div><div>7</div>
</div>
<div id="container2"></div>
</div>
body {
color: white;
background-color: black;
padding: 0 20px;
font-family: 'Signika Negative';
}
#flex {
display: flex;
overflow: hidden;
}
#container1, #container2 {
width: 50%;
}
#container1 div, #container2 div {
margin-bottom: 3px;
height: 26px;
background-color: #777;
border-radius: 13px;
border: 1px solid #333;
text-align: center;
}
flip("#container1 div", doMyStuff, {stagger: 0.1, duration: 1.5, ease: "elastic", delay: 1});
/*
Copy this to your project. Pass in the elements (selector text or NodeList or Array),
then a function/callback that actually performs your DOM changes, and optionally a vars
object that contains any of the following properties to customize the transition:
- duration [Number] - duration (in seconds) of each animation
- stagger [Number | Object | Function] - amount to stagger the starting time of each animation. You may use advanceds staggers too (see https://codepen.io/GreenSock/pen/jdawKx)
- ease [Ease] - controls the easing of the animation. Like "power2.inOut", or "elastic", etc.
- onComplete [Function] - a callback function that should be called when all the animation has completed.
- delay [Number] - time (in seconds) that should elapse before any of the animations begin.
This function will return a Timeline containing all the animations.
*/
function flip(elements, changeFunc, vars) {
elements = gsap.utils.toArray(elements);
vars = vars || {};
let tl = gsap.timeline({onComplete: vars.onComplete, delay: vars.delay || 0}),
bounds = elements.map(element => {
let b = element.getBoundingClientRect();
element._flip && element._flip.progress(1);
element._flip = tl;
return b;
}),
copy = {},
p;
changeFunc();
for (p in vars) {
p !== "onComplete" && p !== "delay" && (copy[p] = vars[p]);
}
copy.x = (i, element) => "+=" + (bounds[i].left - element.getBoundingClientRect().left);
copy.y = (i, element) => "+=" + (bounds[i].top - element.getBoundingClientRect().top);
return tl.from(elements, copy);
}
//this function just takes all the <div> elements from #container1 and puts them into #container2 in a randomized order.
function doMyStuff() {
var elements = gsap.utils.toArray("#container1 div"),
newContainer = document.querySelector("#container2"),
i;
elements.sort(function() { return 0.5 - Math.random(); });
for (i = 0; i < elements.length; i++) {
newContainer.appendChild(elements[i]);
}
}
This Pen doesn't use any external CSS resources.