跳至主要內容
版本:v8

動畫

概觀

Ionic 動畫是一個工具,使開發人員能夠以與平台無關的方式建立複雜的動畫,而無需特定的框架或 Ionic 應用程式。

建立高效的動畫可能具有挑戰性,因為開發人員會受到裝置可用程式庫和硬體資源的限制。此外,許多動畫程式庫使用 JavaScript 驅動的方法,這可能會降低動畫的可擴展性並耗用 CPU 時間。

另一方面,Ionic 動畫使用 Web Animations API,它將所有動畫的計算和執行卸載到瀏覽器。這種方法允許瀏覽器最佳化動畫並確保其順利執行。在不支援 Web Animations 的情況下,Ionic 動畫將回退到 CSS 動畫,兩者在效能上的差異應該可以忽略不計。

安裝

使用 Ionic Core 和 JavaScript 的開發人員應安裝最新版本的 @ionic/core

import { createAnimation } from 'https://cdn.jsdelivr.net/npm/@ionic/core@latest/dist/esm/index.mjs';

...

const animation = createAnimation()
.addElement(myElementRef)
.duration(1000)
.fromTo('opacity', '1', '0.5');
}

基本動畫

在下面的範例中,已建立一個動畫,該動畫會變更 ion-card 元素的不透明度,並沿著 X 軸將其從左移到右。此動畫將無限次執行,並且動畫的每次迭代將持續 1500 毫秒。

預設情況下,所有 Ionic 動畫都會暫停,直到呼叫 play 方法為止。

關鍵影格動畫

Ionic 動畫允許您使用關鍵影格來控制動畫的中間步驟。您可以在這裡使用任何有效的 CSS 屬性,甚至可以使用 CSS 變數作為值。

在撰寫關鍵影格時,連字符 CSS 屬性應使用駝峰式大小寫撰寫。例如,border-radius 應寫為 borderRadius。這也適用於 fromTo()from()to() 方法。

在上面的範例中,卡片元素將從其初始寬度轉換為由 --width 變數定義的寬度,然後轉換為最終寬度。

每個關鍵影格物件都包含一個 offset 屬性。offset 是介於 0 和 1 之間的值,用於定義關鍵影格步驟。偏移值必須按遞增順序排列,並且不能重複。

群組動畫

可以同時對多個元素進行動畫處理,並透過單一父動畫物件進行控制。子動畫會繼承持續時間、easing 和迭代次數等屬性,除非另有指定。在所有子動畫完成之前,不會呼叫父動畫的 onFinish 回呼。

此範例顯示 3 個由單一父動畫控制的子動畫。動畫 cardAcardB 會繼承父動畫的 2000 毫秒持續時間,但動畫 cardC 的持續時間為 5000 毫秒,因為它已明確設定。

之前和之後掛勾

Ionic 動畫提供掛勾,可讓您在動畫執行之前和動畫完成之後變更元素。這些掛勾可用於執行 DOM 讀寫,以及新增或移除類別和內嵌樣式。

此範例會設定一個內嵌篩選器,在動畫開始之前將卡片的背景顏色反轉 75%。動畫完成後,元素的陰影會設定為 rgba(255, 0, 50, 0.4) 0px 4px 16px 6px,也就是紅色光暈,並清除內嵌篩選器。必須停止動畫才能移除陰影並再次使用篩選器播放它。

如需掛勾的完整清單,請參閱方法

鏈式動畫

動畫可以鏈式執行,以便一個接一個地執行。當動畫完成時,play 方法會傳回一個 Promise。

手勢動畫

Ionic 動畫透過與 Ionic 手勢 無縫整合,讓開發人員能夠建立強大的基於手勢的動畫。

在下面的範例中,我們正在建立一個軌跡,我們可以沿著該軌跡拖曳卡片元素。我們的 animation 物件將負責向左或向右移動卡片元素,而我們的 gesture 物件將指示 animation 物件要向哪個方向移動。

基於偏好設定的動畫

開發人員還可以透過使用 CSS 變數來調整其動畫以符合使用者偏好,例如 prefers-reduced-motionprefers-color-scheme

首次建立動畫時,此方法適用於所有支援的瀏覽器。當 CSS 變數變更時,大多數瀏覽器也都能夠動態更新關鍵影格動畫。

Safari 目前不支援動態更新關鍵影格動畫。對於需要在 Safari 中進行這種支援的開發人員,他們可以使用 MediaQueryList.addListener()

覆寫 Ionic 元件動畫

某些 Ionic 元件允許開發人員提供自訂動畫。所有動畫都會以元件的屬性形式提供,或透過全域設定設定。

強制回應

效能考量

CSS 和 Web 動畫通常在合成器執行緒上處理。這與執行配置、繪圖、樣式和 JavaScript 的主要執行緒不同。建議您偏好使用可在合成器執行緒上處理的屬性,以獲得最佳動畫效能。

動畫屬性,例如 heightwidth,會導致額外的佈局和繪製,這可能會導致卡頓並降低動畫效能。另一方面,動畫屬性,例如 transformopacity,瀏覽器可以高度優化,通常不會導致太多卡頓。

有關哪些 CSS 屬性會導致佈局或繪製的資訊,請參閱 CSS Triggers

除錯

