Distance based transition out
by Kenneth Luplau-Brøgger
HTML
<div id="app">
<div>
<div class="grid">
<div v-for="row in grid" class="row">
<div v-for="cell in row" class="cell" @click="activate(cell)">
<transition name="fade">
<div class="cellWrap" v-if="!cell.hidden">
<div class="cellContent">
{{ cell.x }} <span>/</span> {{ cell.y }}
</div>
</div>
</transition>
</div>
</div>
</div>
</div>
</div>
SCSS
body {
padding: 20px;
font-family: Helvetica;
color: #fff;
background: #20262E;
}
.grid {
width: 500px;
height: 500px;
.row {
overflow: hidden;
}
}
.cell {
width: 31%;
height: 0;
padding-bottom: 31%;
margin: 1%;
float: left;
position: relative;
.cellWrap {
background: #35404e;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
cursor: pointer;
&.isAnimating {
transition: transform cubic-bezier(0.68, -0.55, 0.265, 1.55) 0.5s;
}
&.isActive {
transform: scale(1.1);
}
}
.cellContent {
align-self: center;
font-size: 2rem;
font-weight: bold;
span {
color: #4a4a4a;
}
}
}
.fade-leave-active {
transition:
opacity .3s cubic-bezier(0.6, -0.28, 0.735, 0.045),
transform .3s cubic-bezier(0.6, -0.28, 0.735, 0.045);
}
.fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
opacity: 0;
transform: scale(0.75);
}
.fade-enter-active {
transition:
opacity .5s cubic-bezier(0.175, 0.885, 0.32, 1.275),
transform .5s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
.fade-enter /* .fade-leave-active below version 2.1.8 */ {
opacity: 0;
transform: scale(0.75);
}
Vue
const grid = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
new Vue({
el: "#app",
data: {
activeCell: null,
isAnimating: false,
grid: []
},
mounted() {
this.buildGrid();
this.animateIn();
},
methods: {
buildGrid() {
let rows = Array.from(Array(3));
rows.forEach((row, y) => {
rows[y] = Array.from(Array(3)).map((row, x) => {
return {
hidden: true,
x,
y
}
});
});
this.grid = rows;
},
eachCell(fn, otherCell) {
if (!otherCell) {
otherCell = {
x: 0,
y: 0
}
}
this.grid.forEach((row) => {
row.forEach((cell) => {
const dx = otherCell.x - cell.x;
const dy = otherCell.y - cell.y;
const distance = Math.sqrt(dx * dx + dy * dy);
fn(cell, distance);
})
})
},
animateIn(fromCell) {
this.eachCell((cell, distance) => {
setTimeout(() => {
cell.hidden = false;
}, Math.round(distance * 70));
}, fromCell)
},
activate(currentCell) {
this.activeCell = currentCell;
this.eachCell((cell, distance) => {
if (currentCell === cell) {
return;
}
// remove
setTimeout(() => {
cell.hidden = true;
}, Math.round(distance * 70));
}, currentCell)
// animate in again
setTimeout(() => {
this.activeCell = null;
this.animateIn(currentCell);
}, 2000);
}
}
})