Возможно ли анимировать flexbox вставляет & удаляет?
Когда я удаляю элемент из flexbox, остальные элементы "привязываются" к новым позициям немедленно, а не оживляют.
Концептуально, поскольку элементы меняют свои позиции, я ожидал бы перехода к ним.
Я установил свойство перехода на все задействованные элементы (flexbox и дети)
Есть ли способ активировать изменения (добавляет и удаляет) в flexbox? Это на самом деле showstopper для меня и один недостающий кусок с flexbox.
Ответы
Ответ 1
Я установил демо-версию @skyline3000 на основе этого примера из Treehouse. Не уверен, что это изменится, если браузер изменится, но это, по-видимому, предназначено для анимации изменений размера гибкого диска:
http://jsfiddle.net/2gbPg/2/
Также я использовал jQuery, но это технически не требуется.
.flexed {
background: grey;
/* The border seems to cause drawing artifacts on transition. Probably a browser bug. */
/* border: 1px solid black; */
margin: 5px;
height: 100px;
flex-grow: 1;
transition: flex-grow 1000ms linear;
}
.removed {
/* Setting this to zero breaks the transition */
flex-grow: 0.00001;
}
Одно замечание о CSS - вы не можете перейти к flex-grow
нуля, это не будет переход, он просто исчезнет. Вам нужно просто поставить очень маленькую ценность. Также, кажется, есть артефактная ошибка при рисовании границ, поэтому я использовал фон в этом случае.
Ответ 2
Помните, что спецификации Flexible Box Model и Grid Layout постоянно меняются, даже свойства и допустимые значения. Реализации браузера далеки от завершения. При этом вы можете перейти к свойству flex
, чтобы элементы проходили плавно, а затем просто прослушайте TransitionEnd
, чтобы окончательно удалить node из дерева DOM.
Вот пример JSFiddle, работающий в Chrome 21: http://jsfiddle.net/5kJjM/ (щелкните по среднему div)
var node = document.querySelector('#remove-me');
node.addEventListener('click', function(evt) {
this.classList.add('clicked');
}, false);
node.addEventListener('webkitTransitionEnd', function(evt) {
document.querySelector('#flexbox').removeChild(this);
}, false);
#flexbox {
display: -webkit-flex;
-webkit-flex-flow: row;
}
.flexed {
border: 1px solid black;
height: 100px;
-webkit-flex: 1 0 auto;
-webkit-transition: -webkit-flex 250ms linear;
}
.clicked {
-webkit-flex: 0 0 auto;
}
<div id="flexbox">
<div class="flexed"></div>
<div class="flexed" id="remove-me"></div>
<div class="flexed"></div>
</div>
Ответ 3
Я случайно получил его для работы простым способом. В принципе, вы устанавливаете width:0;flex-grow:1
и, конечно, добавляете transition:all 2s;
и что это. Это любопытный хак.
Посмотрите, как работает
Ответ 4
Я сделал код, который анимирует элементы, когда вы его удаляете, посмотрите: https://codepen.io/MauriciAbad/pen/eQoQbK
Он может быть оптимизирован, но работает. ; D
HTML
<div class="container">
<div id="0"></div>
<div id="1"></div>
... more divs ...
</div>
CSS
.container{
display: flex;
flex-wrap: wrap;
}
.container > div{
flex-grow: 1;
transform-origin: left top;
}
JavaScript
var cards = document.querySelectorAll('.container > div');
cards.forEach((card) => {
card.addEventListener('click', () => {removeCard(card);});
});
var cardsOldInfo = //example content
{"cardId": {
"x": 100,
"y": 200,
"width": 100
}
};
var cardsNewInfo = cardsOldInfo;
function removeCard(card){
cardsOldInfo = getCardsInfo();
card.parentNode.removeChild(card);
cardsNewInfo = getCardsInfo();
moveCards();
}
function getCardsInfo(){
updateCards();
let cardsInfo = {};
cards.forEach((card) => {
var rect = card.getBoundingClientRect();
cardsInfo[card.id] = {
"x": rect.left,
"y": rect.top,
"width": (rect.right - rect.left)
};
});
return cardsInfo;
}
function moveCards(){
updateCards();
cards.forEach((card) => {
card.animate([
{
transform: 'translate(${cardsOldInfo[card.id].x - cardsNewInfo[card.id].x}px, ${cardsOldInfo[card.id].y -cardsNewInfo[card.id].y}px) scaleX(${cardsOldInfo[card.id].width/cardsNewInfo[card.id].width})'
},
{
transform: 'none'
}
], {
duration: 250,
easing: 'ease-out'
});
});
}
function updateCards(){
cards = document.querySelectorAll('.container > div');
}