HarmonyOS Canvas绘制出来的添加onTouch手势,但是无法移动

Canvas绘制出来的添加onTouch手势,拖动图标,给图标新的位置,但是无法移动,icon图标在附件中,代码如下:

@Entry  
@Component  
struct CanvasExample {  
  private settings: RenderingContextSettings = new RenderingContextSettings(true);  
  private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings);  
  private img: ImageBitmap = new ImageBitmap("/common/images/seek_bar_icon.png");  
  private offContext: OffscreenCanvasRenderingContext2D = new OffscreenCanvasRenderingContext2D(600, 600, this.settings)  
  @State leftTargetX: number = 100;  
  @State leftTargetY: number = 40;  
  @State rightTargetX: number = 300;  
  @State rightTargetY: number = 40;  
  @State pointSize: number = 20;  
  @State lineStart: number = 25;  
  @State lineEnd: number = 337;  
  @State lineY: number = 50;  
  
  build() {  
    Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {  
      Canvas(this.context)  
        .width('100%')  
        .height('100%')  
        .backgroundColor('#ffff00')  
        .onReady(() => {  
          this.context.lineWidth = 8;  
          this.context.beginPath();  
          this.context.strokeStyle = "#F0F0F0";  
          this.context.lineCap = 'round';  
          this.context.moveTo(this.lineStart, this.lineY);  
          this.context.lineTo(this.lineEnd, this.lineY);  
          this.context.stroke();  
          // 使用drawImage接口将图片画在(0,0)为起点,宽高130的区域  
          this.context.drawImage(this.img, 0, 0, this.pointSize, this.pointSize, this.leftTargetX, this.leftTargetY, this.pointSize, this.pointSize);  
          this.context.drawImage(this.img, 0, 0, this.pointSize, this.pointSize, this.rightTargetX, this.rightTargetY, this.pointSize, this.pointSize);  
  
  
        })  
        .onTouch((event: TouchEvent) => {  
          let x = event.touches[0].x;  
          let y = event.touches[0].y;  
          this.leftTargetX = x;  
          //左边范围  
          if (x >= (this.lineStart - this.pointSize / 2)  
            && x < this.rightTargetX - this.pointSize / 2  
            && y >= this.lineY - this.pointSize  
            && y <= this.lineY + this.pointSize) {  
            this.leftTargetX = x;  
            console.log(`CanvasExample  left====x==${x}==y==${y}`)  
          }  
          //右边  
          if (x > (this.leftTargetX + this.pointSize / 2)  
            && x <= this.lineEnd + this.pointSize / 2  
            && y >= this.lineY - this.pointSize  
            && y <= this.lineY + this.pointSize) {  
            this.rightTargetX = x;  
            console.log(`CanvasExample  right====x==${x}==y==${y}`)  
          }  
        })  
    }  
    .width('100%')  
    .height('100%')  
  }  
}
HarmonyOS
2024-10-22 11:17:07
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
superinsect

可以使用onTouch事件判断触摸点是否是可移动区域,再通过PanGesture

链接:

https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/ts-basic-gestures-pangestur

手势控制坐标点的移动,提供以下案例参考:

@Entry  
@CustomDialog  
export struct AudioRecorderDialog {  
  controller: CustomDialogController  
  private settings: RenderingContextSettings = new RenderingContextSettings(true)  
  private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)  
  @State @Watch('draw') positionXY : number[] = [0, 0];  
  prePosition: number[] = []; // 上一次坐标点  
  @State rectWidth: number = 100;  
  @State rectHeight: number = 100;  
  PanGestureFlag: boolean = false;  
build() {  
    Column() {  
      Canvas(this.context)  
        .width('100%')  
        .height('50%')  
        .backgroundColor('#ffff00')  
        .margin({top: 50})  
        .onReady(() => {  
          this.draw()  
          // this.context.fillRect(this.positionX, this.positionY, this.rectWidth, this.rectWidth)  
        })  
        .gesture( // 拖拽手势  
          PanGesture()  
            .onActionUpdate((event: GestureEvent)=>{  
                if(this.PanGestureFlag) {  
                  console.info(`onActionUpdate  x=${event.offsetX}   y=${event.offsetY}`)  
                  this.prePosition = [...this.positionXY]; // 保存上一次坐标  
                  let x = this.positionXY[0];  
                  let y = this.positionXY[1];  
                  x += parseInt(`${event.offsetX}`);  
                  y += parseInt(`${event.offsetY}`);  
                  this.positionXY = [x, y];  
                  console.log(`pre  ${x}   ${y}`)  
                  console.log(`${this.positionXY}`)  
                }  
            })  
        )  
        .onTouch((event: TouchEvent)=>{  
          let x = event.touches[0].x;  
          let y = event.touches[0].y;  
          if(x >= this.positionXY[0] &&  
            x<= (this.positionXY[0] + this.rectWidth) &&  
            y > this.positionXY[1] &&  
            y<= (this.positionXY[1] + this.rectHeight)  
          ){  
            this.PanGestureFlag = true; // 可以拖动  
          }  
        });  
    }  
  }  