關於在 Chrome 中除錯動畫,有一篇很棒的部落格文章,介紹如何使用 Chrome 開發人員工具檢查動畫:https://developers.google.com/web/tools/chrome-devtools/inspect-styles/animations

也建議為您的動畫指定唯一的識別符號。這些識別符號將會顯示在 Chrome 的「動畫」檢查器中,應該能讓除錯更容易

/**
* The animation for the .square element should
* show "my-animation-identifier" in Chrome DevTools.
*/
const animation = createAnimation('my-animation-identifier')
.addElement(document.querySelector('.square'))
.duration(1000)
.fromTo('opacity', '1', '0');

API

本節提供 Animation 類別中所有可用方法和屬性的清單。

介面

AnimationDirection

type AnimationDirection = 'normal' | 'reverse' | 'alternate' | 'alternate-reverse';

AnimationFill

type AnimationFill = 'auto' | 'none' | 'forwards' | 'backwards' | 'both';

AnimationBuilder

type AnimationBuilder = (baseEl: any, opts?: any) => Animation;
注意

opts 是自訂動畫特有的其他選項。例如,工作表模式進入動畫包含目前斷點的資訊。

AnimationCallbackOptions

interface AnimationCallbackOptions {
/**
* If true, the associated callback will only be fired once.
*/
oneTimeCallback: boolean;
}

AnimationPlayOptions

interface AnimationPlayOptions {
/**
* If true, the animation will play synchronously.
* This is the equivalent of running the animation
* with a duration of 0ms.
*/
sync: boolean;
}

屬性

名稱描述
childAnimations: Animation[]給定父動畫的所有子動畫。
elements: HTMLElement[]附加到動畫的所有元素。
parentAnimation?: Animation給定動畫物件的父動畫。

方法

名稱描述
addAnimation(animationToAdd: Animation | Animation[]): Animation將一個或多個動畫分組在一起,以由父動畫控制。
addElement(el: Element | Element[] | Node | Node[] | NodeList): Animation將一個或多個元素新增到動畫中。
afterAddClass(className: string | string[]): Animation新增一個類別或類別陣列,使其在動畫結束後新增到動畫中的所有元素。
afterAddRead(readFn: (): void): Animation新增一個函式,執行 DOM 讀取,以在動畫結束後執行。
afterAddWrite(writeFn: (): void): Animation新增一個函式,執行 DOM 寫入,以在動畫結束後執行。
afterClearStyles(propertyNames: string[]): Animation新增一個屬性名稱陣列,使其在動畫結束後從動畫中所有元素的內嵌樣式中清除。
afterRemoveClass(className: string | string[]): Animation新增一個類別或類別陣列,使其在動畫結束後從動畫中的所有元素中移除。
afterStyles(styles: { [property: string]: any }): Animation新增一個樣式物件,使其在動畫結束後套用至動畫中的所有元素。
beforeAddClass(className: string | string[]): Animation新增一個類別或類別陣列,使其在動畫開始前新增到動畫中的所有元素。
beforeAddRead(readFn: (): void): Animation新增一個函式,執行 DOM 讀取,以在動畫開始前執行。
beforeAddWrite(writeFn: (): void): Animation新增一個函式,執行 DOM 寫入,以在動畫開始前執行。
beforeClearStyles(propertyNames: string[]): Animation新增一個屬性名稱陣列,使其在動畫開始前從動畫中所有元素的內嵌樣式中清除。
beforeRemoveClass(className: string | string[]): Animation新增一個類別或類別陣列,使其在動畫開始前從動畫中的所有元素中移除。
beforeStyles(styles: { [property: string]: any }): Animation新增一個樣式物件,使其在動畫開始前套用至動畫中的所有元素。
direction(direction?: AnimationDirection): Animation設定動畫應該播放的方向。
delay(delay?: number): Animation設定動畫開始的延遲時間(毫秒)。
destroy(clearStyleSheets?: boolean): Animation銷毀動畫並清除所有元素、子動畫和關鍵影格。
duration(duration?: number): Animation設定動畫的持續時間(毫秒)。
easing(easing?: string): Animation設定動畫的緩和效果(毫秒)。有關接受的緩和效果值清單,請參閱 緩和效果
from(property: string, value: any): Animation設定動畫的起始樣式。
fromTo(property: string, fromValue: any, toValue: any): Animation設定動畫的起始和結束樣式。
fill(fill?: AnimationFill): Animation設定動畫在其元素上套用樣式的方式,在動畫執行之前和之後。
iterations(iterations: number): Animation設定在停止之前動畫週期應播放的次數。
keyframes(keyframes: any[]): Animation設定動畫的關鍵影格。
onFinish(callback: (didComplete: boolean, animation: Animation): void, opts?: AnimationCallbackOptions): Animation新增一個回呼函式,使其在動畫結束時執行。
pause(): Animation暫停動畫。
play(opts?: AnimationPlayOptions): Promise<void>播放動畫。
progressEnd(playTo?: 0 | 1, step: number, dur?: number): Animation停止搜尋動畫。
progressStart(forceLinearEasing?: boolean, step?: number): Animation開始搜尋動畫。
progressStep(step: number): Animation搜尋動畫。
stop(): Animation停止動畫,並將所有元素重設為其初始狀態。
to(property: string, value: any): Animation設定動畫的結束樣式。