填寫這份《一分鐘調查》,幫我們(開發組)做得更好!去填寫Home

Angular 動畫簡介

Introduction to Angular animations

動畫用於提供運動的幻覺:HTML 元素隨著時間改變樣式。精心設計的動畫可以讓你的應用更有趣,更易用,但它們不僅僅是裝飾性的。動畫可以通過幾種方式改善你的應用和使用者體驗:

Animation provides the illusion of motion: HTML elements change styling over time. Well-designed animations can make your application more fun and easier to use, but they aren't just cosmetic. Animations can improve your app and user experience in a number of ways:

  • 沒有動畫,Web 頁面的轉場就會顯得突兀、不協調。

    Without animations, web page transitions can seem abrupt and jarring.

  • 運動能極大地提升使用者體驗,因此動畫可以讓使用者察覺到應用對他們的操作做出了響應。

    Motion greatly enhances the user experience, so animations give users a chance to detect the application's response to their actions.

  • 良好的動畫可以直觀的把使用者的注意力吸引到要留意的地方。

    Good animations intuitively call the user's attention to where it is needed.

典型的動畫會涉及多種隨時間變化的轉換。HTML 元素可以移動、變換顏色、增加或縮小、隱藏或從頁面中滑出。 這些變化可以同時發生或順序發生。你可以控制每次轉換的持續時間。

Typically, animations involve multiple style transformations over time. An HTML element can move, change color, grow or shrink, fade, or slide off the page. These changes can occur simultaneously or sequentially. You can control the timing of each transformation.

Angular 的動畫系統是基於 CSS 功能建構的,這意味著你可以 "動" 瀏覽器認為可動的任何屬性。包括位置、大小、變形、顏色、邊框等。W3C 在它的 CSS Transitions(轉場) 頁中維護了一個可動屬性的列表。

Angular's animation system is built on CSS functionality, which means you can animate any property that the browser considers animatable. This includes positions, sizes, transforms, colors, borders, and more. The W3C maintains a list of animatable properties on its CSS Transitions page.

關於本指南

About this guide

本指南覆蓋了基本的 Angular 動畫特性,讓你能開始為你的專案新增 Angular 動畫。

This guide covers the basic Angular animation features to get you started on adding Angular animations to your project.

本指南中描述的特性,以及相關的 Angular 動畫章節中描述的更多高階特性,都在一個範例現場演練 / 下載範例中進行了示範。

The features described in this guide — and the more advanced features described in the related Angular animations guides — are demonstrated in an example app available as a現場演練 / 下載範例.

前提條件

Prerequisites

本指南假設你已經能熟練建構基本的 Angular 應用,也就是下列章節中所講的那些:

The guide assumes that you're familiar with building basic Angular apps, as described in the following sections:

快速上手

Getting started

Angular 主要的動畫模組是 @angular/animations@angular/platform-browser。當你使用 CLI 建立新專案時,這些依賴會自動新增到你的專案中。

The main Angular modules for animations are @angular/animations and @angular/platform-browser. When you create a new project using the CLI, these dependencies are automatically added to your project.

為了把 Angular 動畫新增到你的專案中,把這些與動畫相關的模組和標準的 Angular 功能一起匯入進來。

To get started with adding Angular animations to your project, import the animation-specific modules along with standard Angular functionality.

步驟一:啟用動畫模組

Step 1: Enabling the animations module

匯入 BrowserAnimationsModule,它能把動畫能力引入 Angular 應用的根模組中。

Import BrowserAnimationsModule, which introduces the animation capabilities into your Angular root application module.

src/app/app.module.ts
      
      import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

@NgModule({
  imports: [
    BrowserModule,
    BrowserAnimationsModule
  ],
  declarations: [ ],
  bootstrap: [ ]
})
export class AppModule { }
    

注意:當你使用 CLI 建立應用時,應用的根模組 app.module.ts 位於 src/app 目錄下。

Note: When you use the CLI to create your app, the root application module app.module.ts is placed in the src/app folder.

步驟二:把動畫功能匯入元件檔案中

Step 2: Importing animation functions into component files

如果你準備在元件檔案中使用特定的動畫函式,請從 @angular/animations 中匯入這些函式。

If you plan to use specific animation functions in component files, import those functions from @angular/animations.

src/app/app.component.ts
      
      import { Component, HostBinding } from '@angular/core';
import {
  trigger,
  state,
  style,
  animate,
  transition,
  // ...
} from '@angular/animations';
    

注意:參閱本章末尾的可用動畫函式彙總表

Note: See a summary of available animation functions at the end of this guide.

步驟三:新增動畫的元資料屬性

Step 3: Adding the animation metadata property

在元件的 @Component() 裝飾器中,新增一個名叫 animations: 的元資料屬性。 你可以把用來定義動畫的觸發器放進 animations 元資料屬性中。

In the component file, add a metadata property called animations: within the @Component() decorator. You put the trigger that defines an animation within the animations metadata property.

src/app/app.component.ts
      
      @Component({
  selector: 'app-root',
  templateUrl: 'app.component.html',
  styleUrls: ['app.component.css'],
  animations: [
    // animation triggers go here
  ]
})
    

簡單轉場動畫

Animating a simple transition

我們來做一個簡單的轉場動作,它把單個 HTML 元素從一個狀態變成另一個狀態。 比如,你可以指定按鈕根據使用者的最後一個動作顯示成OpenClosed狀態。當按鈕處於 open 狀態時,它是可見的,並且是黃色的。當它處於 closed 狀態時,它是透明的,並且是綠色的。

Let's animate a simple transition that changes a single HTML element from one state to another. For example, you can specify that a button displays either Open or Closed based on the user's last action. When the button is in the open state, it's visible and yellow. When it's in the closed state, it's transparent and green.

在 HTML 中,這些屬性都使用普通的 CSS 樣式,比如顏色(color)和透明度(opacity)。在 Angular 中,使用 style() 函式來指定一組用作動畫的 CSS 樣式。 你可以為動畫狀態指定一組樣式,並為該狀態指定一個名字,比如 openclosed

In HTML, these attributes are set using ordinary CSS styles such as color and opacity. In Angular, use the style() function to specify a set of CSS styles for use with animations. You can collect a set of styles in an animation state, and give the state a name, such as open or closed.

動畫狀態和樣式

Animation state and styles

使用 Angular 的 state() 函式來定義不同的狀態,供每次轉場結束時呼叫。該函式接受兩個引數:一個唯一的名字,比如 openclosed 和一個 style() 函式。

Use Angular's state() function to define different states to call at the end of each transition. This function takes two arguments: a unique name like open or closed and a style() function.

使用 style() 函式來定義一組與指定的狀態名相關的樣式。注意,樣式的屬性必須是小駝峰 格式的。

Use the style() function to define a set of styles to associate with a given state name. Note that the style attributes must be in camelCase.

我們來看看 Angular 的 state() 函式如何與 style() 函式聯用,來設定 CSS 樣式的屬性。 在下面的程式碼片段中,該狀態的多個樣式屬性都是同時設定的。在 open 狀態中,該按鈕的高度是 200 畫素,透明度是 1,背景色是黃色。

Let's see how Angular's state() function works with the style⁣­(⁠) function to set CSS style attributes. In this code snippet, multiple style attributes are set at the same time for the state. In the open state, the button has a height of 200 pixels, an opacity of 1, and a background color of yellow.

src/app/open-close.component.ts
      
      // ...
state('open', style({
  height: '200px',
  opacity: 1,
  backgroundColor: 'yellow'
})),
    

closed 狀態中,按鈕的高度是 100 畫素,透明度是 0.5,背景色是綠色。

In the closed state, shown below, the button has a height of 100 pixels, an opacity of 0.5, and a background color of green.

src/app/open-close.component.ts
      
      state('closed', style({
  height: '100px',
  opacity: 0.5,
  backgroundColor: 'green'
})),
    

轉場與時序

Transitions and timing

在 Angular 中,你可以設定多個樣式而不必用動畫。不過,如果沒有進一步細化,按鈕的轉換會立即完成 —— 沒有漸隱、沒有收縮,也沒有其它的視覺化效果來指出正在發生變化。

In Angular, you can set multiple styles without any animation. However, without further refinement, the button instantly transforms with no fade, no shrinkage, or other visible indicator that a change is occurring.

要讓這些變化不那麼突兀,我們需要定義一個動畫轉場來要求這些狀態之間的變化在一段時間內發生。transition() 接受兩個引數:第一個引數接受一個表示式,它定義兩個轉場狀態之間的方向;第二個引數接受一個或一系列 animate() 函式。

To make the change less abrupt, we need to define an animation transition to specify the changes that occur between one state and another over a period of time. The transition() function accepts two arguments: the first argument accepts an expression that defines the direction between two transition states, and the second argument accepts one or a series of animate() steps.

使用 animate() 函式來定義長度、延遲和緩動效果,並指定一個樣式函式,以定義轉場過程中的樣式。 你還可以使用 animate() 函式來為多步動畫定義 keyframes() 函式。這些定義放在 animate() 函式的第二個引數中。

Use the animate() function to define the length, delay, and easing of a transition, and to designate the style function for defining styles while transitions are taking place. You can also use the animate() function to define the keyframes() function for multi-step animations. These definitions are placed in the second argument of the animate() function.

動畫元資料:持續時間、延遲和緩動效果

Animation metadata: duration, delay, and easing

animate() 函式(作為轉場函式的第二個引數)可以接受 timingsstyles 引數。

The animate() function (second argument of the transition function) accepts the timings and styles input parameters.

timings 引數接受一個由三部分組成的字串。

The timings parameter takes a string defined in three parts.

animate ('duration delay easing')

第一部分 duration(持續時間)是必須的。這個持續時間可以表示成一個不帶引號的純數字(表示毫秒),或一個帶引號的有單位的時間(表示秒數)。比如,0.1 秒的持續時間有如下表示方式:

The first part, duration, is required. The duration can be expressed in milliseconds as a simple number without quotes, or in seconds with quotes and a time specifier. For example, a duration of a tenth of a second can be expressed as follows:

  • 作為純數字,毫秒為單位:100

    As a plain number, in milliseconds: 100

  • 作為字串,毫秒為單位:'100ms'

    In a string, as milliseconds: '100ms'

  • 作為字串,秒為單位:'0.1s'

    In a string, as seconds: '0.1s'

第二個引數 delay 的語法和 duration 一樣。比如:

The second argument, delay, has the same syntax as duration. For example:

  • 等待 100 毫秒,然後執行 200 毫秒錶示為:'0.2s 100ms'

    Wait for 100ms and then run for 200ms: '0.2s 100ms'

第三個引數 easing 控制動畫在執行期間如何進行加速和減速。比如 ease-in 表示動畫開始時很慢,然後逐漸加速。

The third argument, easing, controls how the animation accelerates and decelerates during its runtime. For example, ease-in causes the animation to begin slowly, and to pick up speed as it progresses.

  • 等待 100 毫秒,執行 200 毫秒。按照減速曲線運動,快速啟動並逐漸減速,直到靜止:'0.2s 100ms ease-out'

    Wait for 100ms, run for 200ms. Use a deceleration curve to start out fast and slowly decelerate to a resting point: '0.2s 100ms ease-out'

  • 執行 200 毫秒,不等待。按照標準曲線運動,開始很慢,中間加速,最後逐漸減速:'0.2s ease-in-out'

    Run for 200ms, with no delay. Use a standard curve to start slow, accelerate in the middle, and then decelerate slowly at the end: '0.2s ease-in-out'

  • 立即開始,執行 200 毫秒。按照加速曲線運動,開始很慢,最後達到全速:'0.2s ease-in'

    Start immediately, run for 200ms. Use an acceleration curve to start slow and end at full velocity: '0.2s ease-in'

注意:要了解緩動曲線的更多資訊,請參閱 Angular Material Design 網站下的自然緩動曲線主題。

Note: See the Material Design website's topic on Natural easing curves for general information on easing curves.

下面的例子提供了一個從 openclosed 的持續一秒的狀態轉場。

This example provides a state transition from open to closed with a one second transition between states.

src/app/open-close.component.ts
      
      transition('open => closed', [
  animate('1s')
]),
    

在上面的程式碼片段中,=> 運算子表示單向轉場,而 <=> 表示雙向轉場。在轉場過程中,animate() 指定了轉場需要花費的時間。在這裡,從 openclosed 狀態的轉換要花費 1 秒中,表示成 1s

In the code snippet above, the => operator indicates unidirectional transitions, and <=> is bidirectional. Within the transition, animate() specifies how long the transition takes. In this case, the state change from open to closed takes one second, expressed here as 1s.

下面的例子添加了一個從 closedopen 的狀態轉場,轉場動畫持續 0.5 秒。

This example adds a state transition from the closed state to the open state with a 0.5 second transition animation arc.

src/app/open-close.component.ts
      
      transition('closed => open', [
  animate('0.5s')
]),
    

注意:statetransition 函式中使用樣式時有一些需要注意的地方。

Note: Some additional notes on using styles within state and transition functions.

  • 請用 state() 來定義那些每個轉場結束時的樣式,這些樣式在動畫完成後仍會保留。

    Use state() to define styles that are applied at the end of each transition, they persist after the animation has completed.

  • 使用 transition() 來定義那些中間樣式,以便在動畫過程中產生運動的錯覺。

    Use transition() to define intermediate styles, which create the illusion of motion during the animation.

  • 當禁用了動畫時,也會忽略 transition() 中的樣式,但 state() 中的樣式不會。

    When animations are disabled, transition() styles can be skipped, but state() styles can't.

  • 你可以在同一個 transition() 引數中包含多個狀態對:
    transition( 'on => off, off => void' )

    You can include multiple state pairs within the same transition() argument:
    transition( 'on => off, off => void' ).

觸發動畫

Triggering the animation

動畫需要觸發器,以便知道該在何時開始。trigger() 函式會把一些狀態和轉場組合在一起,並為這個動畫命名,這樣你就可以在 HTML 範本中把它附加到想要觸發動畫的元素上了。

An animation requires a trigger, so that it knows when to start. The trigger() function collects the states and transitions, and gives the animation a name, so that you can attach it to the triggering element in the HTML template.

trigger() 函式描述了監聽變化時要使用的觸發器名稱。當這個觸發器名稱所繫結的值發生了變化時,觸發器就會啟動它所定義的操作。這些操作可能是轉場,也可能是其它功能,我們稍後就會看到。

The trigger() function describes the property name to watch for changes. When a change occurs, the trigger initiates the actions included in its definition. These actions can be transitions or other functions, as we'll see later on.

在這個例子中,我們將把該觸發器命名為 openClose,並把它附加到 button 元素上。該觸發器描述了 openclosed 兩個狀態,以及兩個轉場效果的時序。

In this example, we'll name the trigger openClose, and attach it to the button element. The trigger describes the open and closed states, and the timings for the two transitions.

注意:在每個 trigger() 函式呼叫中,元素在任意時刻只能處於其中的一個狀態。但是,元素可以在同一時刻啟用多個觸發器。

Note: Within each trigger() function call, an element can only be in one state at any given time. However, it's possible for multiple triggers to be active at once.

定義動畫,並把它們附加到 HTML 範本中

Defining animations and attaching them to the HTML template

這些控制 HTML 元素如何運動的動畫是在元件的元資料中定義的。請在 @Component() 裝飾器的 animations: 屬性下用程式碼定義你要用的動畫。

Animations are defined in the metadata of the component that controls the HTML element to be animated. Put the code that defines your animations under the animations: property within the @Component() decorator.

src/app/open-close.component.ts
      
      @Component({
  selector: 'app-open-close',
  animations: [
    trigger('openClose', [
      // ...
      state('open', style({
        height: '200px',
        opacity: 1,
        backgroundColor: 'yellow'
      })),
      state('closed', style({
        height: '100px',
        opacity: 0.5,
        backgroundColor: 'green'
      })),
      transition('open => closed', [
        animate('1s')
      ]),
      transition('closed => open', [
        animate('0.5s')
      ]),
    ]),
  ],
  templateUrl: 'open-close.component.html',
  styleUrls: ['open-close.component.css']
})
export class OpenCloseComponent {
  isOpen = true;

  toggle() {
    this.isOpen = !this.isOpen;
  }

}
    

為元件定義好這些動畫觸發器之後,你可以給觸發器名稱加上 @ 字首幷包在方括號裡,來把它附加到元件範本中的元素上。然後,你可以使用 Angular 的標準屬性繫結語法(如下所示),來把這個觸發器繫結到範本表示式上。這裡的 triggerName 就是觸發器的名稱,而 expression 的求值結果是前面定義過的動畫狀態之一。

When you've defined an animation trigger for a component, you can attach it to an element in that component's template by wrapping the trigger name in brackets and preceding it with an @ symbol. Then, you can bind the trigger to a template expression using standard Angular property binding syntax as shown below, where triggerName is the name of the trigger, and expression evaluates to a defined animation state.

      
      <div [@triggerName]="expression">...</div>;
    

當該表示式的值變成了新的狀態時,動畫就會執行或者叫觸發。

The animation is executed or triggered when the expression value changes to a new state.

下列程式碼片段把該觸發器繫結到了 isOpen 屬性的值上。

The following code snippet binds the trigger to the value of the isOpen property.

src/app/open-close.component.html
      
      <div [@openClose]="isOpen ? 'open' : 'closed'" class="open-close-container">
  <p>The box is now {{ isOpen ? 'Open' : 'Closed' }}!</p>
</div>
    

在這個例子中,當 isOpen 表示式求值為一個已定義狀態 openclosed 時,就會通知 openClose 觸發器說狀態變化了。然後,就由 openClose 中的程式碼來處理狀態變更,並啟動狀態變更動畫。

In this example, when the isOpen expression evaluates to a defined state of open or closed, it notifies the trigger openClose of a state change. Then it's up to the openClose code to handle the state change and kick off a state change animation.

對於那些進入或離開頁面的元素(插入到 DOM 中或從中移除),你可以讓動畫變成有條件的。例如,在 HTML 範本中可以和 *ngIf 一起使用動畫觸發器。

For elements entering or leaving a page (inserted or removed from the DOM), you can make the animations conditional. For example, use *ngIf with the animation trigger in the HTML template.

注意:在元件檔案中,要把用來定義動畫的觸發器設定為 @Component() 裝飾器的 animations: 屬性的值。

Note: In the component file, set the trigger that defines the animations as the value of the animations: property in the @Component() decorator.

在 HTML 範本檔案中,使用這個觸發器的名稱來把所定義的這些動畫附加到想要新增動畫的 HTML 元素上。

In the HTML template file, use the trigger name to attach the defined animations to the HTML element to be animated.

程式碼回顧

Code review

下面是轉場動畫範例中討論過的程式碼檔案。

Here are the code files discussed in the transition example.

      
      @Component({
  selector: 'app-open-close',
  animations: [
    trigger('openClose', [
      // ...
      state('open', style({
        height: '200px',
        opacity: 1,
        backgroundColor: 'yellow'
      })),
      state('closed', style({
        height: '100px',
        opacity: 0.5,
        backgroundColor: 'green'
      })),
      transition('open => closed', [
        animate('1s')
      ]),
      transition('closed => open', [
        animate('0.5s')
      ]),
    ]),
  ],
  templateUrl: 'open-close.component.html',
  styleUrls: ['open-close.component.css']
})
export class OpenCloseComponent {
  isOpen = true;

  toggle() {
    this.isOpen = !this.isOpen;
  }

}
    

小節

Summary

