#angular #css-animations #angular7 #angular-router #angular-animations
#angular #css-анимации #angular7 #angular-маршрутизатор #angular-анимации
Вопрос:
Я опробовал около 5 реализаций анимации выхода маршрутизатора. Я просто хочу базовую анимацию постепенного включения / выключения при изменении маршрута, ничего особенного.
Вот запись экрана, показывающая, как все выглядит при переключении маршрута:https://streamable.com/tbkxt
Это, безусловно, лучший результат, который я получил, в других случаях у меня просто кнопки / текст исчезали с экрана один за другим. Я тестирую в Chrome.
У меня включена навигация sidenav, и мой код выглядит следующим образом:
<mat-sidenav-content [@routerTransition]="getPageTransition(routerOutlet)">
<button
@menu-button
*ngIf="!snav.opened"
mat-button
(click)="snav.toggle()"
class="navigation-toggle"
>
<fa-icon icon="bars"></fa-icon>
</button>
<button
@menu-button
*ngIf="snav.opened"
mat-button
(click)="snav.toggle()"
class="navigation-toggle"
>
<fa-icon icon="times"></fa-icon>
</button>
<router-outlet #routerOutlet="outlet"></router-outlet>
</mat-sidenav-content>
Мои анимации определены:
const query = (style, animate, optional = { optional: true }) =>
q(style, animate, optional);
const fade = [
query(':enter, :leave', style({ position: 'fixed', width: '100%' })),
query(':enter', [style({ opacity: 0 })]),
group([
query(':leave', [animate('0.3s ease-out', style({ opacity: 0 }))]),
query(':enter', [
style({ opacity: 0 }),
animate('0.3s ease-out', style({ opacity: 1 }))
])
])
];
export const routerTransition = trigger('routerTransition', [
transition('void => *', [
style({ top: '0px', opacity: 0 }),
animate(2000, style({ top: '0px', opacity: 1 }))
]),
transition('* => void', [
style({ top: '0px', opacity: 1 }),
animate(2000, style({ top: '0px', opacity: 0 }))
]),
transition('* => forward', fade),
transition('* => backward', fade)
]);
И в компоненте я проверяю выход маршрутизатора:
getPageTransition(routerOutlet: RouterOutlet) {
if (routerOutlet.isActivated) {
let transitionName = 'section';
const { path } = routerOutlet.activatedRoute.routeConfig;
const isSame = this.previousPath === path;
const isBackward = this.previousPath.startsWith(path);
const isForward = path.startsWith(this.previousPath);
if (isSame) {
transitionName = 'none';
} else if (isBackward amp;amp; isForward) {
transitionName = 'initial';
} else if (isBackward) {
transitionName = 'backward';
} else if (isForward) {
transitionName = 'forward';
}
this.previousPath = path;
return transitionName;
}
Комментарии:
1. Привет, Себастьян, у меня также был неудачный опыт работы с анимацией маршрутизатора в прошлом. Одна всегда повторяющаяся ошибка была связана со следующим: github.com/angular/angular/issues/15477 . Есть несколько решений, и это может вам помочь. Насколько я понял, вам нужно удерживать компонент, анимируя маршрутизатор с непрозрачности 0,99999 до 1, чтобы сохранить все содержимое и, следовательно, анимацию живой, пока компонент не можно будет выбросить.
2. @JonathanStellwag спасибо — Я не на 100% уверен, что понимаю, что вы имеете в виду, анимируя маршрутизатор с 0.99999 до 1 — вы имеете в виду, что при входе я должен начинать с 0.99999 вместо 0? разве это не сохранит все это видимым? или анимировать его от 0 до 0,99999 — глядя на идею от 0,99999 до 1, он, скорее всего, просто исчезнет в мгновение ока без фактического исчезновения, но я думаю, что я неправильно понимаю. Спасибо!
3. Привет @SebastianG. Я напишу вам ответ, который, возможно, потребуется адаптировать к вашему случаю, и / или вам придется немного попробовать и ошибиться. Но код в разделе комментариев не очень приятный 🙂
Ответ №1:
Я выяснил, что события :enter и:leave, близкие к маршрутизации, могут вызвать несколько проблем с анимацией angular. Этот ответ не является тестовым для вашего случая и, возможно, нуждается в адаптации, поскольку следующий фрагмент зависит от структуры вашего приложения и вашего вложенного маршрутизатора. Я адаптирую этот ответ, если он не подходит или решит вашу проблему!
Что касается этой проблемы с Github, дочерние маршруты немедленно исчезают без воспроизведения анимации при изменении родительского маршрута.
Следующий комментарий решил мою проблему, но мне пришлось адаптировать его для моей среды:
let animation = [...]; // the metadata
transition('A => B', group([
query(':self', animation),
query('router-outlet ~ *', [style({}), animate(1, style({}))], { optional: true })
]))
На самом деле это означает, что вы не только анимируете свой элемент. Вы также применяете анимацию к самому маршрутизатору-выходу. Это может быть реализовано для вашего кода следующим образом:
query('mat-sidenav-content > router-outlet ~ *', [
style({
opacity: .99999
}),
animate(yourAnimationDuration, style({
opacity: 1
}))
], { optional: true });
Я не специалист по Css-селектору, возможно, вам потребуется адаптировать
mat-sidenav-content > router-outlet ~ *
Я надеюсь, что этот ответ может вам помочь 🙂