新聞中心
前提條件
對下列概念有基本的理解:

成都創(chuàng)新互聯(lián)公司是一家以成都網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計、品牌設(shè)計、軟件運維、seo優(yōu)化排名、小程序App開發(fā)等移動開發(fā)為一體互聯(lián)網(wǎng)公司。已累計為成都餐廳設(shè)計等眾行業(yè)中小客戶提供優(yōu)質(zhì)的互聯(lián)網(wǎng)建站和軟件開發(fā)服務(wù)。
- Angular 動畫簡介
- 轉(zhuǎn)場與觸發(fā)器
- 可復(fù)用動畫
路由能讓用戶在應(yīng)用中的不同路由之間導(dǎo)航。當(dāng)用戶從一個路由導(dǎo)航到另一個路由時,Angular 路由器會把這個 URL 映射到一個相關(guān)的組件,并顯示其視圖。為這種路由轉(zhuǎn)換添加動畫,將極大地提升用戶體驗。
Angular 路由器天生帶有高級動畫功能,它可以讓你為在路由變化時為視圖之間設(shè)置轉(zhuǎn)場動畫。要想在路由切換時生成動畫序列,你需要首先定義出嵌套的動畫序列。從宿主視圖的頂層組件開始,在這些內(nèi)嵌視圖的宿主組件中嵌套添加其它動畫。
要啟用路由轉(zhuǎn)場動畫,需要做如下步驟:
- 為應(yīng)用導(dǎo)入路由模塊,并創(chuàng)建一個路由配置來定義可能的路由。
- 添加路由器出口,來告訴 Angular 路由器要把激活的組件放在 DOM 中的什么位置。
- 定義動畫。
讓我們以兩個路由之間的導(dǎo)航過程來解釋一下路由轉(zhuǎn)場動畫,Home 和 About 分別與 ?HomeComponent ?和 ?AboutComponent ?的視圖相關(guān)聯(lián)。所有這些組件視圖都是頂層視圖的子節(jié)點,其宿主是 ?AppComponent?。我們將實現(xiàn)路由器過渡動畫,該動畫會在出現(xiàn)新視圖時向右滑動,并當(dāng)用戶在兩個路由之間導(dǎo)航時把舊視圖滑出。
路由配置
首先,使用 ?RouterModule ?類提供的方法來配置一組路由。該路由配置會告訴路由器該如何導(dǎo)航。
使用 ?RouterModule.forRoot? 方法來定義一組路由。同時,把其返回值添加到主模塊 ?AppModule ?的 ?imports ?數(shù)組中。
注意:
在根模塊 ?
AppModule?中使用 ?
RouterModule.forRoot? 方法來注冊一些頂層應(yīng)用路由和提供者。對于特性模塊,則改用 ?
RouterModule.forChild? 方法。
下列配置定義了應(yīng)用程序中可能的路由。
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { RouterModule } from '@angular/router';
import { AppComponent } from './app.component';
import { OpenCloseComponent } from './open-close.component';
import { OpenClosePageComponent } from './open-close-page.component';
import { OpenCloseChildComponent } from './open-close.component.4';
import { ToggleAnimationsPageComponent } from './toggle-animations-page.component';
import { StatusSliderComponent } from './status-slider.component';
import { StatusSliderPageComponent } from './status-slider-page.component';
import { HeroListPageComponent } from './hero-list-page.component';
import { HeroListGroupPageComponent } from './hero-list-group-page.component';
import { HeroListGroupsComponent } from './hero-list-groups.component';
import { HeroListEnterLeavePageComponent } from './hero-list-enter-leave-page.component';
import { HeroListEnterLeaveComponent } from './hero-list-enter-leave.component';
import { HeroListAutoCalcPageComponent } from './hero-list-auto-page.component';
import { HeroListAutoComponent } from './hero-list-auto.component';
import { HomeComponent } from './home.component';
import { AboutComponent } from './about.component';
import { InsertRemoveComponent } from './insert-remove.component';
import { QueryingComponent } from './querying.component';
@NgModule({
imports: [
BrowserModule,
BrowserAnimationsModule,
RouterModule.forRoot([
{ path: '', pathMatch: 'full', redirectTo: '/enter-leave' },
{
path: 'open-close',
component: OpenClosePageComponent,
data: { animation: 'openClosePage' }
},
{
path: 'status',
component: StatusSliderPageComponent,
data: { animation: 'statusPage' }
},
{
path: 'toggle',
component: ToggleAnimationsPageComponent,
data: { animation: 'togglePage' }
},
{
path: 'heroes',
component: HeroListPageComponent,
data: { animation: 'filterPage' }
},
{
path: 'hero-groups',
component: HeroListGroupPageComponent,
data: { animation: 'heroGroupPage' }
},
{
path: 'enter-leave',
component: HeroListEnterLeavePageComponent,
data: { animation: 'enterLeavePage' }
},
{
path: 'auto',
component: HeroListAutoCalcPageComponent,
data: { animation: 'autoPage' }
},
{
path: 'insert-remove',
component: InsertRemoveComponent,
data: { animation: 'insertRemovePage' }
},
{
path: 'querying',
component: QueryingComponent,
data: { animation: 'queryingPage' }
},
{
path: 'home',
component: HomeComponent,
data: { animation: 'HomePage' }
},
{
path: 'about',
component: AboutComponent,
data: { animation: 'AboutPage' }
},
])
],?home ?和 ?about ?路徑分別關(guān)聯(lián)著 ?HomeComponent ?和 ?AboutComponent ?視圖。該路由配置告訴 Angular 路由器當(dāng)導(dǎo)航匹配了相應(yīng)的路徑時,就實例化 ?HomeComponent ?和 ?AboutComponent ?視圖。
除了 ?path?、?component ?之外,每個路由定義中的 ?data ?屬性也定義了與此路由有關(guān)的動畫配置。當(dāng)路由變化時,?data ?屬性的值就會傳給 ?AppComponent?。你還可以在路由配置中傳遞其它的值供路由的動畫使用。?data ?屬性的值必須滿足 ?routeAnimation? 中定義的轉(zhuǎn)場動畫的要求,稍后我們就會定義它。
注意:
這個 ?
data?中的屬性名可以是任意的。比如,上面例子中使用的名字
animation 就是隨便起的。
路由出口
配置好路由之后,還要告訴 Angular 路由器當(dāng)路由匹配時,要把視圖渲染到那里。你可以通過在根組件 ?AppComponent ?的模板中插入一個 ?? 容器來指定路由出口的位置。
?ChildrenOutletContexts ?包含有關(guān)插座和激活路由的信息。我們可以用每個 ?Route ?的 ?data ?屬性來為我們的路由轉(zhuǎn)換設(shè)置動畫。
?AppComponent ?中定義了一個可以檢測視圖何時發(fā)生變化的方法,該方法會基于路由配置的 ?data ?屬性值,將動畫狀態(tài)值賦值給動畫觸發(fā)器(?@routeAnimation?)。下面就是一個 ?AppComponent ?中的范例方法,用于檢測路由在何時發(fā)生了變化。
constructor(private contexts: ChildrenOutletContexts) {}
getRouteAnimationData() {
return this.contexts.getContext('primary')?.route?.snapshot?.data?.['animation'];
}這里的 ?getRouteAnimationData()? 方法會獲取這個 outlet 指令的值(通過 ?#outlet="outlet"?),并根據(jù)當(dāng)前活動路由的自定義數(shù)據(jù)返回一個表示動畫狀態(tài)的字符串值??梢杂眠@個數(shù)據(jù)來控制各個路由之間該執(zhí)行哪個轉(zhuǎn)場。
動畫定義
動畫可以直接在組件中定義。對于此范例,我們會在獨立的文件中定義動畫,這讓我們可以復(fù)用這些動畫。
下面的代碼片段定義了一個名叫 ?slideInAnimation ?的可復(fù)用動畫。
export const slideInAnimation =
trigger('routeAnimations', [
transition('HomePage <=> AboutPage', [
style({ position: 'relative' }),
query(':enter, :leave', [
style({
position: 'absolute',
top: 0,
left: 0,
width: '100%'
})
]),
query(':enter', [
style({ left: '-100%' })
]),
query(':leave', animateChild()),
group([
query(':leave', [
animate('300ms ease-out', style({ left: '100%' }))
]),
query(':enter', [
animate('300ms ease-out', style({ left: '0%' }))
]),
]),
]),
transition('* <=> *', [
style({ position: 'relative' }),
query(':enter, :leave', [
style({
position: 'absolute',
top: 0,
left: 0,
width: '100%'
})
]),
query(':enter', [
style({ left: '-100%' })
]),
query(':leave', animateChild()),
group([
query(':leave', [
animate('200ms ease-out', style({ left: '100%', opacity: 0 }))
]),
query(':enter', [
animate('300ms ease-out', style({ left: '0%' }))
]),
query('@*', animateChild())
]),
])
]);該動畫定義做了如下事情:
- 定義兩個轉(zhuǎn)場。每個觸發(fā)器都可以定義多個狀態(tài)和多個轉(zhuǎn)場
- 調(diào)整宿主視圖和子視圖的樣式,以便在轉(zhuǎn)場期間,控制它們的相對位置
- 使用 ?
query()? 來確定哪個子視圖正在進(jìn)入或離開宿主視圖
路由的變化會激活這個動畫觸發(fā)器,并應(yīng)用一個與該狀態(tài)變更相匹配的轉(zhuǎn)場
注意:
這些轉(zhuǎn)場狀態(tài)必須和路由配置中定義的 ?
data?屬性的值相一致。
通過將可復(fù)用動畫 ?slideInAnimation ?添加到 ?AppComponent ?的 ?animations ?元數(shù)據(jù)中,可以讓此動畫定義能用在你的應(yīng)用中。
@Component({
selector: 'app-root',
templateUrl: 'app.component.html',
styleUrls: ['app.component.css'],
animations: [
slideInAnimation
]
})那么,我們來分解一下這個動畫定義,并仔細(xì)看看它做了什么……
為宿主組件和子組件添加樣式
在轉(zhuǎn)場期間,新視圖將直接插入在舊視圖后面,并且這兩個元素會同時出現(xiàn)在屏幕上。要防止這種行為,就要修改宿主視圖,改用相對定位。然后,把已移除或已插入的子視圖改用絕對定位。在這些視圖中添加樣式,就可以讓容器就地播放動畫,并防止某個視圖影響頁面中其它視圖的位置。
trigger('routeAnimations', [
transition('HomePage <=> AboutPage', [
style({ position: 'relative' }),
query(':enter, :leave', [
style({
position: 'absolute',
top: 0,
left: 0,
width: '100%'
})
]),查詢視圖的容器
使用 ?query()? 方法可以找出當(dāng)前宿主組件中的動畫元素。?query(":enter")? 語句會返回已插入的視圖,?query(":leave")? 語句會返回已移除的視圖。
假設(shè)你正在從 Home 轉(zhuǎn)場到 About,?Home => About?。
query(':enter', [
style({ left: '-100%' })
]),
query(':leave', animateChild()),
group([
query(':leave', [
animate('300ms ease-out', style({ left: '100%' }))
]),
query(':enter', [
animate('300ms ease-out', style({ left: '0%' }))
]),
]),
]),
transition('* <=> *', [
style({ position: 'relative' }),
query(':enter, :leave', [
style({
position: 'absolute',
top: 0,
left: 0,
width: '100%'
})
]),
query(':enter', [
style({ left: '-100%' })
]),
query(':leave', animateChild()),
group([
query(':leave', [
animate('200ms ease-out', style({ left: '100%', opacity: 0 }))
]),
query(':enter', [
animate('300ms ease-out', style({ left: '0%' }))
]),
query('@*', animateChild())
]),
])在設(shè)置了視圖的樣式之后,動畫代碼會執(zhí)行如下操作:
- ?
query(':enter style({ left: '-100%'})? 會匹配添加的視圖,并通過將其定位在最左側(cè)來隱藏這個新視圖。 - 在正在離開的視圖上調(diào)用 ?
animateChild()?,來運行其子動畫。 - 使用?
group()?函數(shù)使內(nèi)部動畫并行運行。 - 在 ?
group()? 函數(shù)中: - 查詢已移除的視圖,并讓它從右側(cè)滑出。
- 使用緩動函數(shù)和持續(xù)時間定義的動畫,讓這個新視圖滑入。
- 當(dāng)主動畫完成之后,在這個新視圖上調(diào)用 ?
animateChild()? 方法,以運行其子動畫。
此動畫將導(dǎo)致 ?about ?視圖從左側(cè)劃入。
你現(xiàn)在有了一個基本的路由動畫,可以在從一個視圖路由到另一個視圖時播放動畫。
標(biāo)題名稱:創(chuàng)新互聯(lián)Angular教程:Angular路由轉(zhuǎn)場動畫
分享鏈接:http://www.dlmjj.cn/article/djdsgch.html


咨詢
建站咨詢
