Сложные анимационные последовательности¶
28.02.2022
Необходимые условия¶
Базовое понимание следующих концепций:
До сих пор мы изучали простые анимации отдельных элементов HTML. Angular также позволяет анимировать согласованные последовательности, например, всю сетку или список элементов, когда они входят и выходят со страницы.
Вы можете выбрать параллельный запуск нескольких анимаций или последовательный запуск отдельных анимаций, следующих одна за другой.
Функции, управляющие сложными анимационными последовательностями, следующие:
Функции | Подробности |
---|---|
query() | Находит один или несколько внутренних элементов HTML. |
stagger() | Применяет каскадную задержку к анимации для нескольких элементов. |
group() | Запускает несколько шагов анимации параллельно. |
sequence() | Запускает шаги анимации один за другим. |
Функция query()¶
Большинство сложных анимаций полагаются на функцию query()
для поиска дочерних элементов и применения к ним анимации, основными примерами которых являются:
Примеры | Детали |
---|---|
query() с последующим animate() | Используется для запроса простых элементов HTML и прямого применения к ним анимации. |
query() с последующим animateChild() | Используется для запроса дочерних элементов, которые сами имеют метаданные анимации, примененные к ним, и запускают такую анимацию (которая в противном случае была бы заблокирована анимацией текущего/родительского элемента). |
Первым аргументом query()
является строка css selector, которая также может содержать следующие специфические для Angular лексемы:
Токены | Детали |
---|---|
:enter :leave | Для ввода/вывода элементов. |
:animating | Для элементов, которые в данный момент анимируются. |
@* @triggerName | Для элементов с любым или определенным триггером. |
:self | Сам анимируемый элемент. |
Вход и выход из элементов
Не все дочерние элементы на самом деле считаются входящими/выходящими; иногда это может быть нелогичным и запутанным. Пожалуйста, смотрите query api docs для получения дополнительной информации.
Вы также можете увидеть иллюстрацию этого в живом примере анимации (представленном в разделе анимации введение) на вкладке Querying.
Анимация нескольких элементов с помощью функций query() и stagger()¶
После запроса дочерних элементов с помощью функции query()
, функция stagger()
позволяет определить временной промежуток между каждым анимируемым элементом и, таким образом, анимировать элементы с задержкой между ними.
Следующий пример демонстрирует, как использовать функции query()
и stagger()
для анимации списка (героев\, добавляя каждый из них последовательно, с небольшой задержкой, сверху вниз.
-
Используйте функцию
query()
для поиска элемента на странице, который соответствует определенным критериям. -
Для каждого из этих элементов используйте
style()
, чтобы установить одинаковый начальный стиль для элемента.Сделайте его прозрачным и с помощью
transform
переместите его из позиции в позицию, чтобы он мог встать на место. -
Используйте
stagger()
для задержки каждой анимации на 30 миллисекунд. -
Анимируйте каждый элемент на экране в течение 0,5 секунды, используя заданную кривую смягчения, одновременно затухая и разворачиваясь.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
Параллельная анимация с помощью функции group()¶
Вы видели, как добавить задержку между каждой последующей анимацией. Но вы также можете захотеть настроить анимацию, которая будет происходить параллельно.
Например, вы можете захотеть анимировать два CSS-свойства одного и того же элемента, но использовать для каждого из них свою функцию сглаживания
.
Для этого можно использовать функцию animation group()
.
Функция group()
используется для группировки шагов анимации, а не анимированных элементов.
Следующий пример использует group()
на :enter
и :leave
для двух различных временных конфигураций, таким образом применяя две независимые анимации к одному и тому же элементу параллельно.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
|
Последовательные и параллельные анимации¶
В сложных анимациях может происходить множество действий одновременно. Но что если вы хотите создать анимацию, включающую несколько анимаций, происходящих одна за другой? Ранее вы использовали group()
, чтобы запустить несколько анимаций одновременно, параллельно.
Вторая функция под названием sequence()
позволяет запускать те же анимации одну за другой. Внутри sequence()
шаги анимации состоят из вызовов функций style()
или animate()
.
- Используйте
style()
для немедленного применения предоставленных данных о стиле. - Используйте
animate()
для применения данных о стиле в течение заданного интервала времени.
Пример анимации фильтра¶
Посмотрите на другую анимацию на странице живого примера. На вкладке Filter/Stagger введите текст в поле Search Heroes, например Magnet
или tornado
.
Фильтр работает в реальном времени по мере ввода текста. Элементы покидают страницу по мере ввода каждой новой буквы, а фильтр становится все более строгим.
Список героев постепенно возвращается на страницу по мере удаления каждой буквы в поле фильтра.
HTML-шаблон содержит триггер под названием filterAnimation
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
Фильтр filterAnimation
в декораторе компонента содержит три перехода.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
|
Код в этом примере выполняет следующие задачи:
-
Пропускает анимацию, когда пользователь впервые открывает или переходит на эту страницу (анимация фильтра сужает то, что уже есть, поэтому она работает только на элементах, которые уже существуют в DOM)
-
Фильтрует героев, основываясь на значении поискового ввода.
Для каждого изменения:
-
Скрывает элемент, выходящий из DOM, устанавливая его непрозрачность и ширину на 0
-
Анимирует элемент, входящий в DOM в течение 300 миллисекунд.
Во время анимации элемент принимает ширину и непрозрачность по умолчанию.
-
Если в DOM входят или выходят несколько элементов, каждая анимация начинается с верхней части страницы с задержкой в 50 миллисекунд между каждым элементом.
Анимация элементов переупорядоченного списка¶
Хотя Angular правильно анимирует элементы списка *ngFor
из коробки, он не сможет сделать это, если их порядок изменится. Это происходит потому, что он теряет представление о том, какой элемент является каким, что приводит к сбоям анимации.
Единственный способ помочь Angular отслеживать такие элементы — присвоить директиве NgForOf
функцию TrackByFunction
.
Благодаря этому Angular всегда будет знать, какой элемент каким является, что позволит ему постоянно применять правильную анимацию к правильным элементам.
Важно
Если вам нужно анимировать элементы списка *ngFor
и есть вероятность, что порядок этих элементов изменится во время выполнения, всегда используйте TrackByFunction
.
Анимации и инкапсуляция представлений компонентов¶
Анимации Angular основаны на структуре DOM компонентов и не учитывают View Encapsulation, это означает, что компоненты, использующие ViewEncapsulation.Emulated
, ведут себя точно так же, как если бы они использовали ViewEncapsulation.None
(ViewEncapsulation.ShadowDom
ведет себя по-другому, о чем мы поговорим в ближайшее время).
Например, если бы функция query()
(о которой мы расскажем в остальной части руководства по анимации) была применена в верхней части дерева компонентов, использующих инкапсуляцию эмулированного представления, такой запрос смог бы идентифицировать (и, таким образом, анимировать) элементы DOM на любой глубине дерева.
С другой стороны, ViewEncapsulation.ShadowDom
изменяет структуру DOM компонента, "пряча" элементы DOM внутри элементов ShadowRoot
. Такие манипуляции с DOM препятствуют корректной работе некоторых реализаций анимации, поскольку они полагаются на простые структуры DOM и не учитывают элементы ShadowRoot
. Поэтому рекомендуется избегать применения анимации к представлениям, включающим компоненты, использующие инкапсуляцию представления ShadowDom.
Краткое описание последовательности анимации¶
Функции Angular для анимации нескольких элементов начинаются с query()
для поиска внутренних элементов; например, сбор всех изображений внутри div
. Остальные функции, stagger()
, group()
и sequence()
, применяют каскады или позволяют контролировать применение нескольких шагов анимации.
Подробнее об анимации в Angular¶
Вам также может быть интересно следующее: