在HarmonyOS NEXT开发中组件旋转后,平移方向出错?

在HarmonyOS NEXT开发中组件旋转后,平移方向出错?组件旋转后,组件的x, y轴还是原来的方向。代码:

import json from '@ohos.util.json' 
 
@Entry 
@Component 
struct Index { 
  @State imageWidth: number = 0 
  @State imageHeight: number = 0 
  @State offsetX: number = 0 
  @State offsetY: number = 0 
  @State positionX: number = 0 
  @State positionY: number = 0 
  @State angle: number = 0 
  @State rotateValue: number = 0 
  @State scaleValue: number = 1 
  @State pinchValue: number = 1 
  @State pinchX: number = 0 
  @State pinchY: number = 0 
  @State centerX: number = 0 
  @State centerY: number = 0 
 
  aboutToAppear(): void { 
 
  } 
 
  build() { 
    Column() { 
      Text('标题栏') 
        .width('100%') 
        .height(50) 
        .textAlign(TextAlign.Center) 
 
      Column() { 
        Image($r('app.media.img')) 
          .width(200) 
          .height(200) 
          .scale({ x: this.scaleValue, y: this.scaleValue, z: 1 }) 
          .translate({ x: this.offsetX, y: this.offsetY, z: 0 }) 
          .rotate({ 
            angle: this.angle, 
          }) 
          .gesture(GestureGroup(GestureMode.Parallel, 
            PanGesture() 
              .onActionUpdate((event: GestureEvent) => { 
                if (event) { 
                  this.offsetX = this.positionX + event.offsetX 
                  this.offsetY = this.positionY + event.offsetY 
                } 
              }) 
              .onActionEnd(() => { 
                this.positionX = this.offsetX 
                this.positionY = this.offsetY 
                console.info('Pan end') 
              }), 
 
            RotationGesture() 
              .onActionUpdate((event: GestureEvent) => { 
                if (event) { 
                  this.angle = this.rotateValue + event.angle 
 
                } 
              }) 
              .onActionEnd((event: GestureEvent) => { 
                this.rotateValue = this.angle 
                console.error(`${json.stringify(event)}`) 
                console.error(`${this.rotateValue}`) 
                console.info('Rotation end') 
              }) 
          ) 
          ) 
      }.width(500).height(500) 
 
    } 
  } 
} 
阅读 1k
avatarAI BotBETA

回答

在 HarmonyOS NEXT 开发中,当组件旋转后平移方向出错的问题通常是因为平移操作没有考虑到组件的旋转角度。在 2D 平面上,当你对一个对象进行旋转后,其坐标轴的方向也随之改变,因此你需要根据旋转角度调整平移的方向。

在你的代码中,平移操作 (translate) 是在旋转操作 (rotate) 之后应用的,但平移的坐标 (offsetXoffsetY) 是基于原始坐标系的,而不是旋转后的坐标系。因此,当你旋转组件后,平移的方向看起来就会出错。

为了解决这个问题,你需要将平移操作转换为旋转后的坐标系。这通常涉及到一些数学计算,比如使用旋转矩阵来转换坐标。然而,在 HarmonyOS NEXT 的 API 中,并没有直接提供这种转换的功能。

一种简单的解决方案是在手势处理中手动调整平移的坐标,使其与旋转后的组件方向相匹配。这通常涉及到一些三角函数计算,比如使用 Math.cosMath.sin 来计算旋转后的 x 和 y 坐标增量。

然而,这种方法可能会比较复杂,且容易出错。另一种更简单但可能不太精确的方法是,在旋转组件后,调整用户的交互逻辑,使其感觉上像是按照预期方向平移。例如,你可以根据旋转角度调整平移的灵敏度或方向。

由于 HarmonyOS NEXT 的具体 API 和功能可能有所不同,因此以上建议可能需要根据你使用的具体版本和框架进行调整。建议查阅 HarmonyOS NEXT 的官方文档或社区论坛,以获取更详细和具体的解决方案。

1 个回答

你可以将gesture组合手势放在父组件进行规避,代码如下:

import json from '@ohos.util.json' 
 
@Entry 
@Component 
struct Index { 
  @State imageWidth: number = 0 
  @State imageHeight: number = 0 
  @State offsetX: number = 0 
  @State offsetY: number = 0 
  @State positionX: number = 0 
  @State positionY: number = 0 
  @State angle: number = 0 
  @State rotateValue: number = 0 
  @State scaleValue: number = 1 
  @State pinchValue: number = 1 
  @State pinchX: number = 0 
  @State pinchY: number = 0 
  @State centerX: number = 0 
  @State centerY: number = 0 
 
  aboutToAppear(): void { 
 
  } 
 
  build() { 
    Column() { 
      Text('标题栏') 
        .width('100%') 
        .height(50) 
        .textAlign(TextAlign.Center) 
 
      Column() { 
        Image($r('app.media.app_icon')) 
          .width(200) 
          .height(200) 
          .scale({ x: this.scaleValue, y: this.scaleValue, z: 1 }) 
          .translate({ x: this.offsetX, y: this.offsetY }) 
          .rotate({ 
            angle: this.angle, 
          }) 
 
      }.width(500).height(500) 
      .gesture(GestureGroup(GestureMode.Parallel, 
        PanGesture() 
          .onActionUpdate((event: GestureEvent) => { 
            if (event) { 
              this.offsetX = this.positionX + event.offsetX 
              this.offsetY = this.positionY + event.offsetY 
            } 
          }) 
          .onActionEnd(() => { 
            this.positionX = this.offsetX 
            this.positionY = this.offsetY 
            console.info('Pan end') 
          }), 
 
        RotationGesture() 
          .onActionUpdate((event: GestureEvent) => { 
            if (event) { 
              this.angle = this.rotateValue + event.angle 
 
            } 
          }) 
          .onActionEnd((event: GestureEvent) => { 
            this.rotateValue = this.angle 
            console.error(`${json.stringify(event)}`) 
            console.error(`${this.rotateValue}`) 
            console.info('Rotation end') 
          }) 
      ) 
      ) 
    } 
  } 
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进