Angular7 路由器出口动画倾斜并重新排列所有元素,造成混乱
Angular7 router-outlet animations skews and rearranges all elements making a mess
我一直在尝试大约 5 种路由器出口动画的实现。当路线改变时,我只想要一个基本的 fade-in/fade-out 动画,没什么特别的。
这是我切换路线时的屏幕录像:https://streamable.com/tbkxt
这是迄今为止我获得的最好结果,在其他情况下,我只是让 buttons/text 一个一个地从屏幕上消失。我正在 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 && isForward) {
transitionName = 'initial';
} else if (isBackward) {
transitionName = 'backward';
} else if (isForward) {
transitionName = 'forward';
}
this.previousPath = path;
return transitionName;
}
我发现靠近路由的 :enter 和 :leave 事件可能会导致 angular 动画出现几个问题。此答案不适合您的情况,可能需要进行调整,因为以下代码段取决于您的应用程序结构和嵌套路由器。如果它不适合或解决您的问题,我会调整这个答案!
关于this 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-Selector专业的你可能需要适应
mat-sidenav-content > router-outlet ~ *
希望这个回答能帮到你:)
我一直在尝试大约 5 种路由器出口动画的实现。当路线改变时,我只想要一个基本的 fade-in/fade-out 动画,没什么特别的。
这是我切换路线时的屏幕录像:https://streamable.com/tbkxt
这是迄今为止我获得的最好结果,在其他情况下,我只是让 buttons/text 一个一个地从屏幕上消失。我正在 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 && isForward) {
transitionName = 'initial';
} else if (isBackward) {
transitionName = 'backward';
} else if (isForward) {
transitionName = 'forward';
}
this.previousPath = path;
return transitionName;
}
我发现靠近路由的 :enter 和 :leave 事件可能会导致 angular 动画出现几个问题。此答案不适合您的情况,可能需要进行调整,因为以下代码段取决于您的应用程序结构和嵌套路由器。如果它不适合或解决您的问题,我会调整这个答案!
关于this 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-Selector专业的你可能需要适应
mat-sidenav-content > router-outlet ~ *
希望这个回答能帮到你:)