От автора: движение помогает понять красоту. Я всегда восхищался анимацией, она рождает душу приложения, превращая его в живое существо, которое реагирует на наши действия. Это помогает понять его функциональность и заставляет нас сопереживать. Как и везде, в Angular анимация заключается в переходе элемента из исходного состояния (initial state) в конечное (final state), и в вычислении средних состояний для обеспечения появления движения.
CSS-анимация
Основным свойством, которое позволяет анимировать элемент CSS, является переход:
1 2 3 |
.элемент { переход: [свойство] [продолжительность] [легкость] [задержка] } |
Внутри него мы можем объявить [свойство], которым хотим оживить, [продолжительность] анимации, тип потока [легкость], и [задержка].
Мы можем анимировать только:
Элементы, которые имеют определенное начальное состояние для перехода от (т. Е. Width : 200px) и конечное состояние для перехода к (то есть: ширина: 400 пикселей).
Свойства, которые браузер может вычислять в своих состояниях, например ширину, высоту, размер шрифта …
Мы можем инициировать переход CSS с:
CSS : объявлением псевдо-класса: hover.
JS : добавление класса:
1 |
document.getElementsByClassName ('circle') [0] .classList.add ("square"); |
Настройка: наведите курсор на желтый круг, чтобы увидеть переход в действии. Проверьте app.component.scss, чтобы увидеть реализацию:
Производительность.
По соображениям производительности всегда ограничивайте анимацию «преобразованием» (перевод, масштабирование, вращение) и «непрозрачностью».
Теперь, когда вы стали экспертом по анимации CSS, давайте посмотрим, как применить это к Angular.
Анимация Angular
Анимации Angular основаны на API веб-анимациях, которые в основном привносят всю мощь анимации из CSS в JS, позволяя делать удивительные вещи, вроде приостановки или изменения анимации прямо в коде:
1 2 3 |
let elem = document.getElementsByClassName ('circle') [0]; elem .animate ({transform: 'scale (0)', opacity: 0}, 3000); elem .pause () ; |
Настройка анимации
Чтобы начать использовать анимацию в проекте Angular, нам понадобятся:
Проект: установите BrowserModule и BrowserAnimationsModule и добавьте их в пакет package.json ( npm install —save @angular/animations @angular/platform-browser).
Модуль: добавьте в модули, в которых мы будем применять анимацию (обычно это app.module.ts или shared.module.ts).
Компонент: импортируйте функции, которые будете использовать. Объявите анимацию в декораторе компонента. { trigger, state, style, animate, transition } from ‘@angular/animations’
1 2 3 4 5 6 7 8 9 |
import { Component, OnInit } from '@angular/core'; import { trigger, state, style, animate, transition, group } from '@angular/animations'; @Component({ selector: 'my-app', templateUrl: './app.component.html', styleUrls: ['./app.component.scss'], animations: [ ...animation declarations ] }) export class AppComponent... |
Использование анимаций
1 2 3 4 5 6 7 8 9 10 11 12 |
// app.component.ts @Component({ ... animations: [ trigger('triggerName', [ transition('initialState => finalState', [ animate('1500ms ease-in') ]) ]) ], ... }) |
Объявление анимации состоит как минимум из:
Trigger (вызов) ( [ name], [definitions array] ): объявляет анимацию с именем, используемым для применения в шаблоне.
Transition (переход) ( [ states], [definitions array] ): Указывает два состояния ( initialState и finalState ), которые объединяют анимацию. Оператор ‘=>’ используется для однонаправленных переходов и <=> для двунаправленных.
Animation (анимация) (‘[duration] [delay] [ease]’): определяет тип анимации, который будет применяться к переходу между состояниями.
После объявления анимации в компоненте мы можем применить его к элементу, который мы хотим оживить в шаблоне.
1 2 3 4 |
// app.component.html <div @triggerName> <p>I'm going to be animated guys...</p> </div> |
Обратите внимание, что мы больше не используем CSS, все анимации управляются в JS и HTML.
Состояния
Как и в любой анимации, анимации Angular — это переходы между двумя стилизованными состояниями. Существует 2 типа состояний:
Стандартные: — void: когда элемент отсутствует в представлении, он находится в состоянии void. — * : подстановочный знак, соответствующий любому состоянию.
Пользовательские: Состояния, определённые пользователем с помощью state ().
Общие переходы со стандартными состояниями: « void => * » (когда элемент входит) и « * => void » (когда элемент выходит).
1 2 3 4 5 6 7 |
trigger('enterLeave', [ // Animate 1500ms with ease-in flow any element that // transitions from void state (not present) to any other state transition('void => *', [ // This transition's alias is ':enter' animate('1500ms ease-in') ]) ]) |
Если мы применим эту анимацию к элементу …то увидим, что ничего не происходит. Это потому, что в состоянии элемент «void» отсутствует в представлении, поэтому не имеет никакого стиля для перехода.
Без стандартного начального состояния браузер не может вычислить переход этих свойств в конечное состояние. По умолчанию конечное состояние является элементом, естественно помещенным в представление со свойствами, которые мы применили к нему в CSS.
Стили
Мы можем определить стили с функцией style(). Существует два типа стилей:
Стили состояний: применяется к элементу, находящемуся в состоянии. Удаляется при изменении состояния.
Стили перехода: применяется к элементу, когда он переходит в свое конечное состояние. Удаляется, когда применяется конечное состояние (с его собственными стилями).
Внутри стилей перехода также есть деление на два типа:
1. Стили «From»: помещенные в начале перехода, они будут применены к элементу справа, когда тот будет создан.
1 2 3 4 5 6 7 |
trigger('enterLeave', [ transition('void => *', [ // 'From' Style style({ opacity: 0.2, transform: 'translateX(-100%)' }), animate('1500ms ease-in') ]) ]) |
Таким образом, элемент будет иметь стиль, когда исходное состояние «void», и браузер сможет выполнить переход from. Теперь переход работает, и мы можем видеть, как довольно прозрачный элемент (opacity: 0.2) входит с левой стороны экрана (translateX (-100%)) и переходит в свое конечное состояние в центре страницы, увеличивая непрозрачность.
2. Стили «To»: помещенные внутри animate (), они будут использоваться для перехода к нему из стиля «from» или, как в данном случае «void».
1 2 3 4 5 6 7 8 9 10 |
trigger('enterLeave', [ transition('void => *', [ // 'From' Style style({ opacity: 0.2, transform: 'translateX(-100%)' }), animate('1500ms ease-in', // 'To' Style style({ opacity: 1, transform: 'scale(1.5)' }), ) ]) ]) |
Теперь мы можем видеть элемент, входящий с левой стороны экрана, но на этот раз он изменяет свой масштаб на 50%, прежде чем вернуться в конечное состояние в центре страницы.
Стили «To» и «From» удаляются, когда переход завершается, поэтому переход завершается резким показом элемента с его оригинальными стилями CSS.
Редактор: Проверьте app.component.ts в редакторе ниже. Нажмите кнопку «Hide/Show», чтобы применить / удалить состояние «void» для элементов.
Давайте удалим стили «To» и добавим крутую анимацию «leave»:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
trigger('enterLeave', [ transition('void => *', [ // 'From' Style style({ opacity: 0.2, transform: 'translateX(-100%)' }), animate('1500ms ease-in') ]), transition('* => void', [ animate('1500ms ease-in', // 'To' Style style({ opacity: 1, transform: 'translateX(100%)' }), ) ]) ]) |
Редактор: 1- Комментируйте стили «To», чтобы удалить растущий элемент.
2- Раскомментируйте ‘ : LEAVE TRANSITION ‘ в app.component.ts, чтобы увидеть кое-что крутое. Отлично, теперь элемент появляется слева, когда он создан (void), благодаря стилю «From», описанному в переходе.
Затем, когда он удаляется, он снова переходит в «void», покидая экран, благодаря стилям «To».
Когда переход заканчивается, все стили перехода удаляются, и элементы возвращаются в свой стиль конечного перехода (void === not present). И поскольку элемент находится вне окна, мы не видим резкого исчезновения.
Управление состояниями
Помимо состояний по умолчанию, мы также имеем возможность создавать собственные пользовательские состояния и управлять ими, когда они применяются к элементу:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
trigger('selected', [ // Custom state state('selected', style({ backgroundColor: 'whitesmoke', transform: 'scale(1.2)', }) ), // When the element goes from 'selected' state to whatever... transition('selected <=> *', [ animate('300ms ease-in') ]) ]) |
В представлении наш анимационный триггер получает переменную elementState из класса компонента.
1 2 3 4 |
// app.component.html <div [@selected]="elementState"> <p>I'm going to be animated guys...</p> </div> |
Когда elementState === ‘selected’ , стили «выбранного» состояния будут применены к нему. Когда состояние изменяется, элемент переходит в любое другое состояние, как определено (animate (‘300ms ease-in’)).
Мы можем управлять состоянием элемента, изменяя значение elementState с помощью метода, подобного тому, который приведён в примере.
Редактор: нажать на синюю кнопку выбора элементов, чтобы применить состояние «selected» и запустить анимацию.
Также можно запускать несколько анимаций параллельно с помощью group().
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
transition('selected => *', [ group([ // Apply pink color to the item and animate('1s ease', style({ backgroundColor: '#ffc107' }) ), // after a second, fade it to the background animate('2s 1.5s ease', style({ opacity: 0.2, transform: 'scale(0.5)' }) ) ]) ]) |
Редактор: 3- Комментируйте «selected» состояние «transition» и раскомментируйте GROUPED ANIMATIONS, чтобы увидеть их в действии.
И последний трюк. Нужно запустить какие-либо действия, когда анимация заканчивается? Легко, просто привяжите их к событию «done».
1 |
<div class="car" [@selected]="car.selected (@selected.done)="logIt($event)"> |
Вот и все думал, что это будет так долго, поэтому, надеюсь, вам понравилось. Спасибо за внимание.
Автор: Aleix Suau
Источник: //medium.com/
Редакция: Команда webformyself.