鸿蒙-----动画/交互事件

248 阅读4分钟

动画/交互事件


回顾

再前面的文章中,首先从登录页开始,这一篇大概涉及到了基本UI搭建及http网络请求。第二篇中以应用首页为展开, 涉及到了更多UI方面的搭建,有底部导航栏,banner图,懒加载列表等。到第三篇,主要是上传/下载及WebView,这一部分 内容主要是作为应用我的部分经常会有的,比如头像上传,app更新,隐私协议等。此时就将应用登录,注册,首页,列表,我的等 页面主要功能部分就介绍完了。 接下来,是平常会用到的功能,即本地通知,广播,数据库持久化存储。

到这一篇,看点简单的东西,UI动画。

显示动画

定义属性,放在animationTo闭包中修改相应的属性值

    animateTo({
  duration: 1000,
  curve: Curve.Ease // 低速开始 加快 结束前变慢
},() => {
  if (this.flag) {
    this.stackWidth = 200 // 修改控件宽高
    this.stackHeight = 100
  } else {
    this.stackWidth = 400
    this.stackHeight = 200
  }
  this.flag = !this.flag
})

属性动画

相较于显示动画,无需借助animationTo闭包修改属性 运用animation属性,再其之前设置的属性值发生变化时,会执行动画过度

    Stack() {
  Text('test animation')
    .fontColor('#ffffff')
    .fontSize(20)
}.alignContent(Alignment.Center)
  .backgroundColor(this.bgColor) 
  .width(this.stackWidth)
  .height(this.stackHeight)
  .animation({duration: 3000,curve: Curve.Ease,delay: 1000,onFinish: () => {}}) // 颜色,宽高属性改变时,会执行动画
  .translate({x: this.translateX}) // translateX变化不会执行动画

转场动画

组件内转场动画

由IF/ELSE控制的组件显示隐藏,ForEach列表元素个数的变化

为组件增加transition属性,通过animationTo控制开启动画

  transition({type: TransitionType.All,translate: {x: -200,y: 200},opacity: 0})

type: 控制是显示(TransitionType.Insert)或隐藏(TransitionType.Delete)执行动画 针对显示动画,设置的translate,opacity为起始值,控件属性为结束值 针对隐藏动画,控件属性为起始值,设置的平移,透明度等为结束值 动画曲线由animationTo的curve参数决定

  1. 平移 x: 横向的平移距离 y: 纵向的平移距离 z: 竖向的平移距离
      translate: {x: 200,y: -200,z: 200}
    
  2. 缩放 x:横向放大倍数(或缩小比例) Y: 纵向放大倍数(或缩小比例) centerX、centerY指缩放中心点,centerX和centerY默认值是"50%"
      scale: {x: 0,y: 0,centerX: 0,centerY: 0}
    
  3. 透明度 取值范围: [0, 1]
      opacity: 0
    
  4. 旋转 x,y,z: 横向,纵向,竖向的旋转向量
      rotate: {
          x: 0,y: 0,z: 1,angle: 360,centerX: '50%',centerY: '50%'
        }
    
共享元素转场

不同页面,有使用相同的元素的场景,可以使用共享元素转场动画衔接 配置为相同id的组件,它们为共享元素。从起始页共享元素位置、大小过度到目标页的位置、大小

  • A页面:
       sharedTransition("sharedImage",{duration: 1000,curve: Curve.Linear})  // type 默认:SharedTransitionEffectType.Exchange
    
  • B页面:
       sharedTransition("sharedImage",{duration: 1000,curve: Curve.Linear,type: SharedTransitionEffectType.Exchange})  
    

SharedTransitionEffectType.Static 类型的共享元素转场。

  • 只需要再一个页面配置
  • 不能再两个页面中有相同的id
  • 动画从透明度0过度到设定的值 起始页为设定的值到透明度0的变化
  • 位置保持不变
      sharedTransition("text",{curve: Curve.Linear,duration: 1000,type: SharedTransitionEffectType.Static})
    
页面间转场

两个页面跳转时,发生的页面专场效果。定义再pageTransition函数中。

pageTransition() {
  // 定义页面进入动画 RouteType.Push type指定页面为入栈时的动画即执行router.pushUrl时。  当为出栈显示页面时,不执行该动画效果
  PageTransitionEnter({ type: RouteType.Push,duration: 1000,curve: Curve.Linear })
    .translate({x: -200,y: 100})
    .onEnter((type: RouteType, progress: number) => {
      console.log('enter::',type,progress)
    })

  // 定义页面退出动画 RouteType.Pop type指定页面为出栈即router.back时页面退出执行的动画。
  PageTransitionExit({type: RouteType.Pop,duration: 1000,curve: Curve.Linear})
    .slide(SlideEffect.Right)
    .scale({x: 0,y: 0})
    .opacity(0)
    .onExit((type: RouteType, progress: number) => {
      console.log('exit::',type,progress)
    })

  // None 表示对页面栈的push、pop操作均生效
  PageTransitionEnter({ type: RouteType.None,duration: 1000,curve: Curve.Linear })
    .translate({x: -200,y: 100})
}

注:通过设置页面转场的时长为0,可使该页面无页面转场动画

弹簧曲线动画

  • springCurve 构造参数包括初速度,弹簧系统的质量、刚度、阻尼。
animateTo({duration: 2000,curve: curves.springCurve(200,1,3,1.2)},() => {
  this.translateX = 0
})
  • springMotion和responsiveSpringMotion
Circle({width: 50,height: 50})
          .fill(Color.Blue)
          .position({x: this.positionX,y: this.positionY})
          .onTouch((event) => {
            if (event.type == TouchType.Move) {
              animateTo({curve: curves.responsiveSpringMotion(0.15,0.86,0.25)},() => {
                this.positionY = event.touches[0].y
                this.positionX = event.touches[0].x
              })
            } else if(event.type == TouchType.Up) {
              animateTo({curve: curves.springMotion(0.55,0.825,0)},() => {
                this.positionX = 20
                this.positionY = 20
              })
            }
})