鸿蒙5页面转场动画实现(250ms & EaseOut贝塞尔曲线)

暗雨OL
发布于 2025-6-27 21:35
浏览
0收藏

本文将展示如何在鸿蒙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 })

}
}
关键代码解释

  1. 动画参数设置
    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曲线,可以创建出流畅自然的用户体验,既不会因太快而显得突兀,也不会因太慢而让用户等待,在视觉愉悦度和系统效率之间取得完美平衡。

分类
标签
收藏
回复
举报
回复
    相关推荐