W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
對下列概念有基本的理解:
到目前為止,我們已經(jīng)學(xué)過了單個 HTML 元素的簡單動畫。Angular 還允許你在進入和離開頁面時播放 "動畫協(xié)調(diào)序列",比如當(dāng)整個網(wǎng)格或元素列表進入或離開頁面時,多個條目的動畫之間需要彼此協(xié)調(diào)時間。你可以選擇并行執(zhí)行多個動畫,或者按順序逐個運行離散動畫。
用來控制復(fù)雜動畫序列的函數(shù)如下:
函數(shù) |
詳情 |
---|---|
query()
|
用于查找一個或多個內(nèi)部 HTML 元素。 |
stagger()
|
用于為多元素動畫應(yīng)用級聯(lián)延遲。 |
?group() ? |
用于并行執(zhí)行多個動畫步驟。 |
sequence()
|
用于逐個順序執(zhí)行多個動畫步驟。 |
大多數(shù)復(fù)雜動畫都依賴 ?query()
? 函數(shù)來查找子元素并對其應(yīng)用動畫,基本的例子是:
例子 |
詳情 |
---|---|
|
用于查詢簡單的 HTML 元素并直接對它們應(yīng)用動畫。 |
|
用于查詢子元素,這些元素本身就應(yīng)用了動畫元數(shù)據(jù)并觸發(fā)這樣的動畫(否則將被當(dāng)前/父元素的動畫阻止)。 |
query()
的第一個參數(shù)是一個 css 選擇器字符串,它還可以包含以下 Angular 特定的標(biāo)記:
標(biāo)記 |
詳情 |
---|---|
|
用于進入/離開元素。 |
:animating
|
對于當(dāng)前正在播放動畫的元素。 |
@*
@triggerName
|
對于具有任何(或特定)觸發(fā)器的元素。 |
:self
|
動畫元素本身。 |
進入和離開元素
并非所有子元素都會實際上被認(rèn)為是進入/離開;有時,這可能是違反直覺和令人困惑的。
你還可以在 Querying 選項卡下的動畫實時示例(在動畫介紹部分)中看到這方面的插圖。
通過 ?query()
? 查詢子元素后,?stagger()
? 函數(shù)允許你定義每個查詢的動畫項之間的時間間隙,從而為元素之間延遲設(shè)置動畫。
下面的例子演示了如何使用 ?query()
? 和 ?stagger()
? 函數(shù)對依次添加的英雄列表從上到下播放動畫(有少許延遲)。
query()
? 查閱正在進入或離開頁面的任意元素。該查詢會找出那些符合某種匹配 CSS 選擇器的元素
style()
? 為其設(shè)置初始樣式。使其變得透明,并使用 ?transform
?將其移出位置,以便它能滑入后就位。
stagger()
? 來在每個動畫之間延遲 30 毫秒
animations: [
trigger('pageAnimations', [
transition(':enter', [
query('.hero', [
style({opacity: 0, transform: 'translateY(-100px)'}),
stagger(30, [
animate('500ms cubic-bezier(0.35, 0, 0.25, 1)',
style({ opacity: 1, transform: 'none' }))
])
])
])
]),
你已經(jīng)了解了如何在兩個連續(xù)的動畫之間添加延遲。不過你可能還想配置一些并行的動畫。比如,你可能希望為同一個元素的兩個 CSS 屬性設(shè)置動畫,但要為每個屬性使用不同的 ?easing
?函數(shù)。這時,你可以使用動畫函數(shù) ?group()
?。
注意:
?group()
?函數(shù)用于對動畫步驟進行分組,而不是針對動畫元素。
在下面的例子中,對 ?:enter
? 和 ?:leave
? 使用分組,可以配置兩種不同的時序。它們會同時作用于同一個元素,但彼此獨立運行。
animations: [
trigger('flyInOut', [
state('in', style({
width: '*',
transform: 'translateX(0)', opacity: 1
})),
transition(':enter', [
style({ width: 10, transform: 'translateX(50px)', opacity: 0 }),
group([
animate('0.3s 0.1s ease', style({
transform: 'translateX(0)',
width: '*'
})),
animate('0.3s ease', style({
opacity: 1
}))
])
]),
transition(':leave', [
group([
animate('0.3s ease', style({
transform: 'translateX(50px)',
width: 10
})),
animate('0.3s 0.2s ease', style({
opacity: 0
}))
])
])
])
]
復(fù)雜動畫中可以同時發(fā)生很多事情。但是當(dāng)你要創(chuàng)建一個需要讓幾個子動畫逐個執(zhí)行的動畫時,該怎么辦呢?以前我們使用 ?group()
? 來同時并行運行多個動畫。
第二個名叫 ?sequence()
? 的函數(shù)會讓你一個接一個地運行這些動畫。在 ?sequence()
? 中,這些動畫步驟由 ?style()
? 或 ?animate()
? 的函數(shù)調(diào)用組成。
style()
? 用來立即應(yīng)用所指定的樣式數(shù)據(jù)。
animate()
? 用來在一定的時間間隔內(nèi)應(yīng)用樣式數(shù)據(jù)。來看看范例應(yīng)用中的另一個動畫。在 Filter/Stagger 頁,往 Search Heroes 文本框中輸入一些文本,比如 ?Magnet
?或 ?tornado
?。
過濾器會在你輸入時實時工作。每當(dāng)你鍵入一個新字母時,就會有一些元素離開頁面,并且過濾條件也會逐漸變得更加嚴(yán)格。相反,當(dāng)你刪除過濾器中的每個字母時,英雄列表也會逐漸重新進入頁面中。
HTML 模板中包含一個名叫 ?filterAnimation
?的觸發(fā)器。
<label for="search">Search heroes: </label>
<input type="text" id="search" #criteria
(input)="updateCriteria(criteria.value)"
placeholder="Search heroes">
<ul class="heroes" [@filterAnimation]="heroesTotal">
<li *ngFor="let hero of heroes" class="hero">
<div class="inner">
<span class="badge">{{ hero.id }}</span>
<span class="name">{{ hero.name }}</span>
</div>
</li>
</ul>
該組件裝飾器中的 ?filterAnimation
?包含三個轉(zhuǎn)場。
@Component({
animations: [
trigger('filterAnimation', [
transition(':enter, * => 0, * => -1', []),
transition(':increment', [
query(':enter', [
style({ opacity: 0, width: 0 }),
stagger(50, [
animate('300ms ease-out', style({ opacity: 1, width: '*' })),
]),
], { optional: true })
]),
transition(':decrement', [
query(':leave', [
stagger(50, [
animate('300ms ease-out', style({ opacity: 0, width: 0 })),
]),
])
]),
]),
]
})
export class HeroListPageComponent implements OnInit {
heroesTotal = -1;
get heroes() { return this._heroes; }
private _heroes: Hero[] = [];
ngOnInit() {
this._heroes = HEROES;
}
updateCriteria(criteria: string) {
criteria = criteria ? criteria.trim() : '';
this._heroes = HEROES.filter(hero => hero.name.toLowerCase().includes(criteria.toLowerCase()));
const newTotal = this.heroes.length;
if (this.heroesTotal !== newTotal) {
this.heroesTotal = newTotal;
} else if (!criteria) {
this.heroesTotal = -1;
}
}
}
這個例子中的代碼包含下列任務(wù):
對于每次匹配:
盡管 Angular 開箱即用的支持 ?*ngFor
? 列表項動畫,但如果只是它們的順序變化了,就無法支持。因為 Angular 會忘記哪個元素是哪個元素,從而導(dǎo)致這些動畫被破壞。幫助 Angular 跟蹤此類元素的唯一方法是將 ?TrackByFunction
?分配給 ?NgForOf
?指令。這可確保 Angular 始終知道哪個元素是哪個,從而允許它始終將正確的動畫應(yīng)用于正確的元素。
重要:
如果你需要為 ?*ngFor
? 列表的條目設(shè)置動畫,并且此類條目的順序有可能在運行時更改,請始終使用 ?TrackByFunction
?。
Angular 中這些用于多元素動畫的函數(shù),都要從 ?query()
? 開始,查找出內(nèi)部元素,比如找出某個 ?<div>
? 中的所有圖片。其余函數(shù) ?stagger()
?、?group()
? 和 ?sequence()
? 會以級聯(lián)方式或你的自定義邏輯來控制要如何應(yīng)用多個動畫步驟。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: