Вопрос или проблема
Я запускаю анимацию на некоторых элементах, которые в 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 для обработки события окончания анимации, вы сможете поддерживать финальное состояние элементов после завершения анимации.