跳到主要内容
版本:v8

动画

概述​

Ionic Animations 是一个工具,使开发者能够以平台无关的方式创建复杂的动画,无需特定框架或 Ionic 应用。

创建高效的动画可能具有挑战性,因为开发者受到可用库和设备硬件资源的限制。此外,许多动画库使用 JavaScript 驱动的方法,这可能会降低动画的可扩展性并消耗 CPU 时间。

另一方面,Ionic Animations 使用 Web Animations API,它将所有动画的计算和运行都移交给浏览器。这种方法允许浏览器优化动画并确保其流畅执行。在不支持 Web Animations 的情况下,Ionic Animations 将回退到 CSS Animations,这在性能上的差异可以忽略不计。

安装​

使用 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 轴从左向右移动的动画。此动画将无限次运行,每次动画迭代持续 1500ms。

默认情况下,所有 Ionic Animations 都处于暂停状态,直到调用 play 方法。

关键帧动画​

Ionic Animations 允许你使用关键帧控制动画的中间步骤。这里可以使用任何有效的 CSS 属性,你甚至可以使用 CSS 变量作为值。

在编写关键帧时,连字符分隔的 CSS 属性应使用驼峰式写法。例如,border-radius 应写为 borderRadius。这也适用于 fromTo()、from() 和 to() 方法。

在上面的示例中,卡片元素将从其初始宽度过渡到由 --width 变量定义的宽度,然后过渡到最终宽度。

每个关键帧对象包含一个 offset 属性。offset 是一个介于 0 和 1 之间的值,用于定义关键帧步骤。偏移值必须按升序排列且不能重复。

分组动画​

多个元素可以同时进行动画,并通过单个父级动画对象进行控制。除非另有指定,子动画会继承持续时间、缓动和迭代次数等属性。父级动画的 onFinish 回调在所有子动画完成之前不会被调用。

此示例展示了由单个父级动画控制的 3 个子动画。动画 cardA 和 cardB 继承了父级动画的 2000ms 持续时间,但动画 cardC 由于显式设置而具有 5000ms 的持续时间。

Before 和 After 钩子​

Ionic Animations 提供了钩子,让你可以在动画运行之前和动画完成之后更改元素。这些钩子可用于执行 DOM 读取和写入,以及添加或删除类和内联样式。

此示例设置了一个内联滤镜,在动画开始前将卡片的背景颜色反转 75%。动画完成后,元素上的 box shadow 被设置为 rgba(255, 0, 50, 0.4) 0px 4px 16px 6px(红色发光),并且内联滤镜被清除。必须停止动画才能移除 box shadow 并再次使用滤镜播放动画。

参见方法了解完整的钩子列表。

链式动画​

动画可以链接起来,一个接一个地运行。play 方法返回一个 Promise,在动画完成时解析。

手势动画​

Ionic Animations 使开发者能够通过与 Ionic Gestures 无缝集成来创建强大的基于手势的动画。

在以下示例中,我们创建了一个轨道,可以沿其拖动卡片元素。我们的 animation 对象将负责向左或向右移动卡片元素,而我们的 gesture 对象将指示 animation 对象向哪个方向移动。

基于偏好的动画​

开发者还可以使用 CSS 变量根据用户偏好(如 prefers-reduced-motion 和 prefers-color-scheme)定制动画。

在首次创建动画时,此方法适用于所有支持的浏览器。大多数浏览器还能够随着 CSS 变量的更改动态更新关键帧动画。

Safari 目前不支持动态更新关键帧动画。对于需要在 Safari 中获得此类支持的开发者,可以使用 MediaQueryList.addListener()。

覆盖 Ionic 组件动画​

某些 Ionic 组件允许开发者提供自定义动画。所有动画都作为组件上的属性提供,或通过全局配置设置。

Modals​

性能考虑​

CSS 和 Web 动画通常在合成线程上处理。这与主线程(布局、绘制、样式和 JavaScript 执行发生的地方)不同。建议优先使用可以在合成线程上处理的属性,以获得最佳的动画性能。

对诸如 height 和 width 等属性进行动画会导致额外的布局和绘制,这可能导致卡顿并降低动画性能。另一方面,对诸如 transform 和 opacity 等属性进行动画可以由浏览器高度优化,通常不会引起太多卡顿。

关于哪些 CSS 属性会导致布局或绘制发生,请参见 CSS Triggers。

调试​

有关在 Chrome 中调试动画的信息,有一篇很好的博客文章介绍了如何使用 Chrome DevTools 检查动画:https://developers.google.com/web/tools/chrome-devtools/inspect-styles/animations。

还建议为你的动画分配唯一标识符。这些标识符将显示在 Chrome 的动画检查器中,应该使调试更容易:

/**
* .square 元素的动画应在 Chrome DevTools 中
* 显示 "my-animation-identifier"。
*/
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 是特定于自定义动画的额外选项。例如,sheet modal 进入动画包含当前断点的信息。

AnimationCallbackOptions​

interface AnimationCallbackOptions {
/**
* 如果为 true,关联的回调将仅触发一次。
*/
oneTimeCallback: boolean;
}

AnimationPlayOptions​

interface AnimationPlayOptions {
/**
* 如果为 true,动画将同步播放。
* 这相当于以 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设置动画的缓动效果(毫秒)。参见 Easing Effects 了解可接受的缓动值列表。
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设置动画的结束样式。