Skip to content

Instantly share code, notes, and snippets.

@kcmr
Created May 25, 2016 23:22
Show Gist options
  • Select an option

  • Save kcmr/4217eaa6f5ce296e3044c3c306f0cb91 to your computer and use it in GitHub Desktop.

Select an option

Save kcmr/4217eaa6f5ce296e3044c3c306f0cb91 to your computer and use it in GitHub Desktop.
WIP FlIP animations
<div class="frame">
<div class="actions">
<button class="btn btn--positive btn-open">Open modal</button>
<button class="btn btn--positive btn-toggle-collapsed">Toggle expanded</button>
</div>
<div class="modal is-closed is-collapsed" hidden aria-hidden="true">
<div class="modal__content">
<div class="modal__title">
<h1 class="modal__heading">Modal title</h1>
<button class="btn btn--transparent btn-close">&times;</button>
</div>
<div class="modal__body">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat quidem tempore, id. Quia dolore ipsam eveniet, iusto laborum explicabo aut, voluptatum, fugiat sapiente reiciendis recusandae molestias delectus sed vero aspernatur!</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat quidem tempore, id. Quia dolore ipsam eveniet, iusto laborum explicabo aut, voluptatum, fugiat sapiente reiciendis recusandae molestias delectus sed vero aspernatur!</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat quidem tempore, id. Quia dolore ipsam eveniet, iusto laborum explicabo aut, voluptatum, fugiat sapiente reiciendis recusandae molestias delectus sed vero aspernatur!</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat quidem tempore, id. Quia dolore ipsam eveniet, iusto laborum explicabo aut, voluptatum, fugiat sapiente reiciendis recusandae molestias delectus sed vero aspernatur!</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat quidem tempore, id. Quia dolore ipsam eveniet, iusto laborum explicabo aut, voluptatum, fugiat sapiente reiciendis recusandae molestias delectus sed vero aspernatur!</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat quidem tempore, id. Quia dolore ipsam eveniet, iusto laborum explicabo aut, voluptatum, fugiat sapiente reiciendis recusandae molestias delectus sed vero aspernatur!</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat quidem tempore, id. Quia dolore ipsam eveniet, iusto laborum explicabo aut, voluptatum, fugiat sapiente reiciendis recusandae molestias delectus sed vero aspernatur!</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat quidem tempore, id. Quia dolore ipsam eveniet, iusto laborum explicabo aut, voluptatum, fugiat sapiente reiciendis recusandae molestias delectus sed vero aspernatur!</p>
</div>
<div class="modal__footer">
<button class="btn btn--positive">Accept</button>
<button class="btn btn--negative">Cancel</button>
</div>
</div>
<div class="modal__backdrop"></div>
</div>
</div>
(function(d) {
var btnOpen = d.querySelector('.btn-open');
var btnExpand = d.querySelector('.btn-toggle-collapsed');
var btnClose = d.querySelector('.btn-close');
var modal = d.querySelector('.modal');
var modalContent = d.querySelector('.modal__content');
var modalBackdrop = d.querySelector('.modal__backdrop');
var flipped = false;
btnOpen.addEventListener('click', openModal);
btnExpand.addEventListener('click', expandModal);
btnClose.addEventListener('click', closeModal);
function flip() {
var first = modalContent.getBoundingClientRect();
// get last position
modal.classList.remove('is-collapsed');
modal.classList.add('is-expanded');
var last = modalContent.getBoundingClientRect();
modal.classList.remove('is-expanded');
modal.classList.add('is-collapsed');
var invert = {};
invert.y = first.top - last.top;
invert.sy = first.height - last.height;
modalContent.style.transformOrigin = '0 100%';
modalContent.style.transform = 'translateY(-' + invert.y + 'px)';
flipped = true;
}
function openModal() {
modal.hidden = false;
modal.removeAttribute('aria-hidden');
requestAnimationFrame(function() {
setTimeout(function() {
modal.classList.remove('is-closed');
// !flipped && flip();
}, 1);
});
}
function expandModal() {
modal.classList.toggle('is-collapsed');
modal.classList.toggle('is-expanded');
}
function closeModal() {
modal.classList.add('is-closed', 'is-collapsed');
modal.classList.remove('is-expanded');
requestAnimationFrame(function() {
setTimeout(function() {
modal.hidden = true;
modal.setAttribute('aria-hidden', 'true');
}, 380);
});
}
}(document));
html,
body { height: 100%; }
body {
font-family: Roboto, sans-serif;
font-weight: 300;
margin: 0;
background: #f0f0f0;
display: flex;
flex-direction: column;
align-items: center;
}
[hidden] { display: none !important; }
.frame {
width: 360px;
height: 640px;
margin: auto;
border: 1px solid #ccc;
background: #E4E4E4;
box-sizing: border-box;
position: relative;
overflow: hidden;
}
.modal {
position: absolute;
bottom: 0;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: flex-end;
&__content {
transition: transform 360ms cubic-bezier(0,0,0.3,1);
will-change: transform;
transform-origin: bottom;
align-self: flex-end;
display: flex;
height: 100%;
flex-direction: column;
background: #fff;
overflow: hidden;
}
&__title {
padding: 20px;
box-shadow: 0 1px 7px rgba(black, .1), inset 0 -1px 0 rgba(black, .1);
display: flex;
justify-content: space-between;
align-items: center;
}
&__heading {
margin: 0;
font-size: 20px;
font-weight: 500;
}
&__body {
flex: 1;
overflow-y: auto;
padding: 0 20px;
}
&__footer {
padding: 20px;
display: flex;
justify-content: flex-end;
box-shadow: 0 -1px 7px rgba(black, .1), inset 0 1px 0 rgba(black, .1);
}
// states
&.is {
&-collapsed {
.modal__body {
max-height: calc(50% - 146px);
}
.modal__content {
transform: translateY(50%);
}
}
&-expanded {
z-index: 2;
.modal__body {
max-height: unset;
}
.modal__content {
transform: none;
}
}
&-closed {
.modal__content {
transform: translateY(100%);
}
}
}
}
.btn {
background: none;
border: 0;
padding: 10px;
overflow: visible;
min-height: 0;
font-family: inherit;
font-size: 14px;
font-weight: 300;
text-transform: uppercase;
margin-left: 10px;
border-radius: 3px;
box-shadow: inset 0 -3px 0 rgba(0,0,0,.1);
color: #fff;
outline: none;
cursor: pointer;
min-width: 100px;
white-space: nowrap;
&::-moz-focus-inner {
padding: 0;
border: 0;
}
&:active {
box-shadow: inset 0 3px 0 rgba(0,0,0,.1)
}
&--positive {
background: #38C0C3;
}
&--negative {
background: #F56A74;
}
&--transparent {
color: #000;
&:active { box-shadow: none; }
}
&-close {
font-size: 28px;
font-weight: 300;
min-width: unset;
box-shadow: none;
line-height: 0;
width: 30px;
height: 30px;
padding: 0;
margin-right: -5px;
opacity: .5;
&:active {
opacity: 1;
}
}
}
.actions {
position: absolute;
z-index: 1;
transform: translate(-50%, 50%);
left: 50%;
top: 20px;
margin: 0;
display: flex;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment