Поддержание конечного состояния в конце анимации CSS

Вопрос или проблема

Я запускаю анимацию на некоторых элементах, которые в CSS установлены на opacity: 0;. Класс анимации применяется по клику, и с помощью ключевых кадров он изменяет непрозрачность от 0 до 1 (среди прочего).

К сожалению, когда анимация заканчивается, элементы возвращаются к opacity: 0 (как в Firefox, так и в Chrome). Мои естественные мысли заключаются в том, что анимированные элементы должны сохранять конечное состояние, переопределяя свои исходные свойства. Это не так? И если нет, как мне заставить элемент делать это?

Код (версии с префиксами не включены):

@keyframes bubble {
    0%   { transform:scale(0.5); opacity:0.0; }
    50%  { transform:scale(1.2); opacity:0.5; }
    100% { transform:scale(1.0); opacity:1.0; }
}

Попробуйте добавить animation-fill-mode: forwards;. Например, сокращенная запись будет выглядеть так:

animation: bubble 1.0s forwards;

https://developer.mozilla.org/en-US/docs/Web/CSS/animation-fill-mode

Если вы используете больше атрибутов анимации, сокращенная запись будет выглядеть так:

animation: bubble 2s linear 0.5s 1 normal forwards;

Это дает:

  • bubble имя анимации
  • 2s продолжительность
  • linear функция времени
  • 0.5s задержка
  • 1 количество итераций (может быть ‘infinite‘)
  • normal направление
  • forwards режим заполнения (установите ‘backwards’, если хотите иметь совместимость для использования конечной позиции в качестве конечного состояния [это для поддержки браузеров, у которых анимации отключены] {и чтобы ответить только на заголовок, а не на ваш конкретный случай})

Доступные функции времени:

ease | ease-in | ease-out | ease-in-out | linear | step-start | step-end

Доступные направления

normal | reverse | alternate | alternate-reverse

ЕСЛИ НЕ ИСПОЛЬЗУЕТЕ СКРАЩЕННУЮ ЗАПИСЬ: Убедитесь, что animation-fill-mode: forwards идет ПОСЛЕ декларации анимации, иначе это не сработает…

animation-fill-mode: forwards;
animation-name: appear;
animation-duration: 1s;
animation-delay: 1s;

по сравнению с

animation-name: appear;
animation-duration: 1s;
animation-fill-mode: forwards;
animation-delay: 1s;

Используйте
animation-fill-mode: forwards;

animation-fill-mode: forwards;

Элемент будет сохранять значения стиля, установленные последним ключевым кадром (в зависимости от направления анимации и количества итераций).

Примечание: Правило @keyframes не поддерживается в Internet Explorer 9 и более ранних версиях.

Рабочий пример

div {
  width: 100px;
  height: 100px;
  background: red;
  position :relative;
  -webkit-animation: mymove 3ss forwards; /* Safari 4.0 - 8.0 */
  animation: bubble 3s forwards;
  /* animation-name: bubble; 
  animation-duration: 3s;
  animation-fill-mode: forwards; */
}

/* Safari */
@-webkit-keyframes bubble  {
  0%   { transform:scale(0.5); opacity:0.0; left:0}
    50%  { transform:scale(1.2); opacity:0.5; left:100px}
    100% { transform:scale(1.0); opacity:1.0; left:200px}
}

/* Стандартный синтаксис */
@keyframes bubble  {
   0%   { transform:scale(0.5); opacity:0.0; left:0}
    50%  { transform:scale(1.2); opacity:0.5; left:100px}
    100% { transform:scale(1.0); opacity:1.0; left:200px}
}
<h1>Ключевые кадры </h1>
<div></div>
</div><div class="s-prose js-post-body" itemprop="text">

У меня была проблема с использованием forwards: по крайней мере в Chrome, даже после завершения анимации, рендерер все еще потреблял графические ресурсы, что делало приложение менее отзывчивым.

Подход, который не вызывает этой проблемы, – это использование EventListener.

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

CSS

.fade_in {
  animation: fadeIn 2s;
}

@keyframes fadeIn {
  from {
    opacity: 0;
  }

  to {
    opacity: 1;
  }
}

JavaScript

const element = document.getElementById("element-to-be-animated");

element.addEventListener("animationend", () => {
    // Установите свое конечное состояние здесь. Например:
    element.style["opacity"] = 1;
}, { once: true });

Опция once: true говорит движку удалить слушатель событий после его выполнения, оставляя ваше приложение свежим и чистым.

Я создал JSFiddle, чтобы показать, как это работает.

</div>

Ответ или решение

Проблема, с которой вы столкнулись, связана с тем, что по умолчанию элементы, анимированные с помощью CSS, возвращаются к своим исходным стилям после завершения анимации. Однако есть способ заставить элементы сохранять финальное состояние, используя свойство animation-fill-mode.

Для того чтобы анимация сохранила конечное состояние, необходимо добавить animation-fill-mode: forwards;. Это свойство указывает, что стили, заданные последним ключевым кадром анимации, должны быть применены к элементу после завершения анимации.

Вот пример использования:

@keyframes bubble {
    0%   { transform: scale(0.5); opacity: 0.0; }
    50%  { transform: scale(1.2); opacity: 0.5; }
    100% { transform: scale(1.0); opacity: 1.0; }
}

.element {
    animation: bubble 2s forwards; /* Применяем анимацию */
}

Вы также можете использовать сокращенную запись для всех свойств анимации:

.element {
    animation: bubble 2s linear 0.5s 1 normal forwards; /* Пример полной записи */
}

В этом случае анимация будет длиться 2 секунды с линейной функцией времени, начнётся через 0.5 секунды, выполнится 1 раз, а значения останутся после завершения анимации благодаря forwards.

Важно помнить, что если вы не используете сокращенную запись, то animation-fill-mode: forwards; должно стоять после других свойств анимации:

.element {
    animation-name: bubble;
    animation-duration: 2s;
    animation-fill-mode: forwards; /* Это должно быть после */
}

Если речь идет о проблемах с производительностью, вы можете использовать событие animationend в JavaScript, чтобы установить конечное состояние вручную после завершения анимации. Вот пример, как это можно реализовать:

const element = document.getElementById("element-to-be-animated");

element.addEventListener("animationend", () => {
    element.style.opacity = 1; // Устанавливаем финальное состояние
}, { once: true }); // { once: true } позволит удалить слушатель после первого вызова

Это способ гарантирует, что по завершению анимации элемент остается в нужном вам состоянии, при этом минимизируя нагрузку на рендеринг.

Таким образом, используя animation-fill-mode: forwards; или JavaScript для обработки события окончания анимации, вы сможете поддерживать финальное состояние элементов после завершения анимации.

Оцените материал
Добавить комментарий

Капча загружается...