大家好,我是新手程序员Kevin(小K)


最近准备做一个小型APP,其中有一块功能会需要自己绘制图形,比如画简单的图表、动态标记,还有可能要做图片上的一些识别提示。所以就开始翻ArkUI文档里 Canvas组件的部分,专门花了一些时间把这一部分文档认真过了一遍。这里把自己理解的内容和一些学习过程中的感受整理下来。


对Canvas组件的整体理解

先是最基本的概念。Canvas就是一个 绘图画布组件,开发者在这个区域可以自己绘制各种图形。它本身不负责具体的绘制逻辑,只是提供一个“画布环境”,真正的绘制需要通过 RenderingContext 来完成。

Canvas是从 API version 8 开始支持的,在ArkUI里算是比较基础的能力了。后面的版本有逐步增强:

  • API 9:支持在 ArkTS卡片 中使用
  • API 11:支持 元服务
  • API 12:新增AI分析能力相关配置

这个版本演进其实挺关键的,如果要兼容老设备,可能要注意API版本。

另外有个限制需要注意:

Canvas创建时最大面积不能超过 10000px × 10000px

这个限制我一开始觉得不用在意,但后来想了一下,如果要做高清绘图或者长图编辑的情境,就要考虑如何处理这个上限,否则可能会踩坑,需要记住这个硬限制。


Canvas构造方式

Canvas创建的时候主要有两种形式:普通Canvas带AI能力的Canvas

第一种:普通Canvas

Canvas(context?: CanvasRenderingContext2D | DrawingRenderingContext)

这里的关键点是 context,也就是说Canvas必须依赖一个 绘图上下文对象,目前支持两种:

  • CanvasRenderingContext2D
  • DrawingRenderingContext

刚开始看到这两个类的时候有点懵,因为名字看起来很像,但其实用途略有区别。CanvasRenderingContext2D是在web前端的Canvas,DrawingRenderingContext通过 context.canvas.drawXXX() 绘制,并需要 invalidate() 触发刷新。

还有一个限制很重要:一个CanvasRenderingContext2D对象不能被多个Canvas共享,也就是说每个Canvas基本上要有自己的context,否则会有问题。


第二种:带AI能力的Canvas(API12+)

Canvas(context, imageAIOptions)

这个版本开始支持 AI图像分析

新增的参数是:imageAIOptions: ImageAIOptions。它可以配置:** 分析类型 AI控制器(ImageAnalyzerController)**。这个功能看起来其实挺有意思,比如可以做:主体识别、文字识别、对象查找,如果做图片编辑类APP,或者类似扫一扫识别物体之类的功能,这块应该会很有用。


Canvas属性

Canvas除了普通组件属性之外,还有一个比较关键的属性:

enableAnalyzer

这个属性是 API12新增的AI分析开关
enableAnalyzer(boolean)。默认值是 false。当设置为 true 时,Canvas组件支持AI分析功能。

不过这里有两个注意点:

  1. 需要配合。startImageAnalyzerstopImageAnalyzer一起使用。
  2. 不能和 overlay属性 同时使用,否则 overlay 里的 CustomBuilder 会失效。

这个限制在文档里看了一下才发现,如果以后调试的时候overlay突然不生效,可能就是这里冲突了。


Canvas事件

Canvas最重要的事件是:onReadyonReady(() => {})这个事件在两个情况下触发:

  • Canvas初始化完成
  • Canvas大小发生变化

文档里有一句话我觉得特别关键:onReady触发时,画布会被清空。也就是说,如果Canvas大小发生变化,之前画的内容就没了,需要重新绘制。所以一般绘制逻辑应该写在onReady里。

另外还有一个小细节:

  • 如果只是位置变化,不会触发onReady
  • 只会触发onAreaChange

这个细节其实挺重要,不然调试的时候会怀疑为什么绘图没刷新。


示例理解

文档给了三个例子,我自己也简单看了一下逻辑。


示例1:使用CanvasRenderingContext2D

核心逻辑:

this.context.fillRect(0, 30, 100, 100)

也就是说在Canvas准备好之后,在指定位置绘制一个矩形。

流程其实很清晰:

1 创建context
2 创建Canvas组件
3 在onReady里绘图


示例2:使用DrawingRenderingContext

这个例子稍微不同一点:

this.context.canvas.drawCircle(200, 200, 100)
this.context.invalidate()

这里多了一个 invalidate()

我一开始没太理解这个调用,估计应该是通知Canvas 重新刷新绘制内容。和CanvasRenderingContext2D相比,这个API的使用方式略微不同。


示例3:attributeModifier动态设置属性

这个例子信息量最大。

里面涉及:

  • attributeModifier
  • enableAnalyzer
  • AI识别
  • 控制器

核心流程是:

1 Canvas开启AI分析能力
2 点击按钮调用 startImageAnalyzer
3 长按Canvas触发识别

识别类型可以配置:

ImageAnalyzerType.SUBJECT
ImageAnalyzerType.TEXT

也就是主体识别和文字识别。这个功能让我突然想到一个场景:如果APP里有图片编辑功能,可以让用户长按图片识别里面的文字或者物体,感觉挺实用的。


学习过程中的一些理解

刚开始看Canvas这部分文档的时候,其实有点被各种类名绕晕,比如:CanvasCanvasRenderingContext2DDrawingRenderingContext。特别是后两个,名字都差不多,看着很容易混。

后来我试着换一个角度理解,就清晰多了:Canvas负责显示区域Context负责绘图能力。就像画画一样:Canvas = 画布Context = 画笔工具。真正画东西的是工具,而不是画布本身。


另外一个让我注意的点,就是 onReady事件清空画布 这个行为。一开始我以为Canvas像普通View一样,只初始化一次。但文档里写的是:Canvas大小变化也会触发onReady。也就是说如果布局发生变化,绘制内容就会被清空。这意味着:绘图逻辑必须可以重复执行。
否则UI刷新后画面就没了。

这个点我觉得在实际项目里一定会遇到。


另外是关于AI分析能力的一点思考。文档里新增的AI识别功能让我挺感兴趣的。

它不是单纯的绘图,而是结合了图像分析。可以识别:主体文字对象

如果把Canvas和AI能力结合,其实可以做很多东西,比如:图片文字识别图像搜索图片标记智能截图识别

虽然文档只是简单展示了接口,但感觉这里潜力挺大的。


结合自己现在准备做的APP,我觉得Canvas至少可以用在几个地方:绘制图表(柱状图、折线图);图片标记(在图片上画框、标注位置);手写绘图(简单画板、手势轨迹);AI识别辅助(长按识别文字、识别图片主体)

如果把Canvas和手势事件结合,甚至可以做一个简单的绘图工具。


小结

记录一些关键信息:

  • Canvas提供绘制区域
  • 绘图需要依赖RenderingContext
  • onReady是核心事件
  • Canvas大小变化会清空绘制内容
  • API12新增AI图像分析能力
  • context不能共享
  • Canvas面积限制
  • overlay冲突
  • onReady触发机制

之后可能会分享一些自己写小demo的经验,欢迎大家关注和交流。

Logo

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

更多推荐