HarmonyOS中實(shí)現(xiàn)搖桿小球拖動(dòng)功能

在學(xué)習(xí)Harmonyos中實(shí)現(xiàn)了一個(gè)搖桿動(dòng)畫的效果,覺得很不錯(cuò),特來與諸位分享一下?。?!

image.png
搖桿實(shí)現(xiàn)
// 搖桿中心區(qū)域
  private centerX: number = 120
  private centerY: number = 120

  // 大、小圓半徑
  private maxRadius: number = 100
  private radius: number = 20

  // 搖桿小球初始位置
  @State positionX: number = this.centerX
  @State positionY: number = this.centerY

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))
// 處理手指移動(dòng)的事件
  handleTouchEvent(event:TouchEvent) {
    switch (event.type){
      case TouchType.Up:
        // 還原小魚速度
        this.speed = 0
        // 取消定時(shí)任務(wù)
        clearInterval(this.taskId)
        // 還原搖桿小球的坐標(biāo)
        animateTo(
          {curve: curves.springMotion()},
          () => {
            this.positionX = this.centerX
            this.positionY = this.centerY
            this.angle = 0
          }
        )
        break
      case TouchType.Down:
        // 開始定時(shí)任務(wù)
        this.taskId = setInterval(() => {
          this.fishX += this.speed * this.cos
          this.fishY += this.speed * this.sin
        }, 40)

        break
      case TouchType.Move:
        // 1. 獲取手指位置坐標(biāo)
        let x = event.touches[0].x
        let y = event.touches[0].y
        // 2. 計(jì)算手指與中心點(diǎn)的坐標(biāo)差值
        let vx = x - this.centerX
        let vy = y - this.centerY
        // 3. 計(jì)算手指與中心點(diǎn)連線和x正半軸的夾角,單位是弧度
        let angle = Math.atan2(vy, vx)
        // 4.計(jì)算手指與中心點(diǎn)的距離
        let distance = this.getDistance(vx, vy)

        this.sin = Math.sin(angle)
        this.cos = Math.cos(angle)
        animateTo(
          {curve: curves.responsiveSpringMotion()},
          () => {
            // 5. 計(jì)算搖桿小球的坐標(biāo)
            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 = 5
          }
        )
        break
    }
  }

  getDistance(x: number, y: number) {
    let d = Math.sqrt(x * x + y * y)
    return Math.min(d, this.maxRadius)
  }

代碼很簡(jiǎn)單,先是實(shí)現(xiàn)了兩個(gè)同心圓,根據(jù)已知的半徑,和位置就能實(shí)現(xiàn)兩個(gè)圓,在利用觸摸事件,實(shí)現(xiàn)搖桿的功能, getDistance 方法是獲取兩點(diǎn)之間的距離,利用反正切函數(shù)的vx和vy獲取距離,這就是核心代碼,與諸位共勉

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容