Улучшить эту документацию Просмотреть исходный код $animateCss
- Сервис в модуле ngAnimate
Обзор
Сервис $animateCss — полезная утилита для запуска настраиваемых анимаций/ключевых кадров на основе CSS из JavaScript-анимации или напрямую из директивы. Цель $animateCss — НЕ обойти механизм работы $animate и ngAnimate, а предоставить возможность существующим анимациям или директивам создавать более сложные анимации, управляемые исключительно кодом CSS.
Обратите внимание, что анимации, запускаемые с помощью $animateCss, отображаются только в браузерах, поддерживающих CSS-переходы и/или анимации ключевых кадров (это плохо для IE9 и более ранних версий).
Общее использование
Ещё раз, $animateCss предназначен для использования внутри зарегистрированной JavaScript-анимации, работающей с ngAnimate. Возможна прямая работа с $animateCss внутри директивы, однако автоматическое управление отменой анимаций и/или предотвращение запуска анимаций дочерних элементов не поддерживается AngularJS. Для корректной работы используйте $animate для запуска анимации и затем настройте JavaScript-анимацию, которая вводит $animateCss для запуска CSS-анимации.
Пример ниже демонстрирует, как создать анимацию складывания элемента с помощью ng-if:
<!-- notice the `fold-animation` CSS class --> <div ng-if="onOff" class="fold-animation"> This element will go BOOM </div> <button ng-click="onOff=true">Fold In</button>
Теперь создадим JavaScript-анимацию, которая запустит CSS-переход:
ngModule.animation('.fold-animation', ['$animateCss', function($animateCss) {
return {
enter: function(element, doneFn) {
var height = element[0].offsetHeight;
return $animateCss(element, {
from: { height:'0px' },
to: { height:height + 'px' },
duration: 1 // one second
});
}
}
}]);
Более продвинутые применения
$animateCss — это базовый код, который ngAnimate использует для запуска CSS-анимаций за кулисами. Поэтому такие CSS-хуки, как .ng-EVENT, .ng-EVENT-active, .ng-EVENT-stagger, могут быть запущены с помощью $animateCss через JavaScript-код.
Это также означает, что практически любая комбинация добавления классов, удаления классов, установки стилей, динамической установки анимации ключевых кадров, применения жёстких значений продолжительности или задержки, изменения ускорения анимации или применения ступенчатой анимации поддерживается $animateCss. Сам сервис достаточно интеллектуален, чтобы определить комбинацию параметров и проанализировать свойства стилей элемента, чтобы обеспечить работоспособную анимацию, которая будет запущена в CSS.
Пример ниже демонстрирует более продвинутую версию .fold-animation из предыдущего примера:
ngModule.animation('.fold-animation', ['$animateCss', function($animateCss) {
return {
enter: function(element, doneFn) {
var height = element[0].offsetHeight;
return $animateCss(element, {
addClass: 'red large-text pulse-twice',
easing: 'ease-out',
from: { height:'0px' },
to: { height:height + 'px' },
duration: 1 // one second
});
}
}
}]);
Поскольку мы добавляем/удаляем CSS-классы, CSS-переход также учтёт их:
/* since a hardcoded duration value of 1 was provided in the JavaScript animation code,
the CSS classes below will be transitioned despite them being defined as regular CSS classes */
.red { background:red; }
.large-text { font-size:20px; }
/* we can also use a keyframe animation and $animateCss will make it work alongside the transition */
.pulse-twice {
animation: 0.5s pulse linear 2;
-webkit-animation: 0.5s pulse linear 2;
}
@keyframes pulse {
from { transform: scale(0.5); }
to { transform: scale(1.5); }
}
@-webkit-keyframes pulse {
from { -webkit-transform: scale(0.5); }
to { -webkit-transform: scale(1.5); }
}
Учитывая эту сложную комбинацию CSS-классов, стилей и параметров, $animateCss проанализирует всё и запустит анимацию.
Как обрабатываются параметры
$animateCss очень универсален и интеллектуален при определении конфигураций для элемента, чтобы анимация работала с предоставленными параметрами. Например, если мы добавляем класс, содержащий значение ключевого кадра, и хотим также анимировать некоторые внутренние стили с помощью from и to свойств.
var animator = $animateCss(element, {
from: { background:'red' },
to: { background:'blue' }
});
animator.start();
.rotating-animation {
animation:0.5s rotate linear;
-webkit-animation:0.5s rotate linear;
}
@keyframes rotate {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
@-webkit-keyframes rotate {
from { -webkit-transform: rotate(0deg); }
to { -webkit-transform: rotate(360deg); }
}
Здесь не хватает настройки перехода (в CSS-коде или в параметрах $animateCss). Продолжительность анимации будет определяться из стилей ключевых кадров в CSS-классе. В этом случае $animateCss автоматически создаст внутренний стиль перехода, соответствующий продолжительности, определённой из стиля ключевого кадра (который присутствует в добавляемом CSS-классе), а затем подготовит анимацию перехода и анимацию ключевых кадров для одновременного запуска на элементе. Затем, во время анимации, предоставленные from и to CSS-стили будут применены и распределены между анимацией перехода и анимацией ключевых кадров.
Что возвращается
$animateCss работает в два этапа: подготовка и анимация. Поэтому при первом вызове $animateCss анимация НЕ запускается. Все, что происходит, — это подготовка элемента к анимации (это означает, что сгенерированные CSS-классы добавляются и удаляются с элемента). После вызова $animateCss возвращается объект со следующими свойствами:
var animator = $animateCss(element, { ... });
Теперь, как выглядит содержимое нашей переменной animator:
{
// starts the animation
start: Function,
// ends (aborts) the animation
end: Function
}
Для запуска анимации необходимо выполнить animation.start(), которое вернёт промис, с помощью которого можно отследить окончание анимации. Если мы не хотим запускать анимацию, то ДОЛЖНЫ выполнить animation.end() для очистки элемента (поскольку некоторые CSS-классы и стили могут быть применены к элементу на этапе подготовки). Обратите внимание, что все остальные свойства, такие как продолжительность, задержка, переходы и ключевые кадры, — это просто свойства, и изменение их не переконфигурирует параметры анимации.
runner.done() vs runner.then()
Документировано, что animation.start() возвращает объект промиса, и это верно, но также доступен дополнительный метод в экземпляре runner, называемый .done(callbackFn). Метод done работает так же, как .finally(callbackFn), однако он не запускает переваривание (digest). Поэтому по соображениям производительности всегда лучше использовать runner.done(callback) вместо runner.then(), runner.catch() или runner.finally(), если вам не нужен запуск переваривания (digest) после.
Для упрощения ngAnimate изменил API JavaScript-анимаций, чтобы распознавать, когда экземпляр runner возвращается из $animateCss (нет необходимости вызывать runner.done(doneFn) в вашем JavaScript-коде анимации). Обратите внимание на код анимации выше по ссылке в документации выше, чтобы увидеть, как это работает.
Использование
$animateCss(element, options);
Аргументы
| Параметр | Тип | Подробности |
|---|---|---|
| элемент | DOMElement |
элемент, который будет анимирован |
| параметры | object |
параметры анимации, которые будут применены во время анимации
|
Возвращаемые значения
object |
объект с методами start и end и данными об анимации.
|
© 2010–2018 Google, Inc.
Licensed under the Creative Commons Attribution License 4.0.
https://code.angularjs.org/1.7.8/docs/api/ngAnimate/service/$animateCss