HarmonyOS 鸿蒙Next中CanvasRenderingContext2D绘制的图形设置点击事件时,整个界面点击都会响应点击事件,不仅是绘制的图形响应点击事件

HarmonyOS 鸿蒙Next中CanvasRenderingContext2D绘制的图形设置点击事件时,整个界面点击都会响应点击事件,不仅是绘制的图形响应点击事件

问题描述

CanvasRenderingContext2D绘制的图形设置点击事件时,整个界面点击都会相应点击事件,不仅是绘制的图形区域内的点击事件。

问题现象

自定义使用CanvasRenderingContext2D绘制一个不规则的形状,添加到界面上,并给其添加onclick事件,增加日志打印;发现触摸绘制区域之外的位置,也能触发onclick事件;

绘制该区域的代码如下:

  build() {
    Column() {
      Canvas(this.context)
        .width('100%')
        .height('100%')
        .backgroundColor(Color.Transparent)
        .onReady(() => {
          if (this.pathArray?.length > 0 && this.pathArray?.length === 6) {
            let path = new Path2D();
            path.moveTo(this.pathArray[0].x, this.pathArray[0].y);
            path.lineTo(this.pathArray[1].x, this.pathArray[1].y);
            path.lineTo(this.pathArray[2].x, this.pathArray[2].y);
            path.lineTo(this.pathArray[3].x, this.pathArray[3].y);
            path.lineTo(this.pathArray[4].x, this.pathArray[4].y);
            path.lineTo(this.pathArray[5].x, this.pathArray[5].y);
            this.context.fillStyle = MASK_TRANSLUCENT;
            path.closePath();
            this.context.lineWidth = 5;
            this.context.strokeStyle = Color.Black;
            this.context.fill(path);
            Logger.warn(TAG, `draw hot area`);
          }
        })
    }
    .alignItems(HorizontalAlign.Start)
    .width(DEFAULT_WIDTH)
    .height(DEFAULT_HEIGHT)
  }

更多关于HarmonyOS 鸿蒙Next中CanvasRenderingContext2D绘制的图形设置点击事件时,整个界面点击都会响应点击事件,不仅是绘制的图形响应点击事件的实战教程也可以访问 https://www.itying.com/category-93-b0.html

3 回复

感谢您的提问,为了更快解决您的问题,麻烦请补充以下信息:
DEFAULT_WIDTH和DEFAULT_HEIGHT对应的值是多少?
Canvas的backgroundColor设置为非透明色点击的话,是点击的Canvas组件还是非绘制区呢?

更多关于HarmonyOS 鸿蒙Next中CanvasRenderingContext2D绘制的图形设置点击事件时,整个界面点击都会响应点击事件,不仅是绘制的图形响应点击事件的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在鸿蒙Next中,CanvasRenderingContext2D绘制的图形默认会占据整个Canvas区域。要限制点击事件仅响应图形区域,需使用Path2D定义图形边界,并通过isPointInPath方法进行点击检测。示例代码:

let ctx = canvas.getContext('2d') as CanvasRenderingContext2D;
let path = new Path2D();
path.rect(50, 50, 100, 100); // 定义图形区域

canvas.addEventListener('click', (event) => {
  if (ctx.isPointInPath(path, event.offsetX, event.offsetY)) {
    // 点击在图形内才响应
    console.log('图形被点击');
  }
});

在HarmonyOS Next中,Canvas的点击事件默认会响应整个画布区域。要实现仅点击绘制图形区域触发事件,需要手动实现点击区域检测。以下是解决方案:

  1. 使用isPointInPath方法检测点击位置是否在路径内:
Canvas(this.context)
  .onClick((event: ClickEvent) => {
    const x = event.localX;
    const y = event.localY;
    if (this.context.isPointInPath(path, x, y)) {
      // 处理点击逻辑
    }
  })
  1. 对于复杂图形,建议:
  • 保存Path2D对象引用
  • 在点击事件中遍历所有路径进行检测
  • 使用hitRegion属性(如果API支持)
  1. 当前代码改进建议:
  • path声明为成员变量以便访问
  • onClick回调中使用isPointInPath检查

注意:由于Canvas是位图绘制,点击检测需要开发者自行实现,系统不会自动识别绘制内容的形状边界。

回到顶部