动画及转场

属性动画

最基础的动画类型,按照动画参数逐帧驱动属性的变化,产生一帧帧的动画效果。除其中的自定义属性动画外,动画过程的驱动由系统完成,应用侧不感知动画过程。(点击链接可查看)

1.使用animation(属性动画)

示例1:
  @Prop item: Items_color;
  @Prop index: number;
  @Prop animate2: boolean;
  onToggle: () => void = () => {};
  build() {
    Column() {
    }
    .width(75)
    .alignRules(relative_align.align_center_middle)
    .height(75)
    .opacity(!this.animate2? 0.6:1)
    .backgroundColor(this.item.color)
    .rotate({
      x: 0,
      y: 1,
      z: 0,
      angle: this.animate2 ? 360 : 0
    })
    .animation({ curve: curves.springMotion()})
  }

animation属性会自动感应组件可变属性的变化并加载动画。

解释说明:

在这段代码中,animate2发生变化后,angle会从360->0或者从0->360,这样animation属性就会识别到变化,加载动画。

一般的可变属性:

width
height
opacity:number 透明度
translate:{x:number,y:number,z:number} 平移
backgroundColor
scal:{x:number,y:number,z:number,centerX:number,centerY:number} 缩放
rotate:{x,y,z,centerX,centerY,centerZ,perpective} 旋转

2.使用animationTo(显式动画)

示例1:
  
  aboutToAppear() {
    // 使用动画让组件从小变大
    animateTo({ duration: 2000, curve: Curve.EaseInOut }, () => {
      this.scaleValue = 1;
    })
  }

这里写在了aboutToAppear中了,可以让组件加载时出发,可以实现类似组件转场的效果。

Column() {
      }
      .width(this.bubble.size)
      .height(this.bubble.size)
      .scale({ x: this.scaleValue, y: this.scaleValue })
示例2:

写在点击事件里,触发点击事件后执行

.onClick(() => {
        animateTo({ duration: 1000, curve: Curve.FastOutSlowIn }, () => {
          //消失
          this.bubble.size = 0;
        });
解释说明:

接口参数说明

animateTo(value: AnimateParam, event: () => void): void

value指定AnimateParam对象(详细信息点击链接跳转API文档,这里简单说明)

duration:number 动画持续时间
tempo:number 播放速度
curve 动画曲线
delay:number 播放延迟
iterations:number 播放次数
playMode:playMode 播放模式
onFinish:()=>{} 结束回调
expectedFrameRateRange 期望帧率

转场动画

为组件在出现和消失时添加过渡动画。

transition(组件的出现和消失)

示例1:
Column() {
    }
    .alignRules(relative_align.align_center_middle)
    .width(75)
    .height(75)
    .borderRadius('50%')
    .transition(Transition_effect.left_end_effect())
export default class Transition_effect {
  static left_end_effect(): TransitionEffect {
    return TransitionEffect.OPACITY
      .combine(TransitionEffect.scale({ x: 0, y: 0 })
        .animation({ curve: Curve.Friction, delay: 1000 * Math.random() }))
      .combine(TransitionEffect.rotate({ angle: 90 }))
      .combine(TransitionEffect.translate({ y: 150 }))
      .combine(TransitionEffect.move(TransitionEdge.END));
  }
}
示例2:
// 出现时做从指定的透明度为0变为默认的透明度1的动画,该动画时长为1000ms,以及做从指定的绕z轴旋转180°变为默认的旋转角为0的动画,该动画1000ms后播放,时长为1000ms
// 消失时做从默认的透明度为1变为指定的透明度0的动画,该动画1000ms后播放,时长为1000ms,以及做默认的旋转角0变为指定的绕z轴旋转180°的动画,该动画时长为1000ms
Image($r('app.media.Img1')).width(100).height(100)
  .transition(
    TransitionEffect.asymmetric(
      TransitionEffect.OPACITY.animation({ duration: 1000 }).combine(
        TransitionEffect.rotate({ z: 1, angle: 180 }).animation({ delay: 1000, duration: 1000 }))
      ,
      TransitionEffect.OPACITY.animation({ delay: 1000, duration: 1000 }).combine(
        TransitionEffect.rotate({ z: 1, angle: 180 }).animation({ duration: 1000 }))
    )
  )
解释说明:

可以通过asymmetric给显示和消失配置不同的效果 。

同时官方也提供了一些可以直接选用的样式:

IDENTITY 禁用转场效果
OPACITY 出现时透明度从0到1、消失时透明度从1到0
SLIDE 从START边滑入,END边滑出
SLIDE_SWITCH 出现时从右侧先缩小再放大滑入、消失时从左侧先缩小再放大滑出

粒子动画

Particle

完整示例:
@Component
export struct ParticleExample {
  build() {
    Particle({
      particles: [
        {
          emitter: {
            particle: {
              type: ParticleType.POINT, // 粒子类型
              config: {
                radius: 10 // 圆点半径
              },
              lifetime: 4000, // 粒子生命周期,单位ms
              lifetimeRange: 1000, // 粒子生命周期取值范围,单位ms
              count: 1000, // 粒子总数
            },
            emitRate: 10, // 每秒发射粒子数
            position: [0, 0],
            shape: ParticleEmitterShape.RECTANGLE // 发射器形状
          },
          color: {
            range: ['rgb(39, 135, 217)', 'rgb(0, 74, 175)'], //初始颜色范围
          },
          scale: {
            range: [0.0, 0.0],
            updater: {
              type: ParticleUpdater.CURVE,
              config: [
                {
                  from: 0.0,
                  to: 0.5,
                  startMillis: 0,
                  endMillis: 3000,
                  curve: Curve.EaseIn
                }
              ]
            }
          },
          acceleration: {
            //加速度的配置,从大小和方向两个维度变化,speed表示加速度大小,angle表示加速度方向
            speed: {
              range: [3, 9],
              updater: {
                type: ParticleUpdater.RANDOM,
                config: [1, 20]
              }
            },
            angle: {
              range: [90, 90]
            }
          }

        }
      ]
    }).width('100%').height('100%')
  }
}

模态转场

bindContentCover 弹出全屏模态组件
bindSheet 弹出半模态组件
bindMenu 点击后弹出菜单。
bindContextMenu 长按或者右键点击后弹出
bindPopup 弹出Popup弹框
if 新增或删除

详细内容可以点链接去官网看,我没用到就不展示了。

页面转场动画

pageTransition() {
  PageTransitionEnter()
  PageTransitionExit()
}

PageTransitionEnter({ type?: RouteType, duration?: number, curve?: Curve | string, delay?: number })

PageTransitionExit({ type?: RouteType, duration?: number, curve?: Curve | string, delay?: number })

示例1:

  pageTransition() {
    PageTransitionEnter({ type: RouteType.None, duration: 1000,curve: Curve.Sharp })
      .slide(SlideEffect.Top)
    PageTransitionExit({ type: RouteType.None, duration: 1000,curve: Curve.Rhythm })
      .slide(SlideEffect.Bottom)
  }

解释说明:

效果不论是push、pop从上面进来,出去时从下面出去

示例2:

pageTransition() {
  // 进入效果,右侧滑入,页面栈发生push操作时该效果才生效
  PageTransitionEnter({ type: RouteType.Push, duration: 1200 })
    .slide(SlideEffect.Right)
  // 进入效果,左侧滑入,页面栈发生pop操作时该效果才生效
  PageTransitionEnter({ type: RouteType.Pop, duration: 1200 })
    .slide(SlideEffect.Left)
  // 退出效果,左侧滑出,页面栈发生push操作时该效果才生效
  PageTransitionExit({ type: RouteType.Push, duration: 1000 })
    .slide(SlideEffect.Left)
  // 退出效果,右侧滑出,页面栈发生pop操作时该效果才生效
  PageTransitionExit({ type: RouteType.Pop, duration: 1000 })
    .slide(SlideEffect.Right)
}

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