详解Angular路由动画及高阶动画函数

一、路由动画

路由动画需要在host元数据中指定触发器。动画注意不要过多,否则适得其反。

内容优先,引导用户去注意到某个内容。动画只是辅助手段。

在router.animate.ts中定义一个进场动画,一个离场动画。

因为进场动画和离场动画用的特别频繁,有一个别名叫:enter和:leave。

import { trigger, state, transition, style, animate} from '@angular/animations';

export const slideToRight = trigger('routeAnim',[

state('void',style({'position':'fixed','width':'100%','height':'100%'})),

state('*',style({'position':'fixed','width':'100%','height':'80%'})),

transition('void => *',[

style({transform:'translateX(-100%)'}),

animate('.5s ease-in-out', style({transform:'translateX(0)'}))

]),

transition('* => void',[

style({transform:'translateX(0)'}),

animate('.5s ease-in-out', style({transform:'translateX(100%)'}))

]),

]);

在project-list中使用路由动画。

import { Component, OnInit , HostBinding } from "@angular/core";

import { MatDialog } from "@angular/material";

import { NewProjectComponent } from "../new-project/new-project.component";

import { InviteComponent } from '../invite/invite.component';

import { ConfirmDialogComponent } from '../../shared/confirm-dialog/confirm-dialog.component';

import {slideToRight} from '../../animate/router.animate'

@Component({

selector: "app-project-list",

templateUrl: "./project-list.component.html",

styleUrls: ["./project-list.component.scss"],

animations:[

slideToRight

]

})

export class ProjectListComponent implements OnInit {

@HostBinding('@routeAnim') state;

projects = [

{

name: "企业协作平台",

desc: "这是一个企业内部项目",

coverImg: "assets/images/covers/0.jpg"

},

{

name: "自动化测试项目",

desc: "这是一个企业内部项目",

coverImg: "assets/images/covers/2.jpg"

}

];

constructor(private dialog: MatDialog) { }

ngOnInit() { }

openNewProjectDialog() {

// this.dialog.open(NewProjectComponent,{data:'this is a dialog'});

const dialogRef = this.dialog.open(NewProjectComponent, {

data: { title: '新建项目' }

});

dialogRef.afterClosed().subscribe((result) => {

console.log(result);

});

}

lauchInviteDialog() {

const dialogRef = this.dialog.open(InviteComponent);

}

lauchUpdateDialog() {

const dialogRef = this.dialog.open(NewProjectComponent, {

data: { title: '编辑项目' }

});

}

lauchConfimDialog() {

const dialogRef = this.dialog.open(ConfirmDialogComponent, {

data: { title: '编辑项目', content: '您确认删除该项目吗?' }

});

}

}

在task-home中使用路由动画。

import { Component, OnInit , HostBinding } from "@angular/core";

import { NewTaskComponent } from "../new-task/new-task.component";

import { MatDialog } from "@angular/material";

import { CopyTaskComponent } from "../copy-task/copy-task.component";

import { ConfirmDialogComponent } from "../../shared/confirm-dialog/confirm-dialog.component";

import { NewTaskListComponent } from "../new-task-list/new-task-list.component";

import {slideToRight} from '../../animate/router.animate';

@Component({

selector: "app-task-home",

templateUrl: "./task-home.component.html",

styleUrls: ["./task-home.component.scss"],

animations:[

slideToRight

]

})

