HarmonyOS鸿蒙Next中现在可以用模拟器绘制,但是画出来是连续的圆点不是线条

HarmonyOS鸿蒙Next中现在可以用模拟器绘制,但是画出来是连续的圆点不是线条 我现在用cavans画布开发绘画软件,在我写添加点逻辑的时候在模拟器上画的稍微快一点就都是虚线了,我的效果想是平滑的线,问一下怎么实现,这是我的代码

// 添加点
addPoint(x: number, y: number) {
  const color = this.isEraserMode ? Color.White : this.paintColor
  const size = this.isEraserMode ? this.eraserSize : this.paintSize
  
  this.currentStroke.push(new DrawingPoint(x, y, size, color))
}

更多关于HarmonyOS鸿蒙Next中现在可以用模拟器绘制,但是画出来是连续的圆点不是线条的实战教程也可以访问 https://www.itying.com/category-93-b0.html

3 回复

开发者你好,画出虚线的原因是采样频率不够,参考下面这段代码

addPoint(x: number, y: number) {
  const color = this.isEraserMode ? Color.White : this.paintColor
  const size = this.isEraserMode ? this.eraserSize : this.paintSize
  // 找到上一点
  const last = this.currentStroke[this.currentStroke.length - 1]
  if (last) {
    // 计算距离
    const dx = x - last.x
    const dy = y - last.y
    const distance = Math.sqrt(dx * dx + dy * dy)
    // 每隔多少像素补一个点(值越小越顺滑,性能越低)
    const step = size / 2    // 推荐:笔越粗补得越密
    if (distance > step) {
      const steps = Math.floor(distance / step)
      for (let i = 1; i <= steps; i++) {
        const newX = last.x + (dx * i) / steps
        const newY = last.y + (dy * i) / steps
        this.currentStroke.push(new DrawingPoint(newX, newY, size, color))
      }
    }
  }
  // 追加当前点
  this.currentStroke.push(new DrawingPoint(x, y, size, color))
}

更多关于HarmonyOS鸿蒙Next中现在可以用模拟器绘制,但是画出来是连续的圆点不是线条的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙Next中,使用Canvas绘制时出现连续圆点而非线条,通常是因为未正确设置画笔样式。需检查Paint对象的setStrokeWidthsetStrokeCap方法。确保setStrokeWidth设置合适的线宽(如大于1),并将setStrokeCap设为Paint.Cap.ROUNDPaint.Cap.BUTT,而非默认点状样式。同时,使用canvas.drawLinecanvas.drawPath方法绘制路径,而非连续点。

你遇到的问题是由于在快速绘制时,addPoint方法收集到的点不够密集,导致Canvas绘制时点与点之间距离过大,呈现为虚线或圆点。关键在于需要在点之间进行插值,生成平滑的路径。

以下是实现平滑线条的核心思路和修改建议:

1. 插值算法(核心解决思路)addPoint方法中,不要只记录当前点,而应该在上一个点和当前点之间插入多个中间点。常用的插值算法有线性插值或贝塞尔曲线插值。

2. 修改addPoint方法逻辑 你需要记录前一个点的坐标,然后在添加新点时,计算两点之间的距离,根据距离动态插入中间点。

示例代码修改:

// 在类中增加前一个点坐标的存储
private lastX: number = -1;
private lastY: number = -1;

// 修改后的addPoint方法
addPoint(x: number, y: number) {
    const color = this.isEraserMode ? Color.White : this.paintColor;
    const size = this.isEraserMode ? this.eraserSize : this.paintSize;

    if (this.lastX === -1) {
        // 第一个点,直接添加
        this.currentStroke.push(new DrawingPoint(x, y, size, color));
    } else {
        // 计算与上一个点的距离
        const distance = Math.sqrt(Math.pow(x - this.lastX, 2) + Math.pow(y - this.lastY, 2));
        const steps = Math.max(1, Math.floor(distance / 2)); // 每2像素插入一个点,可根据需要调整
        
        for (let i = 1; i <= steps; i++) {
            const t = i / steps;
            const interpX = this.lastX + (x - this.lastX) * t;
            const interpY = this.lastY + (y - this.lastY) * t;
            this.currentStroke.push(new DrawingPoint(interpX, interpY, size, color));
        }
    }
    
    // 更新上一个点坐标
    this.lastX = x;
    this.lastY = y;
}

// 在开始新笔画时重置上一个点坐标
startNewStroke() {
    this.lastX = -1;
    this.lastY = -1;
    // ... 其他初始化逻辑
}

3. 绘制优化 在Canvas绘制时,建议使用Path2D或类似的路径对象来构建连续路径,而不是单独绘制每个点。这样可以确保绘制引擎将整个笔画作为一条连续路径处理。

4. 性能考虑

  • 插值密度需要根据实际需求调整,过高的密度会影响性能
  • 可以考虑使用更高效的插值算法,如二次贝塞尔曲线
  • 对于绘制性能要求高的场景,可以尝试使用WebGL或原生绘图API

这种插值方法能有效解决快速绘制时出现的虚线问题,使线条更加平滑连续。

回到顶部