draw(){  
    // console.log('demoTest :' + 's')  
    if(this.prePosition.length) {  
      console.info(`clearRect  ${this.prePosition}`)  
      this.context.clearRect(this.prePosition[0], this.prePosition[1], this.rectWidth, this.rectHeight);  
    }  
    console.info(`fillRect  ${this.positionXY} `)  
    this.context.fillRect(this.positionXY[0], this.positionXY[1], this.rectWidth, this.rectHeight)  
  }  
}

onTouch事件是开始刚触摸到屏幕时会触发,但是现在需要实现的需求是在拖动时画布上的元素变化,需要记录手指/鼠标的偏移量,所以使用PanGesture拖动手势更合适

开发者也可以只使用PanGesture拖动,代码样例:

@Entry  
@CustomDialog  
export struct AudioRecorderDialog {  
  controller: CustomDialogController  
  private settings: RenderingContextSettings = new RenderingContextSettings(true)  
  private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)  
  @State @Watch('draw') positionXY : number[] = [0, 0]; // 原始坐标点  
  prePosition: number[] = []; // 上一次坐标点  
  clickXY: number[] = []; // 鼠标落下坐标点  
  // 偏移参照点  
  shiftingPosition: number[] = [];  
  
  rectWidth: number = 100;  
  rectHeight: number = 100;  
  PanGestureFlag: boolean = false;  
  build() {  
    Column() {  
      Canvas(this.context)  
        .width('100%')  
        .height('50%')  
        .backgroundColor('#ffff00')  
        .margin({top: 50})  
        .onReady(() => {  
          this.draw()  
        })  
        .gesture( // 拖拽手势  
          PanGesture()  
            .onActionStart((event: GestureEvent)=>{  
              let x = event.fingerList[0].localX;  
              let y = event.fingerList[0].localY;  
              if(x >= this.positionXY[0] &&  
                x<= (this.positionXY[0] + this.rectWidth) &&  
                y > this.positionXY[1] &&  
                y<= (this.positionXY[1] + this.rectHeight)  
              ){  
                this.PanGestureFlag = true; // 可以拖动  
                this.clickXY = [parseInt(`${x}`), parseInt(`${y}`)];  
                this.shiftingPosition = [...this.positionXY];  
                console.info(`shiftingPosition   ${this.shiftingPosition}`)  
              }  
            })  
            .onActionUpdate((event: GestureEvent)=>{  
              if(this.PanGestureFlag) {  
                this.prePosition = [...this.positionXY]; // 保存上一次坐标  
                const x = this.shiftingPosition[0] +  parseInt(`${event.offsetX}`);  
                const y = this.shiftingPosition[1] + parseInt(`${event.offsetY}`);  
                this.positionXY = [x, y];  
                // console.info(`shiftingPosition   ${this.shiftingPosition}`);  
                console.log(`positionXY     ${this.positionXY}`);  
              }  
            })  
            .onActionEnd(()=>{  
              this.PanGestureFlag = false; // 结束后,停止拖动  
            })  
        )  
    }  
  }  
  draw(){  
    // console.log('demoTest :' + 's')  
    if(this.prePosition.length) {  
      this.context.clearRect(this.prePosition[0], this.prePosition[1], this.rectWidth, this.rectHeight);  
    }  
    this.context.fillRect(this.positionXY[0], this.positionXY[1], this.rectWidth, this.rectHeight)  
  }  
}
分享
微博
QQ
微信
回复
2024-10-22 17:15:58
相关问题
HarmonyOS LongPressGesture手势移动问题
486浏览 • 1回复 待解决
HarmonyOS 子窗口是否可手势移动
70浏览 • 1回复 待解决
如何操作canvas重新绘制
1101浏览 • 1回复 待解决
Canvas绘制内容如何动态更新
1649浏览 • 1回复 待解决
HarmonyOS Canvas中关于绘制图片问题
385浏览 • 1回复 待解决
Canvas如何触发刷新重复绘制
953浏览 • 1回复 待解决
canvas怎么绘制资源目录下图片
665浏览 • 1回复 待解决
如何使用canvas绘制圆角矩形
546浏览 • 1回复 待解决
如何使用canvas添加水印
1333浏览 • 1回复 待解决
HyperlinkonTouch预览报错
1992浏览 • 1回复 待解决
Canvas如何绘制app.media下面的图片?
2365浏览 • 1回复 待解决