export class TaskHomeComponent implements OnInit {

constructor(private dialog: MatDialog) {}

@HostBinding('@routeAnim') state;

ngOnInit() {}

launchNewTaskDialog() {

// this.dialog.open(NewTaskComponent);

const dialogRef = this.dialog.open(NewTaskComponent, {

data: { title: "新建任务" }

});

}

lauchCopyTaskDialog() {

const dialogRef = this.dialog.open(CopyTaskComponent, {

data: { lists: this.lists }

});

}

launchUpdateTaskDialog(task) {

const dialogRef = this.dialog.open(NewTaskComponent, {

data: { title: "修改任务", task: task }

});

}

launchConfirmDialog() {

const dialogRef = this.dialog.open(ConfirmDialogComponent, {

data: { title: "删除任务列表", content: "您确定要删除该任务列表吗?" }

});

}

launchEditListDialog() {

const dialogRef = this.dialog.open(NewTaskListComponent, {

data: { title: "更改列表名称" }

});

dialogRef.afterClosed().subscribe(result => console.log(result));

}

launchNewListDialog() {

const dialogRef = this.dialog.open(NewTaskListComponent, {

data: { title: "新建列表名称" }

});

dialogRef.afterClosed().subscribe(result => console.log(result));

}

lists = [

{

id: 1,

name: "待办",

tasks: [

{

id: 1,

desc: "任务一: 去星巴克买咖啡",

completed: true,

priority: 3,

owner: {

id: 1,

name: "张三",

avatar: "avatars:svg-11"

},

dueDate: new Date(),

reminder: new Date()

},

{

id: 2,

desc: "任务一: 完成老板布置的PPT作业",

completed: false,

priority: 2,

owner: {

id: 2,

name: "李四",

avatar: "avatars:svg-12"

},

dueDate: new Date()

}

]

},

{

id: 2,

name: "进行中",

tasks: [

{

id: 1,

desc: "任务三: 项目代码评审",

completed: false,

priority: 1,

owner: {

id: 1,

name: "王五",

avatar: "avatars:svg-13"

},

dueDate: new Date()

},

{

id: 2,

desc: "任务一: 制定项目计划",

completed: false,

priority: 2,

owner: {

id: 2,

name: "李四",

avatar: "avatars:svg-12"

},

dueDate: new Date()

}

]

}

];

}

定义路由

<mat-list-item [routerLink]="['/project']">

<mat-icon mat-list-icon svgIcon="projects"></mat-icon>

<h4 mat-line>项目首页</h4>

<p mat-line mat-subheader> 查看您的所有项目</p>

</mat-list-item>

<mat-list-item [routerLink]="['/task']">

<mat-icon mat-list-icon svgIcon="projects"></mat-icon>

<h4 mat-line>任务首页</h4>

<p mat-line mat-subheader> 查看您的所有项目</p>

</mat-list-item>

注意:一定要用HostBinding形式。

二、Group

用于同时进行一组动画变换

group([animate(...),animate(...)...])接收一个数组,数组里写多个动画。

import { trigger, state, transition, style, animate, group} from '@angular/animations';

export const slideToRight = trigger('routeAnim',[

state('void',style({'position':'fixed','width':'100%','height':'80%'})),

state('*',style({'position':'fixed','width':'100%','height':'80%'})),

transition(':enter',[

style({transform:'translateX(-100%)',opacity:'0'}),

group([

animate('.5s ease-in-out', style({transform:'translateX(0)'})),

animate('.3s ease-in', style({opacity:1}))

])

]),

transition(':leave',[

style({transform:'translateX(0)',opacity:'1'}),

group([

animate('.5s ease-in-out', style({transform:'translateX(100%)'})),

animate('.3s ease-in', style({opacity:0}))

])

]),

]);

三、Query & Stagger

Query用于父节点寻找子节点,把动画应用到选中元素。非常强大。

Stagger指定有多个满足Query的元素,每个的动画之间有间隔。

做一个示例:新建的时候同时新建2个项目,两个新建出的项目的动画依次产生,第一个完成后才开始第二个。

建立list.animate.ts

进场动画,先隐藏起来,通过stagger间隔1000s做一个1s的动画。

import { trigger, state, transition, style, animate, query, animation,stagger} from '@angular/animations';

