转场动画,谁有好的方案吗?-鸿蒙开发者社区-51CTO.COM

转场动画,谁有好的方案吗?

转场动画

HarmonyOS
2024-06-11 20:51:22
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
depengli

在说明转场之前,需要先说明下页面管理的数据结构,在 ArkUi中,使用栈这个数据结构管理页面,当前显示的页面在栈的顶部。

1. 跳转到一个新页面时,将要显示的页面会覆盖在当前正在显示的页面之上,这个就是栈的push操作,新页面在栈顶位置,之前的页面在栈顶位置之下。

2. 返回操作,当前正在显示的页面会从页面栈中弹出,之前的页面就显示出来了,这个就是栈的pop操作。栈的数量减一,之前的页面重新回到在栈顶。

在ArkUi中可以通过导入ohos.router实现页面切换,在这个包中定义了三种路由切换的操作:

1. push: 跳转到指定的新页面。

2. back:返回页面栈中的上一个页面。

3. replace:使用指定页面替换当前页面。

还有一个默认操作:返回键,三键导航上的返回键或者全局手势触发的返回事件,对应router模块中的back操作。

页面转场动效只针对 push 和 back 场景,replace场景下没有对应的页面转场动效。

转场动效中有入场和出场两个概念:入场就是从不可见状态到前台显示的过程,在页面栈的栈顶;出场就是页面从前台消失,可能还在页面栈中,也可能不在页面栈中。

两个路由操作和两个页面效果,一共有四个场景需要讨论:

1、pop 操作

最开始栈顶页面是 page A, pop操作之后,栈顶元素变成 page B

  • page C 触发PageTransitionExit, 触发的RouteType 为 Pop
  • page B 触发PageTransitionEnter,触发的RouteType为 Pop

2、push 操作

  • page C 触发PageTransitionEnter, 触发的RouteType 为 Push
  • page B 触发PageTransitionExit,触发的RouteType为 Push

全局函数PageTransitionEnter和PageTransitionExit用于在页面切换过程中指定转场动效,可以指定转场动画时长(duration),时间曲线(curve),动画延迟时长(delay),如果指定RouteType,那么只有在指定的路由操作下才能触发:

  • PageTransitionEnter 指定 RouteType.Pop: pop操作触发的入场动画
  • PageTransitionEnter 指定 RouteType.Push: push操作触发的入场动画
  • PageTransitionExit 指定 RouteType.Pop: pop操作触发的离场动画
  • PageTransitionExit 指定 RouteType.Push:push操作触发的离场动画

页面转场动画支持的默认属性,包括:平移,缩放,透明度,因为页面转场的顺序是 入场前状态 -> 显示状态 -> 离场后状态, PageTransitionEnter 指定的是入场动画的起始值,PageTransitionExit 指定的是离场动画的终点值。

页面转场中最常见的应该就是页面的淡入淡出动效,可以通过设置opacity实现,例如在 PageTransitionEnter 设置 opacity: 0.3, 在 PageTransitionExit 设置 opacity: 0.2, 那么在转场变换就是这样的:

入场动画: opacity属性: 0.3 -> 1.0

离场动画: opacity属性: 1.0 -> 0.2

页面转场中另外一个最常见的场景就是滑入滑出,可以通过配置slide实现,默认定义了四个方向的滑动动效。

主页通过路由参数传递滑动方向和背景色。

Text('SlideEffect.Top') 
  .translate({ x: 0, y: this.topY }) 
  .width('100%') 
  .height('10%') 
  .textAlign(TextAlign.Center) 
  .fontSize('20fp') 
  .fontWeight(FontWeight.Bold) 
  .backgroundColor('#FFF6CD46') 
  .onClick(() => { 
    router.push({ 
      url: NEXT_PAGE, 
      params: { type: SlideEffect.Top, color: '#FFF6CD46' } 
    }) 
  })

跳转页通过router获取路由参数,配置对应的背景色和转场动效。

aboutToAppear() { 
  let param = router.getParams() 
  this.type = param['type']; 
  this.color = param['color']; 
} 
 
pageTransition() { 
  PageTransitionEnter({ duration: 370, curve: Curve.Linear }) 
    .slide(this.type) 
 
  PageTransitionExit({ duration: 370, curve: Curve.Ease }) 
    .slide(this.type) 
}

在页面入场下,配置的方向,是动画的起始方向;在页面离场下,配置的方向,是动画的终点方向。

页面转场还支持逐帧回调,PageTransitionEnter 中的 onEnter 回调和PageTransitionExit 中的 onExit, 第一个参数标记当前的路由操作,第二个参数是 [0, 1] 闭区间内的动画进度。可以让控件在页面转场时实现相应的动效,通过逐帧的回调,可以让开发者对页面上的控件的自定义转场动效。

在之前示例之上,为主页上的按钮添加自定义动效,在页面入场的时候,按钮从四个方向飞入,在页面离场的时候,按钮向四个方向飞出。

在对应的逐帧回调中修改状态变量,对应的状态变量又绑定在控件的属性上,在动画过程中,progress 在[0, 1]闭区间内线性变化。

pageTransition() { 
  PageTransitionEnter({ duration: 370, curve: Curve.Linear }) 
    .onEnter((type: RouteType, progress: number) => { 
      this.progress = 1 - progress 
    }) 
 
  PageTransitionExit({ duration: 370, curve: Curve.Ease }) 
    .onExit((type: RouteType, progress: number) => { 
      this.progress = progress 
    }) 
} 
 
Text('SlideEffect.Top') 
  .translate({ x: 0, y: `-${this.progress * 200}%` }) // progress状态变量绑定在平移属性上。 
  .width('100%') 
  .height('10%')

共享元素转场

两个页面上存在相同元素,通过配置相同的ID和动效参数,在页面转场时,这个元素会产生位移和长宽动效。

页面A,只设置了id,在跳转到B时,会使用B页面的动效参数。

Image($r('app.media.icon')) 
  .width(100) 
  .height(100) 
  .sharedTransition(SHARED_TRANSITION_ID) 
  .onClick(() => { 
    router.push({ url: 'pages/second' }) 
  })

页面B在返回A页面时, 因为A页面没有设置动效参数,动效时长、曲线会和页面转场一致。

Image($r('app.media.icon')) 
  .sharedTransition(SHARED_TRANSITION_ID, { duration: 1000, curve: Curve.EaseIn }) 
  .clip(true) 
  .width(150) 
  .height(150) 
  .onClick(() => { 
    router.back() 
  })
  • 不设置 sharedTransitionOptions, 取页面转场的周期、时间曲线。
  • 使用终点页面的sharedTransitionOptions生效,如果A页面跳转到B页面,使用B页面上配置的 sharedTransitionOptions。
  • 共享元素转场只包含两个动效: 位移动效和长宽变化
  • 只支持:Image Text Button 控件

组件内转场

在说明animateTo的时候,他的另外一个作用是可以在容器发生子控件新增、删除、交换导致布局发生变化的时候,插入对应的位移动画。默认情况下删除或者新增的空间是控件任何动效的。可以通过 transition来设置对应控件的入场和消失动画。transition的设置和页面间转场类似,可以通过指定type来指定入场或者消失动画, 根据type的不同,设置的属性值也有不同的含义。

− type = Insert: 当前指定的状态属性是入场动画的起始状态

− type = Delete: 当前指定的状态属性是离场动画的终点状态

− type 不指定: 在入场动画时作为动画的起始状态,在离场动画时作为动画的终点状态

为之前的list示例新增两个动效:

− 删除动效:通过左滑手势触发动效,透明度变为零,向左平移滑出屏幕。

.transition({ type: TransitionType.Delete, opacity: 0, translate: { x: -360 } })

translate和通用属性的translate的差别是,transition中的translate不支持百分比

− 新增动效:透明度从零渐变,y轴从0开始放大。

.transition({ type: TransitionType.Insert, opacity: 0, scale: { y: 0 } })

删除的动效分为两端,第一阶段:跟手移动一段时间;第二阶段:继续移动,滑出窗口

通过使用

PanGesture 

手势,在手势移动过程中,修改offsetX状态变量,实现跟手移动,在手势完成之后,通过

animateTo

触发离场动效。

.translate({ x: this.offsetX }) 
  .gesture(PanGesture({ direction: PanDirection.Left }) 
    .onActionStart(() => { 
    }).onActionUpdate((event: GestureEvent) => { 
      this.offsetX = event.offsetX 
    }).onActionEnd((event: GestureEvent) => { 
      this.callBack(this.index) 
    }) 
  )
分享
微博
QQ
微信
回复
2024-06-12 22:47:31
相关问题
taskpool使用 ,谁有方案
644浏览 • 1回复 待解决
本地收发消息实践,谁有方案
540浏览 • 1回复 待解决
ArkUI转场动画可以改颜色
1829浏览 • 1回复 待解决
har和hsp转换,有方案
595浏览 • 1回复 待解决
Text模拟隐私协议,有方案
683浏览 • 1回复 待解决
连接网络信息获取有方案
553浏览 • 1回复 待解决
如何实现动画转场效果
769浏览 • 1回复 待解决
SM4 CBC模式加解密,有方案
934浏览 • 1回复 待解决
HarmonyOS 页面内组件转场动画
253浏览 • 1回复 待解决
请问如何去掉ability转场动画
11167浏览 • 2回复 待解决
如何全局设置页面转场动画
660浏览 • 1回复 待解决
Tabs 出现/消失转场动画效果
283浏览 • 1回复 待解决
屏幕旋转计算,有什么方案
828浏览 • 1回复 待解决
Scrollerfling实现有什么方案
711浏览 • 1回复 待解决