在上一篇文章中,我们通过组合系统的 Circle 组件实现了一个可定制的圆环控件,本篇将介绍如何利用 CanvasMiniCanvas 两种方式自绘同样的圆环,并支持外部传参来设置半径、线宽、颜色及填充色。通过本节学习,读者可以深入掌握 Canvas 的使用以及一个轻量级绘图库 MiniCanvas 的接入方法。

1. Canvas 自绘方式

1.1 组件与绘图上下文准备

借助 ArkUI 在 API 8 版本提供的 Canvas,我们首先创建组件并准备绘图上下文对象:

@Component export 
struct Ring {

  // 开启抗锯齿的渲染设置
  private settings: RenderingContextSettings = new RenderingContextSettings(true);
  // Canvas 2D 绘图上下文
  private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings);

  public ringAttribute: RingAttribute = null;  // 接收外部传参

  /** 在 build 之前校验属性 */
  private aboutToAppear() {
    this.ringAttribute = RingAttribute.filter(this.ringAttribute);
  }
  
  build() {
    Canvas(this.context)
      .width(this.ringAttribute.radius * 2)
      .height(this.ringAttribute.radius * 2)
      .onReady(() => {
        const r = this.ringAttribute.radius;
        const w = this.ringAttribute.width;
        // 设置绘制样式
        this.context.strokeStyle = this.ringAttribute.color.toString();
        this.context.fillStyle   = this.ringAttribute.solid.toString();
        this.context.lineWidth    = w;
        this.context.beginPath();
        // arc(x, y, radius, startAngle, endAngle)
        this.context.arc(r, r, r - w / 2, 0, Math.PI * 2);
        this.context.stroke();
      });
  }
}
  • **Canvas(this.context)**:将 CanvasRenderingContext2D 绑定到组件上。
  • **onReady**:Canvas 准备好后回调,在此执行绘制命令。
  • **arc**:绘制完整圆弧,从 0 到 2π。

1.2 属性校验类 RingAttribute

与组合方式相同,我们依然需要一个 RingAttribute 类来定义默认值并过滤非法入参,确保绘制参数有效。

class RingAttribute {
  radius: number = 45;
  width: number  = 5;
  color: any     = '#000000';
  solid: any     = '#ffffff';

  public static filter(attr: RingAttribute): RingAttribute {
    const def = new RingAttribute();
    if (!attr) return def;
    attr.radius ??= def.radius;
    attr.width  ??= def.width;
    attr.color  ??= def.color;
    attr.solid  ??= def.solid;
    return attr;
  }
}

1.3 在页面中使用

import { Ring } from '../widgets/Ring';

@Entry @Component 
struct CanvasDemo {
  build() {
    Column({ space: 10 }) {
      // 默认圆环
      Ring()
      // 绿色环,半径 50、宽度 8
      Ring({ ringAttribute: { radius: 50, width: 8, color: Color.Green, solid: '#eee' }})
      // 红色环,半径 60、宽度 12
      Ring({ ringAttribute: { radius: 60, width: 12, color: Color.Red, solid: Color.Pink }})
    }
    .padding(20)
    .width('100%')
    .height('100%')
  }
}

运行后即可看到三个圆环,完全由 Canvas 绘制。


2. MiniCanvas 简化绘制

为了屏蔽 Canvas 的繁琐 API,开源社区提供了一个轻量级库 MiniCanvas,它封装了常用绘图操作,只需简单几行代码即可完成绘制。

2.1 安装 MiniCanvas

在项目的 entry 目录下执行:

npm install git+https://gitee.com/ark-ui/MiniCanvas.git

安装完成后,package.json 会自动添加依赖。

2.2 引入并使用

import { MiniCanvas, Paint } from '@ohos/mini_canvas';

@Entry @Component 
struct MiniCanvasDemo {
  build() {
    Column({ space: 10 }) {
      Row({ space: 10 }) {

        // 默认画布圆环
        MiniCanvas({
          attribute: { width: 120, height: 120, background: '#fff', antiAlias: true },
          onDraw: (canvas: ICanvas) => {
            const paint = new Paint();
            paint.setStroke(true).setStrokeWidth(5).setColor('#000');
            // 在 (60,60) 处以半径 50 绘制圆环
            canvas.drawCircle(60, 60, 50, paint);
          }
        })

        // 绿色圆环
        MiniCanvas({
          attribute: { width: 120, height: 120, background: '#fff', antiAlias: true },
          onDraw: (canvas: ICanvas) => {
            const paint = new Paint();
            paint.setStroke(true).setStrokeWidth(8).setColor(Color.Green.toString());
            canvas.drawCircle(60, 60, 50, paint);
          }
        })

        // 粉色圆环
        MiniCanvas({
          attribute: { width: 120, height: 120, background: '#fff', antiAlias: true },
          onDraw: (canvas: ICanvas) => {
            const paint = new Paint();
            paint.setStroke(true).setStrokeWidth(12).setColor(Color.Pink.toString());
            canvas.drawCircle(60, 60, 50, paint);
          }
        })

      }
    }
    .padding(20)
    .width('100%')
    .height('100%')
  }
}
  • **Paint**:画笔封装,链式配置笔触是否描边、宽度和颜色。
  • **onDraw**:在回调内直接调用 canvas.drawCircle 绘制圆环。

小结

  • Canvas 方式:使用原生 CanvasRenderingContext2D,拥有最灵活、最底层的绘制能力。
  • MiniCanvas 方式:对 Canvas 进行二次封装,提供简洁 API,适合日常快速绘制。

通过本文学习,您不仅掌握了两种自绘圆环的实现思路,也理解了自定义组件如何接收和校验外部参数。接下来,您可以结合时间刻度、进度动画等需求,利用 Canvas 或 MiniCanvas 打造更多丰富精美的 OpenHarmony UI 组件。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