export const listAnimation = trigger('listAnim', [

transition('* => *', [

query(':enter', style({opacity: 0}), { optional: true }), //加入optional为true,后面的状态动画都是可选的

query(':enter', stagger(1000, [

animate('1s', style({opacity: 1}))

]), { optional: true }),

query(':leave', style({opacity: 1}), { optional: true }),

query(':leave', stagger(1000, [

animate('1s', style({opacity: 0}))

]), { optional: true })

])

]);

在project_list中使用

应用query动画一般都是跟*ngFor在一起的,需要外面套一层div。

<div class="container" [@listAnim]="projects.length">

<app-project-item *ngFor="let project of projects" [item]="project"

class="card"

(onInvite)="lauchInviteDialog()"

(onEdit)="lauchUpdateDialog()"

(onDelete)="lauchConfimDialog(project)">

</app-project-item>

</div>

<button class="ab-buttonmad-fab fab-button" mat-fab type="button" (click)="openNewProjectDialog()">

<mat-icon>add</mat-icon>

</button>

修改对应的css

// :host{

// display: flex;

// flex-direction: row;

// flex-wrap: wrap;

// }

//把host改为div

.container{

display: flex;

flex-direction: row;

flex-wrap: wrap;

}

修改一下component

import { Component, OnInit , HostBinding } from "@angular/core";

import { MatDialog } from "@angular/material";

import { NewProjectComponent } from "../new-project/new-project.component";

import { InviteComponent } from '../invite/invite.component';

import { ConfirmDialogComponent } from '../../shared/confirm-dialog/confirm-dialog.component';

import {slideToRight} from '../../animate/router.animate'

import { listAnimation } from '../../animate/list.animate';

import { projection } from '@angular/core/src/render3';

@Component({

selector: "app-project-list",

templateUrl: "./project-list.component.html",

styleUrls: ["./project-list.component.scss"],

animations:[

slideToRight,listAnimation //第一步,导入listAnimation

]

})

export class ProjectListComponent implements OnInit {

@HostBinding('@routeAnim') state;

//第二步,改造一下数组,加id

projects = [

{

id:1,

name: "企业协作平台",

desc: "这是一个企业内部项目",

coverImg: "assets/images/covers/0.jpg"

},

{

id:2,

name: "自动化测试项目",

desc: "这是一个企业内部项目",

coverImg: "assets/images/covers/2.jpg"

}

];

constructor(private dialog: MatDialog) { }

ngOnInit() { }

//第三步,新增元素时hard code一下

openNewProjectDialog() {

// this.dialog.open(NewProjectComponent,{data:'this is a dialog'});

const dialogRef = this.dialog.open(NewProjectComponent, {

data: { title: '新建项目' }

});

dialogRef.afterClosed().subscribe((result) => {

console.log(result);

this.projects = [...this.projects,

{id:3,name:'一个新项目',desc:'这是一个新项目',coverImg:"assets/images/covers/3.jpg"},

{id:4,name:'又一个新项目',desc:'这是又一个新项目',coverImg:"assets/images/covers/4.jpg"}]

});

}

lauchInviteDialog() {

const dialogRef = this.dialog.open(InviteComponent);

}

lauchUpdateDialog() {

const dialogRef = this.dialog.open(NewProjectComponent, {

data: { title: '编辑项目' }

});

}

//第四步,改造一下删除项目

lauchConfimDialog(project) {

const dialogRef = this.dialog.open(ConfirmDialogComponent, {

data: { title: '删除项目', content: '您确认删除该项目吗?' }

});

dialogRef.afterClosed().subscribe(result=>{

console.log(result);

this.projects=this.projects.filter(p=>p.id!=project.id);

});

}

}

Stagger使得在多个元素时候,动画交错开,而不是一起。

以上就是详解Angular路由动画及高阶动画函数的详细内容,更多关于Angular路由动画及高阶动画函数的资料请关注其它相关文章!

以上是 详解Angular路由动画及高阶动画函数 的全部内容, 来源链接: utcz.com/p/220554.html

回到顶部