詳解Angular路由動(dòng)畫及高階動(dòng)畫函數(shù)
一、路由動(dòng)畫
路由動(dòng)畫需要在host元數(shù)據(jù)中指定觸發(fā)器。動(dòng)畫注意不要過多,否則適得其反。
內(nèi)容優(yōu)先,引導(dǎo)用戶去注意到某個(gè)內(nèi)容。動(dòng)畫只是輔助手段。
在router.animate.ts中定義一個(gè)進(jìn)場動(dòng)畫,一個(gè)離場動(dòng)畫。
因?yàn)檫M(jìn)場動(dòng)畫和離場動(dòng)畫用的特別頻繁,有一個(gè)別名叫: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中使用路由動(dòng)畫。
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: "企業(yè)協(xié)作平臺",
desc: "這是一個(gè)企業(yè)內(nèi)部項(xiàng)目",
coverImg: "assets/images/covers/0.jpg"
},
{
name: "自動(dòng)化測試項(xiàng)目",
desc: "這是一個(gè)企業(yè)內(nèi)部項(xiàng)目",
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: '新建項(xiàng)目' }
});
dialogRef.afterClosed().subscribe((result) => {
console.log(result);
});
}
lauchInviteDialog() {
const dialogRef = this.dialog.open(InviteComponent);
}
lauchUpdateDialog() {
const dialogRef = this.dialog.open(NewProjectComponent, {
data: { title: '編輯項(xiàng)目' }
});
}
lauchConfimDialog() {
const dialogRef = this.dialog.open(ConfirmDialogComponent, {
data: { title: '編輯項(xiàng)目', content: '您確認(rèn)刪除該項(xiàng)目嗎?' }
});
}
}
在task-home中使用路由動(dòng)畫。
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: "新建任務(wù)" }
});
}
lauchCopyTaskDialog() {
const dialogRef = this.dialog.open(CopyTaskComponent, {
data: { lists: this.lists }
});
}
launchUpdateTaskDialog(task) {
const dialogRef = this.dialog.open(NewTaskComponent, {
data: { title: "修改任務(wù)", task: task }
});
}
launchConfirmDialog() {
const dialogRef = this.dialog.open(ConfirmDialogComponent, {
data: { title: "刪除任務(wù)列表", content: "您確定要?jiǎng)h除該任務(wù)列表嗎?" }
});
}
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: "任務(wù)一: 去星巴克買咖啡",
completed: true,
priority: 3,
owner: {
id: 1,
name: "張三",
avatar: "avatars:svg-11"
},
dueDate: new Date(),
reminder: new Date()
},
{
id: 2,
desc: "任務(wù)一: 完成老板布置的PPT作業(yè)",
completed: false,
priority: 2,
owner: {
id: 2,
name: "李四",
avatar: "avatars:svg-12"
},
dueDate: new Date()
}
]
},
{
id: 2,
name: "進(jìn)行中",
tasks: [
{
id: 1,
desc: "任務(wù)三: 項(xiàng)目代碼評審",
completed: false,
priority: 1,
owner: {
id: 1,
name: "王五",
avatar: "avatars:svg-13"
},
dueDate: new Date()
},
{
id: 2,
desc: "任務(wù)一: 制定項(xiàng)目計(jì)劃",
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>項(xiàng)目首頁</h4>
<p mat-line mat-subheader> 查看您的所有項(xiàng)目</p>
</mat-list-item>
<mat-list-item [routerLink]="['/task']">
<mat-icon mat-list-icon svgIcon="projects"></mat-icon>
<h4 mat-line>任務(wù)首頁</h4>
<p mat-line mat-subheader> 查看您的所有項(xiàng)目</p>
</mat-list-item>
注意:一定要用HostBinding形式。
二、Group
用于同時(shí)進(jìn)行一組動(dòng)畫變換
group([animate(...),animate(...)...])接收一個(gè)數(shù)組,數(shù)組里寫多個(gè)動(dòng)畫。
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用于父節(jié)點(diǎn)尋找子節(jié)點(diǎn),把動(dòng)畫應(yīng)用到選中元素。非常強(qiáng)大。
Stagger指定有多個(gè)滿足Query的元素,每個(gè)的動(dòng)畫之間有間隔。
做一個(gè)示例:新建的時(shí)候同時(shí)新建2個(gè)項(xiàng)目,兩個(gè)新建出的項(xiàng)目的動(dòng)畫依次產(chǎn)生,第一個(gè)完成后才開始第二個(gè)。

建立list.animate.ts
進(jìn)場動(dòng)畫,先隱藏起來,通過stagger間隔1000s做一個(gè)1s的動(dòng)畫。
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,后面的狀態(tài)動(dòng)畫都是可選的
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中使用
應(yīng)用query動(dòng)畫一般都是跟*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>
修改對應(yīng)的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 //第一步,導(dǎo)入listAnimation
]
})
export class ProjectListComponent implements OnInit {
@HostBinding('@routeAnim') state;
//第二步,改造一下數(shù)組,加id
projects = [
{
id:1,
name: "企業(yè)協(xié)作平臺",
desc: "這是一個(gè)企業(yè)內(nèi)部項(xiàng)目",
coverImg: "assets/images/covers/0.jpg"
},
{
id:2,
name: "自動(dòng)化測試項(xiàng)目",
desc: "這是一個(gè)企業(yè)內(nèi)部項(xiàng)目",
coverImg: "assets/images/covers/2.jpg"
}
];
constructor(private dialog: MatDialog) { }
ngOnInit() { }
//第三步,新增元素時(shí)hard code一下
openNewProjectDialog() {
// this.dialog.open(NewProjectComponent,{data:'this is a dialog'});
const dialogRef = this.dialog.open(NewProjectComponent, {
data: { title: '新建項(xiàng)目' }
});
dialogRef.afterClosed().subscribe((result) => {
console.log(result);
this.projects = [...this.projects,
{id:3,name:'一個(gè)新項(xiàng)目',desc:'這是一個(gè)新項(xiàng)目',coverImg:"assets/images/covers/3.jpg"},
{id:4,name:'又一個(gè)新項(xiàng)目',desc:'這是又一個(gè)新項(xiàng)目',coverImg:"assets/images/covers/4.jpg"}]
});
}
lauchInviteDialog() {
const dialogRef = this.dialog.open(InviteComponent);
}
lauchUpdateDialog() {
const dialogRef = this.dialog.open(NewProjectComponent, {
data: { title: '編輯項(xiàng)目' }
});
}
//第四步,改造一下刪除項(xiàng)目
lauchConfimDialog(project) {
const dialogRef = this.dialog.open(ConfirmDialogComponent, {
data: { title: '刪除項(xiàng)目', content: '您確認(rèn)刪除該項(xiàng)目嗎?' }
});
dialogRef.afterClosed().subscribe(result=>{
console.log(result);
this.projects=this.projects.filter(p=>p.id!=project.id);
});
}
}
Stagger使得在多個(gè)元素時(shí)候,動(dòng)畫交錯(cuò)開,而不是一起。
以上就是詳解Angular路由動(dòng)畫及高階動(dòng)畫函數(shù)的詳細(xì)內(nèi)容,更多關(guān)于Angular路由動(dòng)畫及高階動(dòng)畫函數(shù)的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
AngularJS中的Promise詳細(xì)介紹及實(shí)例代碼
這篇文章主要介紹了AngularJS中的Promise詳細(xì)介紹及實(shí)例代碼的相關(guān)資料,Promise是一種模式,以同步操作的流程形式來操作異步事件,避免了層層嵌套,可以鏈?zhǔn)讲僮鳟惒绞录?,需要的朋友可以參考?/div> 2016-12-12
Ionic + Angular.js實(shí)現(xiàn)圖片輪播的方法示例
圖片輪播在我們?nèi)粘i_發(fā)中是再熟悉不過的了,下面這篇文章主要給大家介紹了Ionic + Angular實(shí)現(xiàn)圖片輪播的方法,文中給出了詳細(xì)的示例代碼供大家參考學(xué)習(xí),需要的朋友們下面來一起看看吧。2017-05-05
Angular實(shí)踐之將Input與Lifecycle轉(zhuǎn)換成流示例詳解
這篇文章主要為大家介紹了Angular實(shí)踐之將Input與Lifecycle轉(zhuǎn)換成流示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02
angular將html代碼輸出為內(nèi)容的實(shí)例
今天小編就為大家分享一篇angular將html代碼輸出為內(nèi)容的實(shí)例,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-09-09
AngularJs導(dǎo)出數(shù)據(jù)到Excel的示例代碼
本篇文章主要介紹了AngularJs導(dǎo)出Excel的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-08-08
Angular實(shí)現(xiàn)一個(gè)簡單的多選復(fù)選框的彈出框指令實(shí)例
下面小編就為大家?guī)硪黄狝ngular實(shí)現(xiàn)一個(gè)簡單的多選復(fù)選框的彈出框指令實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-04-04
Angular項(xiàng)目如何使用攔截器?httpClient?請求響應(yīng)處理
這篇文章主要介紹了Angular項(xiàng)目簡單使用攔截器httpClient請求響應(yīng)處理,目前我的Angular版本是Angular?17.3,版本中實(shí)現(xiàn)請求和響應(yīng)的攔截處理了,這種機(jī)制非常適合添加如身份驗(yàn)證頭、錯(cuò)誤統(tǒng)一處理、日志記錄等功能,需要的朋友可以參考下2024-06-06最新評論