你已經學會了如何在兩個狀態之間新增簡單的轉場動畫,只要使用 style()state(),並使用 animate() 來定義時序就可以了。

You learned to add animation to a simple transition between two states, using style() and state() along with animate() for the timing.

你還可以到 "動畫" 組下學習 Angular 動畫的高階特性,不妨先從轉場與觸發器中講述的高階技巧開始。

You can learn about more advanced features in Angular animations under the Animation section, beginning with advanced techniques in transition and triggers.

動畫 API 小節

Animations API summary

@angular/animations 模組提供的這些功能性 API 提供了一種領域特定語言(DSL),用於在 Angular 應用中建立和控制動畫效果。到 API 參考手冊中檢視完整的列表以及這些核心功能、相關資料結構的詳細語法。

The functional API provided by the @angular/animations module provides a domain-specific language (DSL) for creating and controlling animations in Angular applications. See the API reference for a complete listing and syntax details of the core functions and related data structures.

函式名

Function name

用途

What it does

trigger()

開始動畫,並充當所有其它動畫函式的容器。HTML 範本可以繫結到 triggerName。使用第一個引數來宣告唯一的觸發器名稱。要使用陣列語法。

Kicks off the animation and serves as a container for all other animation function calls. HTML template binds to triggerName. Use the first argument to declare a unique trigger name. Uses array syntax.

style()

定義一個或多個要用於動畫中的 CSS 樣式。用於在動畫期間控制 HTML 元素的視覺外觀。要使用物件語法。

Defines one or more CSS styles to use in animations. Controls the visual appearance of HTML elements during animations. Uses object syntax.

state()

建立一組有名字的 CSS 樣式,它會在成功轉換到指定的狀態時應用到元素上。該狀態可以在其它動畫函式中透過名字進行參考。

Creates a named set of CSS styles that should be applied on successful transition to a given state. The state can then be referenced by name within other animation functions.

animate()

指定轉場的時序資訊。delayeasing 是可選值。其中可以包含 style() 呼叫。

Specifies the timing information for a transition. Optional values for delay and easing. Can contain style() calls within.

transition()

定義兩個命名狀態之間的動畫序列。使用陣列語法。

Defines the animation sequence between two named states. Uses array syntax.

keyframes()

允許以特定的時間間隔對樣式進行順序更改。用於 animate() 中。每個 keyframe() 中都可以包含多個 style() 呼叫。使用陣列語法。

Allows a sequential change between styles within a specified time interval. Use within animate(). Can include multiple style() calls within each keyframe(). Uses array syntax.

group()

指定要並行執行的一組動畫步驟(內部動畫)。 該動畫只有當所有內部動畫步驟都完成之後才會繼續。用於 sequence()transition() 中。

Specifies a group of animation steps (inner animations) to be run in parallel. Animation continues only after all inner animation steps have completed. Used within sequence() or transition().

query()

找出當前元素中的一個或多個內部 HTML 元素。

Finds one or more inner HTML elements within the current element.

sequence()

指定一個動畫步驟列表,它們會逐個順序執行。

Specifies a list of animation steps that are run sequentially, one by one.

stagger()

交錯安排多元素動畫的開始時間。

Staggers the starting time for animations for multiple elements.

animation()

產生可在其它地方呼叫的可複用動畫。與 useAnimation() 一起使用。

Produces a reusable animation that can be invoked from elsewhere. Used together with useAnimation().

useAnimation()

啟用一個可複用動畫。和 animation() 一起使用。

Activates a reusable animation. Used with animation().

animateChild()

允許子元件上的動畫和父元件在同一個時間範圍(timeframe)內執行。

Allows animations on child components to be run within the same timeframe as the parent.

關於 Angular 動畫的更多知識

More on Angular animations

你可能還對下列內容感興趣:

You may also be interested in the following:

到這個 Demo 中檢視 2017 年 11 月的 AngularConnect 大會上完整的動畫及其示範

Check out this presentation, shown at the AngularConnect conference in November 2017, and the accompanying source code.