Angular 路由器过渡动画有条件地左右滑动
Angular router transition animations slide both left and right conditionally
我已阅读这篇关于 Angular 的路由器转换动画的文章:
并且:
但是,这太静态了。我希望它根据选项卡的顺序向左滑动 和向右滑动 。
是否可以为此创建路由器动画?我的意思示例如下:
https://material.angular.io/components/tabs/examples
看看它如何非常自然地向左 滑动 和向右 滑动,具体取决于您在哪个选项卡上。
这必须是动态的,因为选项卡将在运行时添加。
我已经设法让它在 "faking" 它所处的状态下工作。
在component.html
:
<div [@animRoutes]="pageState">
<router-outlet></router-outlet>
</div>
pageState
是 component.ts
文件中的一个 变量 。
每当我点击一个我想右移的选项卡时,我会将 pageState
设置为 right
,left
也是如此,并让 Angular 剩下的接手
注意: 您必须创建 right
和 right1
状态作为 hack,因为 Angular 目前不支持 right => right
状态转换!! left
当然也是如此。
我的@Component
注释如下:
@Component({
selector: 'app-workspace-container',
templateUrl: './workspace-container.component.html',
styleUrls: ['./workspace-container.component.scss'],
animations: [
trigger('animRoutes', [
transition('* => right', right),
transition('* => left', left),
transition('* => right1', right),
transition('* => left1', left),
]),
],
changeDetection: ChangeDetectionStrategy.OnPush,
})
其中left
、left1
、right
、right1
是:
const left = [
query(':enter, :leave', style({ position: 'fixed', width: '100%' }), { optional: true }),
group([
query(':enter', [style({ transform: 'translateX(-100%)' }), animate('.3s ease-out', style({ transform: 'translateX(0%)' }))], {
optional: true,
}),
query(':leave', [style({ transform: 'translateX(0%)' }), animate('.3s ease-out', style({ transform: 'translateX(100%)' }))], {
optional: true,
}),
]),
];
const right = [
query(':enter, :leave', style({ position: 'fixed', width: '100%' }), { optional: true }),
group([
query(':enter', [style({ transform: 'translateX(100%)' }), animate('.3s ease-out', style({ transform: 'translateX(0%)' }))], {
optional: true,
}),
query(':leave', [style({ transform: 'translateX(0%)' }), animate('.3s ease-out', style({ transform: 'translateX(-100%)' }))], {
optional: true,
}),
]),
];
TL;DR: 将您要进入的状态设为 变量 ,这样您就可以动态设置您希望的状态你会。
今天事情有点简单,因为新的动画别名存在 :increment 和 :decrement。别名已在 Angular 5.
中引入
所以我修改后的方案是:
@Component({
selector: 'app-workspace-container',
templateUrl: './workspace-container.component.html',
styleUrls: ['./workspace-container.component.scss'],
animations: [
trigger('animRoutes', [
transition(':increment', right),
transition(':decrement', left),
]),
],
})
export class ComponentContainingRouterOutlet implements OnDestroy, OnInit {
//... ngOnInit,ngOnDestroy
constructor( private route: ActivatedRoute ) { }
animationState: number;
onActivate($event) {
this.animationState = this.route.firstChild.snapshot.data['routeIdx'];
}
}
router-outlet 位置调用动画:
<div [@animRoutes]="animationState">
<router-outlet (activate)="onActivate($event)"></router-outlet>
</div>
修改路由定义为例,看data: { routeIdx: X }
:
const routes: Routes = [
{
path: 'routeOne',
component: ComponentOne,
data: { routeIdx: 0 }
},
{
path: 'routeTwo',
component: ComponentTwo,
data: { routeIdx: 1}
},
{
path: 'routeThree',
component: ComponentThree,
data: { routeIdx: 2 }
},
{
path: 'routeFour',
component: ComponentFour,
data: { routeIdx: 3 }
},
{
path: '',
redirectTo: 'routeOne',
pathMatch: 'full'
}
]
转换与 中的相同 post:
const left = [
query(':enter, :leave', style({ position: 'fixed', width: '100%' }), { optional: true }),
group([
query(':enter', [style({ transform: 'translateX(-100%)' }), animate('.3s ease-out', style({ transform: 'translateX(0%)' }))], {
optional: true,
}),
query(':leave', [style({ transform: 'translateX(0%)' }), animate('.3s ease-out', style({ transform: 'translateX(100%)' }))], {
optional: true,
}),
]),
];
const right = [
query(':enter, :leave', style({ position: 'fixed', width: '100%' }), { optional: true }),
group([
query(':enter', [style({ transform: 'translateX(100%)' }), animate('.3s ease-out', style({ transform: 'translateX(0%)' }))], {
optional: true,
}),
query(':leave', [style({ transform: 'translateX(0%)' }), animate('.3s ease-out', style({ transform: 'translateX(-100%)' }))], {
optional: true,
}),
]),
];
Michal.S 的出色解决方案。所以我也可以在没有 Routechange 的情况下使用它,但也可以在你自己的选项卡组件上使用它。
如果您有自定义选项卡控件,您可以这样做:
第一步:添加上面的动画
const left = [
query(':enter, :leave', style({ position: 'absolute', width: '100%' }), { optional: true }), // or fixed
group([
query(':enter', [style({ transform: 'translateX(-100%)' }), animate('.4s ease-out', style({ transform: 'translateX(0%)' }))], {
optional: true,
}),
query(':leave', [style({ transform: 'translateX(0%)' }), animate('.4s ease-out', style({ transform: 'translateX(100%)' }))], {
optional: true,
}),
]),
];
const right = [
query(':enter, :leave', style({ position: 'absolute', width: '100%' }), { optional: true }),
group([
query(':enter', [style({ transform: 'translateX(100%)' }), animate('.4s ease-out', style({ transform: 'translateX(0%)' }))], {
optional: true,
}),
query(':leave', [style({ transform: 'translateX(0%)' }), animate('.4s ease-out', style({ transform: 'translateX(-100%)' }))], {
optional: true,
}),
]),
];
第2步:在模板中将触发器添加到动画项的容器中。相对或弹性定位。
<div [@animStep]="currentStep">
<app-step1 *ngIf=“currentStep === 1”></app-step1>
<app-step2 *ngIf=“currentStep === 2”></app-step2>
<app-step3 *ngIf=“currentStep === 3”></app-step3>
</div>
第 3 步:在组件装饰器中添加动画
// component
animations: [
trigger('animStep', [
transition(':increment', right),
transition(':decrement', left),
]),
],
第 3 步:触发值的变化
currentStep += 1;
我已阅读这篇关于 Angular 的路由器转换动画的文章:
并且:
但是,这太静态了。我希望它根据选项卡的顺序向左滑动 和向右滑动 。
是否可以为此创建路由器动画?我的意思示例如下:
https://material.angular.io/components/tabs/examples
看看它如何非常自然地向左 滑动 和向右 滑动,具体取决于您在哪个选项卡上。
这必须是动态的,因为选项卡将在运行时添加。
我已经设法让它在 "faking" 它所处的状态下工作。
在component.html
:
<div [@animRoutes]="pageState">
<router-outlet></router-outlet>
</div>
pageState
是 component.ts
文件中的一个 变量 。
每当我点击一个我想右移的选项卡时,我会将 pageState
设置为 right
,left
也是如此,并让 Angular 剩下的接手
注意: 您必须创建 right
和 right1
状态作为 hack,因为 Angular 目前不支持 right => right
状态转换!! left
当然也是如此。
我的@Component
注释如下:
@Component({
selector: 'app-workspace-container',
templateUrl: './workspace-container.component.html',
styleUrls: ['./workspace-container.component.scss'],
animations: [
trigger('animRoutes', [
transition('* => right', right),
transition('* => left', left),
transition('* => right1', right),
transition('* => left1', left),
]),
],
changeDetection: ChangeDetectionStrategy.OnPush,
})
其中left
、left1
、right
、right1
是:
const left = [
query(':enter, :leave', style({ position: 'fixed', width: '100%' }), { optional: true }),
group([
query(':enter', [style({ transform: 'translateX(-100%)' }), animate('.3s ease-out', style({ transform: 'translateX(0%)' }))], {
optional: true,
}),
query(':leave', [style({ transform: 'translateX(0%)' }), animate('.3s ease-out', style({ transform: 'translateX(100%)' }))], {
optional: true,
}),
]),
];
const right = [
query(':enter, :leave', style({ position: 'fixed', width: '100%' }), { optional: true }),
group([
query(':enter', [style({ transform: 'translateX(100%)' }), animate('.3s ease-out', style({ transform: 'translateX(0%)' }))], {
optional: true,
}),
query(':leave', [style({ transform: 'translateX(0%)' }), animate('.3s ease-out', style({ transform: 'translateX(-100%)' }))], {
optional: true,
}),
]),
];
TL;DR: 将您要进入的状态设为 变量 ,这样您就可以动态设置您希望的状态你会。
今天事情有点简单,因为新的动画别名存在 :increment 和 :decrement。别名已在 Angular 5.
中引入所以我修改后的方案是:
@Component({
selector: 'app-workspace-container',
templateUrl: './workspace-container.component.html',
styleUrls: ['./workspace-container.component.scss'],
animations: [
trigger('animRoutes', [
transition(':increment', right),
transition(':decrement', left),
]),
],
})
export class ComponentContainingRouterOutlet implements OnDestroy, OnInit {
//... ngOnInit,ngOnDestroy
constructor( private route: ActivatedRoute ) { }
animationState: number;
onActivate($event) {
this.animationState = this.route.firstChild.snapshot.data['routeIdx'];
}
}
router-outlet 位置调用动画:
<div [@animRoutes]="animationState">
<router-outlet (activate)="onActivate($event)"></router-outlet>
</div>
修改路由定义为例,看data: { routeIdx: X }
:
const routes: Routes = [
{
path: 'routeOne',
component: ComponentOne,
data: { routeIdx: 0 }
},
{
path: 'routeTwo',
component: ComponentTwo,
data: { routeIdx: 1}
},
{
path: 'routeThree',
component: ComponentThree,
data: { routeIdx: 2 }
},
{
path: 'routeFour',
component: ComponentFour,
data: { routeIdx: 3 }
},
{
path: '',
redirectTo: 'routeOne',
pathMatch: 'full'
}
]
转换与
const left = [
query(':enter, :leave', style({ position: 'fixed', width: '100%' }), { optional: true }),
group([
query(':enter', [style({ transform: 'translateX(-100%)' }), animate('.3s ease-out', style({ transform: 'translateX(0%)' }))], {
optional: true,
}),
query(':leave', [style({ transform: 'translateX(0%)' }), animate('.3s ease-out', style({ transform: 'translateX(100%)' }))], {
optional: true,
}),
]),
];
const right = [
query(':enter, :leave', style({ position: 'fixed', width: '100%' }), { optional: true }),
group([
query(':enter', [style({ transform: 'translateX(100%)' }), animate('.3s ease-out', style({ transform: 'translateX(0%)' }))], {
optional: true,
}),
query(':leave', [style({ transform: 'translateX(0%)' }), animate('.3s ease-out', style({ transform: 'translateX(-100%)' }))], {
optional: true,
}),
]),
];
Michal.S 的出色解决方案。所以我也可以在没有 Routechange 的情况下使用它,但也可以在你自己的选项卡组件上使用它。
如果您有自定义选项卡控件,您可以这样做:
第一步:添加上面的动画
const left = [
query(':enter, :leave', style({ position: 'absolute', width: '100%' }), { optional: true }), // or fixed
group([
query(':enter', [style({ transform: 'translateX(-100%)' }), animate('.4s ease-out', style({ transform: 'translateX(0%)' }))], {
optional: true,
}),
query(':leave', [style({ transform: 'translateX(0%)' }), animate('.4s ease-out', style({ transform: 'translateX(100%)' }))], {
optional: true,
}),
]),
];
const right = [
query(':enter, :leave', style({ position: 'absolute', width: '100%' }), { optional: true }),
group([
query(':enter', [style({ transform: 'translateX(100%)' }), animate('.4s ease-out', style({ transform: 'translateX(0%)' }))], {
optional: true,
}),
query(':leave', [style({ transform: 'translateX(0%)' }), animate('.4s ease-out', style({ transform: 'translateX(-100%)' }))], {
optional: true,
}),
]),
];
第2步:在模板中将触发器添加到动画项的容器中。相对或弹性定位。
<div [@animStep]="currentStep">
<app-step1 *ngIf=“currentStep === 1”></app-step1>
<app-step2 *ngIf=“currentStep === 2”></app-step2>
<app-step3 *ngIf=“currentStep === 3”></app-step3>
</div>
第 3 步:在组件装饰器中添加动画
// component
animations: [
trigger('animStep', [
transition(':increment', right),
transition(':decrement', left),
]),
],
第 3 步:触发值的变化
currentStep += 1;