如何用Angular 6建立各種動畫效果
【51CTO.com快譯】 介紹
就技術角度而言,動畫可以被定義為從初始狀態到最終狀態的轉換過程。如今它已是各種Web應用不可或缺的組成部分。通過動畫,我們不僅能創建出各種酷炫的UI,同時它們也能增加應用程式的趣味性。因此,設計精美的動畫在吸引使用者眼球的同時,也增強了他們的瀏覽體驗。
Angular能夠讓我們創建出具有原生表現效果的動畫。我們將通過本文學習到如何使用Angular 6來建立各種動畫效果。在此,我們將使用Visual Studio Code來進行示例演示。
準備工作
安裝Visual Studio Code和Angular CLI。
如果您是新手,請參閱我以前的Angular 6.0入門文章(https://dzone.com/articles/getting-started-with-angular-60),在自己的機器上建立出Angular 6開發環境。
原始碼
請從GitHub處下載原始碼,地址是:https://github.com/AnkitSharma-007/angular-6-animations。
理解Angular動畫的不同狀態
動畫是某個元素從一種狀態向另一種狀態的轉變, Angular為單個元素定義出了三種不同的狀態。
- Void狀態:void狀態表示某個元素處於不是DOM一部分的狀態。當一個元素被建立且尚未放置到DOM中、或者該元素從DOM中移除時,就處於該狀態。此狀態特別實用,特別是當我們想通過新增或刪除DOM中的元素,來建立動畫的時候,我們在程式碼中用關鍵字void來定義這種狀態。
- Wildcard狀態:又稱元素的預設狀態。不管當前的動畫狀態如何,各種樣式都用這種狀態來定義元素。我們在程式碼中用符號*來定義這種狀態。
- Custom狀態:元素的這種狀態需要在程式碼中被明確定義。我們在程式碼中可以使用任何自定義的名稱來表示這種狀態。
動畫轉換定時
我們在自己的應用中,通過定義動畫轉換的定時,來顯示從一個狀態過度到另一個狀態。Angular為我們提供瞭如下三種與時間相關的屬性:
1.持續時間(Duration)
此屬性表示我們的動畫從開始(初始狀態)到完成(最終狀態)所需的時間。我們可以用以下三種方式來定義動畫的持續時間:
- 使用一個整數值,來表示以毫秒為單位的時間,例如:500
- 使用一個字串值,來表示以毫秒為單位的時間,例如:’500ms’
- 使用一個字串值,來表示以秒為單位的時間。例如:’0.5’
2.延遲(Delay)
此屬性代表動畫從觸發到和實際轉換開始之間的時間間隔。該屬性遵循與上述持續時間相同的語法規則。要定義延遲,我們需要在持續時間值的後面,以字串的形式新增延遲的數值,即:'Duration Delay'。例如' 0.3s 500ms’,表示轉換將等待500毫秒,然後執行0.3秒。
3.滑動(Easing)
此屬性表示動畫在其執行過程中是如何被加速或減速的。我們可以在持續時間和延遲的字串後面,新增第三個變數。當然,如果延遲數值不存在的話,那麼Easing將成為第二個數值。這同樣也是一個可選屬性。例如:
- '0.3s 500ms ease-in'。這意味著轉換將等待500毫秒,然後執行0.3秒(300毫秒),實現滑入的效果。
- '300ms ease-out'。這意味著轉換將執行300毫秒(0.3秒),實現滑出的效果。
建立Angular 6應用
請在您的計算機上開啟命令提示行,並執行以下命令集:
- mkdir ngAnimationDemo
- cd ngAnimationDemo
- ng new ngAnimation
這些命令將建立一個名為ngAnimationDemo的目錄,然後在該目錄內建立一個名為ngAnimation的Angular應用。
請使用Visual Studio Code開啟ngAnimation應用。接著我們將建立自己的元件。
請依次進入View >> Integrated Terminal,這將開啟Visual Studio Code的終端視窗。
請執行以下命令,以建立相應的元件:
ng g c animationdemo
它將在/src/app資料夾內建立我們的元件--animationdemo。
為了用到Angular動畫,我們需要在應用中匯入特定的動畫模組--BrowserAnimationsModule。請開啟app.module.ts檔案,並新增如下的匯入定義:
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; // other import definitions @NgModule({ imports: [BrowserAnimationsModule // other imports]})
理解Angular動畫的語法
下面,我們在元件的元資料中編寫動畫程式碼。其語法如下:
@Component({ // other component properties. animations: [ trigger('triggerName'), [ state('stateName', style()) transition('stateChangeExpression', [Animation Steps]) ] ] })
此處,我們用到了名為animations的屬性。該屬性的輸入是一個陣列,此陣列包含一個或多個“觸發器”。同時,每個觸發器都帶有唯一的名稱、和用來定義動畫的狀態和各種轉換的具體實現。
另外,每一個狀態函式都會通過“stateName”來唯一地識別其狀態、並用樣式函式來顯示在該狀態下的元素樣式。
當然,每個轉換函式也都通過stateChangeExpression,來定義元素狀態轉換、並定義動畫的不同步驟所對應的陣列,從而能夠顯示出轉換是如何發生的。在此,我們就可以用逗號分隔的數值,來將多個觸發器函式包括到動畫的屬性之中。
由於這些功能(觸發、狀態、和轉換)都被定義在@angular/animations模組之中,因此,我們需要在自己的元件匯入該模組。
為了將動畫應用到某個元素之上,我們需要在元素的定義中包含觸發器的名稱,即:在元素的標籤裡使用@後面加觸發器名稱的格式。對應的程式碼示例如下:
<div @changeSize></div>
這是將觸發器changeSize應用到元素的上。
下面,讓我們建立更多的動畫,以更好地理解Angular的動畫概念吧。
更改大小的動畫
我們將建立一個動畫,來實現一鍵改變的大小。
請開啟animationdemo.component.ts檔案,將如下程式碼新增到匯入定義之中。
import { trigger, state, style, animate, transition } from '@angular/animations';
在元件的元資料中新增如下的動畫屬性定義。
animations: [ trigger('changeDivSize', [ state('initial', style({ backgroundColor: 'green', width: '100px', height: '100px' })), state('final', style({ backgroundColor: 'red', width: '200px', height: '200px' })), transition('initial=>final', animate('1500ms')), transition('final=>initial', animate('1000ms')) ]), ]
在此,我們定義了一個觸發器—changeDivSize,而且該觸發器裡的兩個功能函式。該元素在“初始”狀態時呈現綠色,並隨著寬度和高度的增加,在“最終”狀態時呈現為紅色。
同時,我們定義了狀態的轉換規則:從“初始”態到“最終”態將持續1500毫秒,而從“最終”態返回“初始”態則為1000毫秒。
為了改變元素的狀態,我們在元件的類定義中定義了一個功能函式。我們將如下程式碼包含在AnimationdemoComponent類中:
currentState = 'initial'; changeState() { this.currentState = this.currentState === 'initial' ? 'final' : 'initial'; }
此處,我們定義了一個changeState方法,來切換元素的狀態。
請開啟animationdemo.component.html檔案,並新增以下程式碼:
<h3>Change the div size</h3> <button (click)="changeState()">Change Size</button> <br /> <div [@changeDivSize]=currentState></div> <br />
我們定義了一個按鈕,來呼叫點選時的changeState函式。由於我們前面已經定義了元素,並對它應用了changeDivSize動畫觸發器,因此當按鈕被點選時,它會更新元素的狀態,其大小則會伴隨著轉換效果而發生變化。
在執行該應用之前,我們也需要將引用包含在app.component.html檔案內的Animationdemo元件中。
開啟app.component.html檔案,您會發現該檔案中已包含了一些預設的HTML程式碼。請刪除所有的程式碼,並按照下圖所示放置元件的選擇器:
<app-animationdemo></app-animationdemo>
請在Visual Studio Code的終端窗口裡執行ng serve命令,以執行該程式碼。執行完畢後,它會提示您在瀏覽器中開啟http://localhost:4200。隨後,您就會在瀏覽器中看到如下點選按鈕的動畫效果。
氣球動畫效果
在前面的動畫示例中,轉化僅發生在兩個方向。而在本節中,我們將學習如何改變所有方向上的尺寸。這與氣球的充、放氣比較類似,故稱為氣球動畫效果。
請在動畫屬性中新增如下的觸發器定義。
trigger('balloonEffect', [ state('initial', style({ backgroundColor: 'green', transform: 'scale(1)' })), state('final', style({ backgroundColor: 'red', transform: 'scale(1.5)' })), transition('final=>initial', animate('1000ms')), transition('initial=>final', animate('1500ms')) ]),
在此,我們使用轉換屬性來更改所有方向的尺寸大小。當該元素的狀態發生變化時轉換隨即發生。
請在app.component.html檔案中新增如下HTML程式碼。
<h3>Balloon Effect</h3> <div (click)="changeState()" style="width:100px;height:100px; border-radius: 100%; margin: 3rem; background-color: green" [@balloonEffect]=currentState> </div>
在此,我們定義了一個div,並通過CSS樣式來定義成一個圓圈。我們將通過點選div去呼叫changeState,從而實現元素狀態的切換。
下圖便是該動畫在瀏覽器中的執行效果:
淡入和淡出動畫
有時候,我們需要在顯示動畫的同時,對DOM新增或移除元素。下面,我們來看看如何通過對一個列表新增或刪除條目,以實現淡入和淡出的動畫效果。
請將如下程式碼插入AnimationdemoComponent類的定義之中。
listItem = []; list_order: number = 1; addItem() { var listitem = "ListItem " + this.list_order; this.list_order++; this.listItem.push(listitem); } removeItem() { this.listItem.length -= 1; }
請在該動畫的屬性中新增如下的觸發器定義。
trigger('fadeInOut', [ state('void', style({ opacity: 0 })), transition('void <=> *', animate(1000)), ]),
在此,我們定義了觸發器fadeInOut。當該元素被新增到DOM時,它的狀態就從void轉換為wildcard,我們表示為void => *。而當該元素從DOM刪除時,它的狀態就從wildcard轉換為void,我們表示為* => void。
我們給動畫的不同方向使用相同的動畫定時,其語法為<=>。正如該觸發器所定義的,動畫從void => * 和 * => void,都需要1000毫秒才能完成。
請在app.component.html檔案中新增如下HTML程式碼。
<h3>Fade-In and Fade-Out animation</h3>
<button (click)="addItem()">Add List</button>
<button (click)="removeItem()">Remove List</button>
<div style="width:200px; margin-left: 20px">
<ul>
<li *ngFor="let list of listItem" [@fadeInOut]>
{{list}}
</li>
</ul>
</div>
在此,我們定義了兩個按鈕來新增和刪除條目。我們將fadeInOut觸發器與元素繫結,以實現在對DOM進行新增、刪除時,能夠出現淡入和淡出的效果。
下圖便是該動畫在瀏覽器中的執行效果:
進入和離開動畫
此外,我們還能夠通過對DOM的新增,實現某個元素從左邊進入螢幕;而在刪除時,能讓該元素從右邊離開螢幕。
由於從void => * 和 * => void 的轉換十分常見。因此,Angular為這些動畫提供了別名機制:
- 對於 void => * ,我們可以用':enter'
- 對於 * => void ,我們可以用':leave'
這兩個別名使得此類轉換更具可讀性,也更容易被理解。
請在動畫的屬性中新增如下觸發器的定義。
trigger('EnterLeave', [ state('flyIn', style({ transform: 'translateX(0)' })), transition(':enter', [ style({ transform: 'translateX(-100%)' }), animate('0.5s 300ms ease-in') ]), transition(':leave', [ animate('0.3s ease-out', style({ transform: 'translateX(100%)' })) ]) ])
在此,我們定義了觸發器EnterLeave。那麼':enter'的轉換需要等待300毫秒,然後執行0.5秒,並實現滑入的效果;而':leave'的轉換隻執行0.3秒,實現滑出的效果。
請在app.component.html檔案中新增如下HTML程式碼。
<h3>Enter and Leave animation</h3> <button (click)="addItem()">Add List</button> <button (click)="removeItem()">Remove List</button> <div style="width:200px; margin-left: 20px"> <ul> <li *ngFor="let list of listItem" [@EnterLeave]="'flyIn'"> {{list}} </li> </ul> </div>
在此,我們定義了兩個按鈕來對列表新增和刪除條目。我們將EnterLeave觸發器與元素繫結,以實現在對DOM進行新增、刪除時,出現滑入和滑出的效果。
下圖便是該動畫在瀏覽器中的執行效果:
結論
綜上所述,我們針對Angular 6的動畫效果,探討了動畫狀態和轉換的概念,也通過一個應用示例展示了實際的動畫程式碼與效果。
原文標題:Understanding Angular 6 Animations,作者:Ankit Sharma
【51CTO譯稿,合作站點轉載請註明原文譯者和出處為51CTO.com】
【責任編輯:龐桂玉 TEL:(010)68476606】