
鸿蒙5页面转场动画实现(250ms & EaseOut贝塞尔曲线)
本文将展示如何在鸿蒙5(HarmonyOS)中实现优雅的页面转场动画,使用250ms时长与EaseOut贝塞尔曲线效果。
效果预览
当点击"跳转到目标页"按钮时,可以看到页面平滑过渡的效果,动画持续250毫秒,符合EaseOut曲线(启动迅速,结束平滑)。
实现代码
import { Curve, Ease } from ‘@ohos/curves’
import router from ‘@ohos.router’
@Entry
@Component
struct IndexPage {
@State scale: number = 0.8
@State opacity: number = 0
@State bgColor: Color = Color.White
// 使用250ms持续时间的EaseOut曲线定义转场动画
private transitionOptions: router.RouterOptions = {
animator: {
duration: 250,
curve: Curve.EaseOut
}
}
build() {
Stack() {
Column() {
Text(‘首页’)
.fontSize(36)
.fontWeight(FontWeight.Bold)
.margin({ top: 20, bottom: 10 })
// 显示动画预览区域
Stack() {
Column() {
Text('Hello Harmony!')
.fontSize(18)
.fontColor(Color.Black)
}
.width('90%')
.height(200)
.backgroundColor('#D2F1FF')
.borderRadius(16)
.opacity(this.opacity)
.scale({ x: this.scale, y: this.scale })
.transition('scale', { duration: 500, curve: Ease.Linear })
.transition('opacity', { duration: 500, curve: Ease.Linear })
}
.width('100%')
.height(240)
.margin(20)
Text('动画设置参数')
.fontSize(20)
.margin({ top: 20 })
Divider().margin(10)
// 参数设置面板
Column() {
Row() {
Text('动画时长: 250ms')
.fontSize(18)
.fontColor('#007DFF')
}
.width('100%')
.justifyContent(FontAlign.Center)
Row() {
Text('贝塞尔曲线: Curve.EaseOut')
.fontSize(18)
.fontColor('#007DFF')
}
.width('100%')
.margin({ top: 10 })
.justifyContent(FontAlign.Center)
}
.width('90%')
.padding(20)
.backgroundColor('#FFFFFF')
.borderRadius(16)
.margin(20)
// 转场控制按钮
Button('跳转到目标页')
.width('80%')
.height(50)
.fontSize(18)
.margin({ top: 30 })
.backgroundColor('#007DFF')
.onClick(() => {
router.pushUrl({
url: 'pages/TargetPage',
}, this.transitionOptions)
})
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
.onAppear(() => {
this.scale = 1.0;
this.opacity = 1;
})
}
}
}
@Component
struct TargetPage {
@State scale: number = 1.0
@State opacity: number = 0
private transitionOptions: router.RouterOptions = {
animator: {
duration: 250,
curve: Curve.EaseOut
}
}
build() {
Stack() {
Column() {
Text(‘目标页面’)
.fontSize(36)
.fontWeight(FontWeight.Bold)
.margin({ top: 20, bottom: 30 })
Image($r('app.media.target'))
.width(250)
.height(250)
.objectFit(ImageFit.Contain)
.margin(20)
Text('这是通过动画转场到达的目标页面')
.fontSize(18)
.margin({ top: 20, bottom: 20 })
Button('返回首页')
.width('80%')
.height(50)
.fontSize(18)
.margin({ top: 30 })
.backgroundColor('#4CAF50')
.onClick(() => {
router.back(this.transitionOptions)
})
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
.onAppear(() => {
this.opacity = 1
})
}
.opacity(this.opacity)
.transition('opacity', { duration: 300 })
}
}
关键代码解释
- 动画参数设置
private transitionOptions: router.RouterOptions = {
animator: {
duration: 250,
curve: Curve.EaseOut
}
}
这段代码定义了页面转场动画的参数:
duration: 250 - 指定动画持续250毫秒
curve: Curve.EaseOut - 使用贝塞尔曲线缓出效果
2. 动画触发执行
// 页面跳转时应用动画
router.pushUrl({
url: ‘pages/TargetPage’,
}, this.transitionOptions)
// 返回时也应用相同的动画效果
router.back(this.transitionOptions)
3. EaseOut曲线特性
Curve.EaseOut是一种先快后慢的动画效果:
动画启动时变化速度快
接近结束时变化速度逐渐减慢
提供更自然的过渡体验
特别适合页面转场场景
4. 组件动画实现
.transition(‘scale’, { duration: 500, curve: Ease.Linear })
.transition(‘opacity’, { duration: 500, curve: Ease.Linear })
这展示了如何在组件上应用动画效果,定义多个属性的过渡效果。
设计理念与最佳实践
一致性原则:进出动画应该采用相同的效果和持续时间
适量原则:250ms是页面转场的理想时间,足够体现效果又不拖沓
方向性:EaseOut曲线特别适合正向导航(进入新页面)
反馈原则:动画效果为用户提供明确的导航反馈
适应性:在所有屏幕尺寸和方向上保持一致的体验
通过在鸿蒙系统中使用250ms的转场时长配合EaseOut曲线,可以创建出流畅自然的用户体验,既不会因太快而显得突兀,也不会因太慢而让用户等待,在视觉愉悦度和系统效率之间取得完美平衡。
