HarmonyOS 鸿蒙Next canvas如何实现点击消除画板中已存在的绘画线条

发布于 1周前 作者 wuwangju 最后一次编辑是 5天前 来自 鸿蒙OS

HarmonyOS 鸿蒙Next canvas如何实现点击消除画板中已存在的绘画线条

大家知道canvas如何实现点击消除画板中已存在的绘画线条啊?

2 回复

老铁,可以试试这个代码。是可以点击消除已存在的绘画线条的:

[@Entry](/user/Entry)
[@Component](/user/Component)
struct Index3 {
 [@State](/user/State) message: string = 'Hello World';

 build() {
   Column() {
     SaveLineCanvas()
   }
   .width('100%')
   .height('100%')
   .justifyContent(FlexAlign.Center)
 }
}

interface Lines {
 path: number[],
 x1: number
 y1: number
 x2: number
 y2: number
 color: string
 lineWidth: number
}

[@Component](/user/Component)
export struct SaveLineCanvas {
 private settings: RenderingContextSettings = new RenderingContextSettings(true)
 private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
 [@State](/user/State) eventType: string = '';
 [@State](/user/State) text: string = '';
 // 保存线条的数组
 lines: Lines[] = [];

 drawLine(x1: number, y1: number, x2: number, y2: number, color: string, lineWidth: number) {
   let ctx = this.context
   ctx.beginPath();
   ctx.moveTo(x1, y1);
   ctx.lineTo(x2, y2);
   ctx.strokeStyle = color;
   ctx.lineWidth = lineWidth;
   ctx.stroke();
   // 保存路径信息
   this.lines.push({
     path: ctx.getLineDash(),
     x1: x1,
     y1: y1,
     x2: x2,
     y2: y2,
     color: color,
     lineWidth: lineWidth
   });
   ctx.setLineDash([]); // 重置虚线模式
 }

 // 擦除线条的函数
 eraseLineByTouch(x: number, y: number) {
   let ctx = this.context
   let lines = this.lines
   // 保存画布状态
   ctx.save();
   // 清除画布
   ctx.clearRect(0, 0, 1256, 2760);
   // 重新绘制除了被擦除的线之外的所有线
   for (let i = 0; i < lines.length; i++) {
     let line = lines[i];
     // 判断触摸点是否在线条上
     if (!this.isPointOnLine(x, y, line.x1, line.y1, line.x2, line.y2)) {
       ctx.beginPath();
       ctx.moveTo(line.x1, line.y1);
       ctx.lineTo(line.x2, line.y2);
       ctx.strokeStyle = line.color;
       ctx.lineWidth = line.lineWidth;
       ctx.setLineDash(line.path); // 恢复虚线模式
       ctx.stroke();
     } else {
       // 从数组中删除线条
       this.lines.splice(i, 1);
       i--; // 调整索引,因为数组长度已经改变
     }
   }
   // 恢复画布状态
   ctx.restore();
 }

 // 判断点是否在线上
 isPointOnLine(x: number, y: number, x1: number, y1: number, x2: number, y2: number) {
   let dx = x2 - x1;
   let dy = y2 - y1;
   if (dy === 0) {
     return x >= Math.min(x1, x2) && x <= Math.max(x1, x2);
   } else {
     let t = (y - y1) / dy;
     let xOnLine = x1 + t * dx;
     return Math.abs(xOnLine - x) < 10; // 允许一定的误差范围
   }
 }

 build() {
   Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
     Canvas(this.context)
       .width('100%')
       .height('100%')
       .backgroundColor('#ffff00')
       .onReady(() => {
         // 绘制多条线
         this.drawLine(50, 50, 150, 150, 'black', 6);
         this.drawLine(150, 50, 50, 150, 'red', 4);
         this.drawLine(200, 50, 50, 150, 'blue', 4);
         this.drawLine(300, 50, 50, 150, 'gray', 4);
         this.drawLine(400, 50, 50, 150, '#ff26ffea', 4);

       })
       .onTouch((event?: TouchEvent) => {
         if (event) {
           if (event.type === TouchType.Down) {
             this.eventType = 'Down';
             this.eraseLineByTouch(event.touches[0].x, event.touches[0].y);
           }
           if (event.type === TouchType.Up) {
             this.eventType = 'Up';
           }
           if (event.type === TouchType.Move) {
             this.eventType = 'Move';
           }
           this.text = 'TouchType:' + this.eventType + '\nDistance between touch point and touch element:\nx: '
             + event.touches[0].x + '\n' + 'y: ' + event.touches[0].y + '\nComponent globalPos:('
             + event.target.area.globalPosition.x + ',' + event.target.area.globalPosition.y + ')\nwidth:'
             + event.target.area.width + '\nheight:' + event.target.area.height
           console.info(`text: ${this.text}`)

         }
       })
   }
   .width('100%')
   .height('100%')
 }
}

更多关于HarmonyOS 鸿蒙Next canvas如何实现点击消除画板中已存在的绘画线条的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙系统中,实现Next canvas点击消除画板中已存在的绘画线条,可以通过以下步骤实现:

  1. 存储绘画数据:在画板进行绘画时,将每次绘制的线条数据存储起来,包括线条的起点、终点、颜色、粗细等。

  2. 实现点击检测:在canvas上监听点击事件,获取点击的位置坐标。

  3. 匹配并消除线条:遍历存储的线条数据,判断点击位置是否在线条的一定范围内(例如,判断点击点是否在某条线段的垂直投影范围内)。如果匹配成功,将该线条从存储的数据中移除。

  4. 重绘canvas:在移除线条后,重新绘制canvas,只绘制未被消除的线条。

  5. 优化性能:如果线条数据较多,可以通过空间划分、索引等数据结构来优化匹配和消除线条的效率。

示例代码(伪代码):

void onClick(int x, int y) {
    for (Line line : lines) {
        if (isPointOnLine(x, y, line)) {
            lines.remove(line);
            break;
        }
    }
    redrawCanvas();
}

以上代码逻辑为简化示例,具体实现需根据实际需求调整。

如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html

回到顶部