Here is my attempt in vanilla JS (tested on Chrome and Firefox)
It mainly works only with CSS transitions by the transform
property for the selected element and over opacity
for all other elements. FadeOut / In is launched while the selected item moves as you indicated.
CodePen Demo
CSS
main { display: flex; flex-wrap: wrap; border: 1px solid #ccc; } div { background: #a0c6df; width: 100px; height: 100px; border: 2px #8fa0c6 dashed; margin: 10px; opacity: 1; cursor: pointer; transition: all 1s; } main.fadeout div:not(.current) { opacity: 0; cursor: default; }
Js
var main = document.querySelector('main'); var boxes = document.querySelectorAll('main div'); var animationIsRunning = false; var getBoxPosition = function() { [].forEach.call(boxes, function(b) { var gBCR = b.getBoundingClientRect(); b.dataset.top = gBCR.top; b.dataset.left = gBCR.left; }); } window.addEventListener('resize', function() { var dc; getBoxPosition(); if (dc = main.querySelector('div.current')) { main.classList.remove('fadeout'); dc.classList.remove('current'); dc.style.transform = 'translate(0,0)'; } }); main.addEventListener('click', function(evt) { var b = evt.target, left = 0, top = 0; if (b.nodeName.toLowerCase() !== 'div') { return false; } if ( main.querySelector('.current') && !b.classList.contains('current') ) { return false; } if (!animationIsRunning) { animationIsRunning = true; b.classList.toggle('current'); main.classList.toggle('fadeout'); if (b.classList.contains('current')) { left = b.dataset.left; top = b.dataset.top; } b.style.transform = 'translate(-'+ left +'px, -'+ top +'px)'; } }); main.addEventListener('transitionend', function() { animationIsRunning = false; }); getBoxPosition();
source share