Skip to content

Instantly share code, notes, and snippets.

@MidnightDesign
Created October 2, 2017 19:41
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 MidnightDesign/6e3f3c2618aa150b9ed2274127cbbaee to your computer and use it in GitHub Desktop.
Save MidnightDesign/6e3f3c2618aa150b9ed2274127cbbaee to your computer and use it in GitHub Desktop.
interface CSSStyleDeclaration {
willChange: string;
}
function positionAndDimensionsFromClientRect(element: HTMLElement, sourceClientRect: ClientRect) {
element.style.top = sourceClientRect.top.toString(10) + 'px';
element.style.left = sourceClientRect.left.toString(10) + 'px';
element.style.width = sourceClientRect.width.toString(10) + 'px';
element.style.height = sourceClientRect.height.toString(10) + 'px';
}
function measureTargetClientRect(destination: Element, element: HTMLElement, before: Element | null) {
destination.insertBefore(element, before);
return element.getBoundingClientRect();
}
function clearPositionAndDimensions(element: HTMLElement) {
['top', 'left', 'width', 'height', 'position', 'transition', 'will-change', 'border-radius'].forEach(property => {
element.style.removeProperty(property);
});
}
function transition(element: HTMLElement, destination: Element, before: Element | null = null) {
const sourceClientRect = element.getBoundingClientRect();
const destinationClientRect = measureTargetClientRect(destination, element, before);
element.ownerDocument.body.insertBefore(element, null);
element.style.position = 'absolute';
element.style.willChange = 'top, left, width, height';
const transitionTime = '.5s';
element.style.transition = `top ${transitionTime},
left ${transitionTime},
width ${transitionTime},
height ${transitionTime}`;
positionAndDimensionsFromClientRect(element, sourceClientRect);
requestAnimationFrame(() => {
element.addEventListener('transitionend', () => {
clearPositionAndDimensions(element);
destination.insertBefore(element, before);
});
positionAndDimensionsFromClientRect(element, destinationClientRect);
});
}
const el = document.querySelector('.element');
if (el !== null) {
const containers = [
document.querySelector('.source-container'),
document.querySelector('.destination-container'),
];
document.addEventListener('click', () => {
const destinationContainer = el.parentElement === containers[0] ? containers[1] : containers[0];
if (el instanceof HTMLElement && destinationContainer !== null) {
transition(el, destinationContainer);
}
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment