鸿蒙 OS-08 动画:属性动画、显式动画、组件转场动画、触摸事件 鱼摇杆动画

143 阅读1分钟

图片来源:黑马程序员 bz

原理:属性的变化,开始状态,结束状态,变化过程。

  • 属性动画:通过设置组件的 animation 属性来添加动画。

  • 显示动画:通过全局 animateTo() 函数来改变组件的属性。更加灵活,所有的属性都可以定义在方法内

  • 组件转场动画:组件插入、移除时的过渡动画。组件.transition()参数控制 + animateTo()true/false控制。

     transition 中 type:TransitionType.All,//if 显示 100-》20,gone 20->100
        // type: TransitionType.Insert,//插入 显示view 时,traslate作为起点,  从 traslate 位置--》position位置
        // type: TransitionType.Delete,//删除 view 消失时, traslate作为终点,position位置--》traslate位置
    
  • 触摸事件摇杆动画:

//摇杆 大小
Row(){...}.onTouch(this.handleTouchEvent.bind(this))

//处理手势事件,只是单指
handleTouchEvent(event: TouchEvent){
move 坐标  :手指坐标,相对摇杆位置。 计算角度 + 距离:
摇杆位置:手的相对移动位置
鱼位置:角度 * speed , setinterval 定时任务 刷新位置 如果不加只会 丢失很多距离}

// 小鱼坐标 @State fishX: number = 200 @State fishY: number = 180 // 小鱼角度 @State angle: number = 0 // 小鱼图片 @State src: Resource = $r('app.media.fish')

// 小鱼图片 Image(this.src) .position({x: this.fishX - 20, y: this.fishY - 20}) .rotate({angle:this.angle, centerX: '50%', centerY: '50%'}) .width(40) .height(40) //.animation({duration: 500, curve: Curve.Smooth}) //1 . 属性动画 .transition({ type: TransitionType.Insert, opacity: 0, translate: {x: -250} })

属性动画:更加方便 Button('←').backgroundColor('#20101010') .onClick(() => { this.fishX -= 20 this.src = $r('app.media.fish_rev') ) })

2.显示动画:更加灵活,所有的属性都可以定义在方法内 Button('←').backgroundColor('#20101010') .onClick(() => { animateTo( {duration: 500}, () => { this.fishX -= 20 this.src = $r('app.media.fish_rev') } ) })


# 属性动画:通过设置组件的 animation 属性来添加动画。

![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/26871aea9ac04480ba56325c180b547f~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=2564&h=1464&s=1397887&e=png&b=030303)


方式 1

![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/e6c0989fbf6548349276d2b4becaad75~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1884&h=1160&s=1040661&e=png&b=232628)

# 显示动画:通过全局 animateTo 函数来改变组件的属性。

![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/30904bc1ebdc43c9a3b28f3c749affc1~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=2462&h=1448&s=1329177&e=png&b=030303)

# 组件转场动画:组件插入、移除时的过渡动画。组件.transition()参数控制 + animateTo()true/false控制。

起始点坐标,0,0
position

![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/8c78708d986e4840b3c9f30175cbd8ff~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=2682&h=1390&s=1062093&e=png&b=020202)

true /false 控制显示与否。
![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/735c06c8d86b4c6faaa800dbbb7b5605~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=2530&h=1320&s=1180747&e=png&b=020202)

```TypeScript

// 是否开始游戏
@State isBegin: boolean = false

@State fishX: number = 0
@State fishY: number = 0


// 开始、结束 按钮
Button('开始、结束 游戏')
  .onClick(() => {
    animateTo(
      {duration: 3000},
      () => {
        // 点击后显示小鱼
        this.isBegin = !this.isBegin
      }
    )
  })
if(!this.isBegin){
  // 小鱼图片
  Image(this.src)
    // .position({x: this.fishX - 20, y: this.fishY - 20})
    .position({x: this.fishX + 20, y: this.fishY + 20})
    .rotate({angle:this.angle, centerX: '50%', centerY: '50%'})
    .width(40)
    .height(40)
    //.animation({duration: 500, curve: Curve.Smooth})
    .transition({//组件 转场动画
      type:TransitionType.All,//if 显示 100-》20,gone 20->100
      // type: TransitionType.Insert,//插入 显示view 时,作为起点,  从 traslate 位置--》position位置
      // type: TransitionType.Delete,//删除 view 消失时, traslate作为终点,position位置--》traslate位置
      opacity: 0,//透明度 0 开始 ,逐渐到 1
      translate: {x: 100}//开始位置,结束位置
    })
}

小鱼摇杆动画:总之

image.png

触摸事件


// 摇杆
Row(){
  Circle({width: this.maxRadius * 2, height: this.maxRadius * 2})
    .fill('#20101010')
    .position({ x: this.centerX-this.maxRadius, y: this.centerY-this.maxRadius })
  Circle({ width: this.radius * 2, height: this.radius * 2 })
    .fill('#403A3A3A')
    .position({ x: this.positionX - this.radius, y: this.positionY - this.radius})
}
.height(240)
.width(240)
.justifyContent(FlexAlign.Center)
.position({x:0,y:120})
.onTouch(this.handleTouchEvent.bind(this))




// 处理手指移动的事件
handleTouchEvent(event: TouchEvent){
  switch (event.type){
    case TouchType.Up:
      // 还原小鱼速度
      this.speed = 0
      // 取消定时任务
      clearInterval(this.taskId)
      // 还原摇杆小球的坐标
      animateTo(
        {curve: curves.springMotion()},
        () => {
          this.positionX = this.centerX
          this.positionY = this.centerY

          this.angle = 0
        }
      )
      break
    case TouchType.Down:
      // 开始定时任务
      this.taskId = setInterval(() => {
        this.fishX += this.speed * this.cos
        this.fishY += this.speed * this.sin
      }, 40)
      break

    case TouchType.Move:
      // 1.获取手指位置坐标
      let x = event.touches[0].x
      let y = event.touches[0].y
      // 2.计算手指与中心点的坐标差值
      let vx = x - this.centerX
      let vy = y - this.centerY
      // 3.计算手指与中心点连线和x轴正半轴的夹角,单位是弧度
      let angle = Math.atan2(vy, vx)
      // 4.计算手指与中心点的距离
      let distance = this.getDistance(vx, vy)

      this.sin = Math.sin(angle)
      this.cos = Math.cos(angle)
      animateTo(
        {curve: curves.responsiveSpringMotion()},//持续 跟手 动画。
        () => {
          // 5.计算摇杆小球的坐标
          this.positionX = this.centerX + distance * this.cos
          this.positionY = this.centerY + distance * this.sin

          // 6.修改小鱼的角度
          if(Math.abs(angle * 2) < Math.PI){
            this.src = $r('app.media.fish')
          }else{
            this.src = $r('app.media.fish_rev')
            angle = angle < 0 ? angle + Math.PI : angle - Math.PI
          }
          this.angle = angle * 180 / Math.PI

          this.speed = 1
        }
      )
      break
  }
}