Улучшить эту документацию Просмотреть исходный код $animateCss
- сервис в модуле ngAnimate
Обзор
Сервис $animateCss — полезный инструмент для запуска настраиваемых анимаций/ключевых кадров на основе CSS из JavaScript-анимации или непосредственно из директивы. Цель $animateCss — не обойти работу $animate и ngAnimate, а предоставить возможность для существующих анимаций или директив создавать более сложные анимации, которые могут управляться исключительно кодом CSS.
Обратите внимание, что только браузеры, поддерживающие CSS-переходы и/или анимации ключевых кадров, могут отображать анимации, запускаемые через $animateCss (плохие новости для 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-классе, который добавляется), а затем подготовит анимацию перехода и анимацию ключевых кадров для одновременного выполнения на элементе. Затем, когда анимация запустится, предоставленные стили CSS from и to будут применены и распределены по анимации перехода и анимации ключевых кадров.
Что возвращается
$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–2020 Google, Inc.
Licensed under the Creative Commons Attribution License 3.0.
https://code.angularjs.org/1.8.2/docs/api/ngAnimate/service/$animateCss