CSS анимации заканчиваются вместе, хотя они запускаются в разное время - PullRequest
0 голосов
/ 30 июня 2018

У меня есть несколько элементов одного типа, и я хочу, чтобы они использовали одну и ту же анимацию CSS, но я хочу, чтобы они запускали / заканчивали анимацию в разное время.

Кодовый код для следующего кода

HTML:

<div class="container">
    <div class="box hidden"></div>
</div>
<div class="container">
    <div class="box hidden"></div>
</div>
<div class="container">
    <div class="box hidden"></div>
</div>

CSS:

.container {
    width: 100px;
    height: 100px;
    margin-bottom: 20px;
}

.box {
    width: 100%;
    height: 100%;
}

.box.hidden {
    visibility: hidden;
}

.box {
    animation: growIn 1s;
    animation-timing-function: cubic-bezier(.46,.13,.99,.83);
    transition: all .2s cubic-bezier(0.215, 0.61, 0.355, 1);
}

.container:first-child .box {
    background-color: green;
}

.container:nth-child(2) .box {
    background-color: orange;
}

.container:nth-child(3) .box {
    background-color: red;
}

@keyframes growIn {
    from {
        transform: scale(0);
    }
    to {
        transform: scale(1);
    }
}

Элементы box начинаются как скрытые, и затем, используя javascript, я удаляю это имя класса из разных полей, но в разное время:

const boxes = document.querySelectorAll(".box");
boxes.forEach(box => {
    setTimeout(() => box.classList.remove("hidden"), Math.random() * 1000);
});

Что происходит, так это то, что все 3 блока заканчивают свою анимацию в одно и то же время. Анимация начинается в разное время, но все заканчивается вместе.

Почему это?
Если я делаю то же самое, но добавляю имя класса вместо его удаления (чтобы запустить анимацию), то оно ведет себя так, как я хочу.
Есть идеи? Спасибо.

Ответы [ 2 ]

0 голосов
/ 30 июня 2018

Просто потому, что все анимации уже запущены одновременно . Использование visibility:hidden не помешает запустить анимацию и заставит ее запуститься позже, когда элемент станет видимым. То же самое произойдет с непрозрачностью, например:

const boxes = document.querySelectorAll(".box");
boxes.forEach(box => {
  setTimeout(() => box.classList.remove("hidden"), Math.random() * 5000);
});
.container {
  width: 100px;
  height: 100px;
  margin-bottom: 20px;
}

.box {
  width: 100%;
  height: 100%;
}

.box.hidden {
  opacity: 0.1;
}

.box {
  animation: growIn 5s;
  animation-timing-function: cubic-bezier(.46, .13, .99, .83);
  transition: all .2s cubic-bezier(0.215, 0.61, 0.355, 1);
}

.container:first-child .box {
  background-color: green;
}

.container:nth-child(2) .box {
  background-color: orange;
}

.container:nth-child(3) .box {
  background-color: red;
}

@keyframes growIn {
  from {
    transform: scale(0);
  }
  to {
    transform: scale(1);
  }
}
<div class="container">
  <div class="box hidden"></div>
</div>
<div class="container">
  <div class="box hidden"></div>
</div>
<div class="container">
  <div class="box hidden"></div>
</div>

Вы можете увидеть поведение, которое вы ищете, если вместо этого используете свойство display:

const boxes = document.querySelectorAll(".box");
boxes.forEach(box => {
  setTimeout(() => box.classList.remove("hidden"), Math.random() * 3000);
});
.container {
  width: 100px;
  height: 100px;
  margin-bottom: 20px;
}

.box {
  width: 100%;
  height: 100%;
}

.box.hidden {
  display:none;
}

.box {
  animation: growIn 1s;
  animation-timing-function: cubic-bezier(.46, .13, .99, .83);
  transition: all .2s cubic-bezier(0.215, 0.61, 0.355, 1);
}

.container:first-child .box {
  background-color: green;
}

.container:nth-child(2) .box {
  background-color: orange;
}

.container:nth-child(3) .box {
  background-color: red;
}

@keyframes growIn {
  from {
    transform: scale(0);
  }
  to {
    transform: scale(1);
  }
}
<div class="container">
  <div class="box hidden"></div>
</div>
<div class="container">
  <div class="box hidden"></div>
</div>
<div class="container">
  <div class="box hidden"></div>
</div>

Из спецификации :

Свойство visibility указывает, будут ли поля, сгенерированные элемент отображается .

Невидимые поля по-прежнему влияют на макет (установите От свойства 'display' до 'none' до полное подавление генерации блока ).

Таким образом, поле всегда генерируется при использовании visibility в отличие от использования display.

И если мы проверим спецификацию , относящуюся к анимации, мы найдем это:

Установка для свойства display значения none приведет к прекращению работы анимация применяется к элементу и его потомкам. Если элемент имеет отображение none, обновляя display до значения, отличного от none запустит все анимации, примененные к элементу , по имени animation свойство, а также все анимации, примененные к потомкам с дисплей отличный от нуля.

0 голосов
/ 30 июня 2018

Проблема в том, что ваши элементы box начинаются с класса .box, который является классом анимации. Это означает, что анимация начинается с момента загрузки элементов, независимо от того, скрыты они или нет. это означает, что когда вы удалите «скрытый» класс, они просто проявят себя в какой-то момент во время анимации.

Что вы хотите сделать, это переименовать класс анимации, например, «grower»

.grower {
    animation: growIn 1s;
    animation-timing-function: cubic-bezier(.46,.13,.99,.83);
    transition: all .2s cubic-bezier(0.215, 0.61, 0.355, 1);
}

Затем включите это в цикл javascript:

const boxes = document.querySelectorAll(".box");
boxes.forEach(box => {
  setTimeout(() => {
    box.classList.remove("hidden");
    box.classList.add("grower"); }, Math.random() * 1000);
});

Вот фрагмент кода, чтобы показать его в действии:

const boxes = document.querySelectorAll(".box");
boxes.forEach(box => {
  setTimeout(() => {
    box.classList.remove("hidden");
    box.classList.add("grower"); }, Math.random() * 1000);
});
.container {
  width: 100px;
  height: 100px;
  margin-bottom: 20px;
}

.box {
  width: 100%;
  height: 100%;
}

.box.hidden {
  visibility: hidden;
}

.grower {
	animation: growIn 1s;
	animation-timing-function: cubic-bezier(.46,.13,.99,.83);
	transition: all .2s cubic-bezier(0.215, 0.61, 0.355, 1);
}

.container:first-child .box {
  background-color: green;
}

.container:nth-child(2) .box {
  background-color: orange;
}

.container:nth-child(3) .box {
  background-color: red;
}

@keyframes growIn {
  from {
		transform: scale(0);
  }
  to {
		transform: scale(1);
  }
}
<div class="container">
  <div class="box hidden"></div>
</div>
<div class="container">
  <div class="box hidden"></div>
</div>
<div class="container">
  <div class="box hidden"></div>
</div>
...