HarmonyOS Next中使用Canvas提供画布组件,用于自定义绘制图形,我们可以使用CanvasRenderingContext2D对象和OffscreenCanvasRenderingContext2D对象在Canvas组件上进行绘制,绘制对象可以是基础形状、文本、图片等。
HarmonyOS Next 提供了以下三种形式在画布绘制自定义图形:
- 使用CanvasRenderingContext2D对象在Canvas画布上绘制。
- 离屏绘制是指将需要绘制的内容先绘制在缓存区,再将其转换成图片,一次性绘制到Canvas上,加快了绘制速度。
- 在Canvas上加载Lottie动画。
Canvas绘制使用步骤
首先我们需要构建RenderingContextSettings对象,然后使用RenderingContextSettings对象对象构建CanvasRenderingContext2D,因为Canvas构造函数中需要传入CanvasRenderingContext2D对象。
下面实现最简单的一个示例:
private settings: RenderingContextSettings = new RenderingContextSettings(true)
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
build() {
RelativeContainer() {
Canvas(this.context)
.width('100%')
.height('100%')
.backgroundColor('#660099')
}
}
这里只是简单实现一个背景色,这里面setting用来配置CanvasRenderingContext2D对象的参数,包括是否开启抗锯齿,true表明开启抗锯齿。接下来我们就可以使用CanvasRenderingContext2D操作Canvas了。要操作Canvas必须要等待onReady回调后才可以执行,onReady(event: () => void)是Canvas组件初始化完成时的事件回调,调用该事件后,可获取Canvas组件的确定宽高,进一步使用CanvasRenderingContext2D对象和OffscreenCanvasRenderingContext2D对象调用相关API进行图形绘制。
离屏渲染介绍
离屏绘制是指将需要绘制的内容先绘制在缓存区,再将其转换成图片,一次性绘制到Canvas上,加快了绘制速度。过程为:
- 通过transferToImageBitmap方法将离屏画布最近渲染的图像创建为一个ImageBitmap对象。
- 通过CanvasRenderingContext2D对象的transferFromImageBitmap方法显示给定的ImageBitmap对象。
在画布组件中,通过CanvasRenderingContext2D对象和OffscreenCanvasRenderingContext2D对象在Canvas组件上进行绘制时调用的接口相同。
下面是一个离屏渲染的示例:
@Entry
@Component
struct Index {
private settings: RenderingContextSettings = new RenderingContextSettings(true)
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
private offCanvas: OffscreenCanvas = new OffscreenCanvas(600, 600)
build() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Canvas(this.context)
.width('100%')
.height('100%')
.backgroundColor('#5F3CE2')
.onReady(() => {
let offContext = this.offCanvas.getContext("2d", this.settings)
//可以在这里绘制内容
offContext.strokeRect(20, 20, 100, 100);
//将离屏绘值渲染的图像在普通画布上显示
let image = this.offCanvas.transferToImageBitmap();
this.context.transferFromImageBitmap(image);
})
}
.width('100%')
.height('100%')
}
}
- 首先创建setting对象,用来配置CanvasRenderingContext2D对象和OffscreenCanvasRenderingContext2D对象的参数,包括是否开启抗锯齿。true表明开启抗锯齿。
- 接下来创建OffscreenCanvas对象,width为离屏画布的宽度,height为离屏画布的高度。通过在canvas中调用OffscreenCanvasRenderingContext2D对象来绘制。
- 在onReady中通过
let offContext = this.offCanvas.getContext("2d", this.settings)
获取离屏上下文 - 在离屏画布中绘制矩形
- 通过
this.offCanvas.transferToImageBitmap()
将离屏绘值渲染的图像在普通画布上显示
各种形状绘制
绘制线条
通过beginPath、moveTo、lineTo来实现线条绘制。
@Entry
@Component
struct Index {
//用来配置CanvasRenderingContext2D对象和OffscreenCanvasRenderingContext2D对象的参数,包括是否开启抗锯齿。true表明开启抗锯齿
private settings: RenderingContextSettings = new RenderingContextSettings(true)
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
build() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Canvas(this.context)
.width('100%')
.height('100%')
.backgroundColor('#cbbbf2')
.onReady(() => {
this.context.beginPath();
this.context.moveTo(150, 50);
this.context.lineTo(200, 150);
this.context.stroke();
})
}
.width('100%')
.height('100%')
}
}
绘制矩形
fillRect绘制实心矩形,strokeRect绘制空心矩形,下面以实心矩形为例:
@Entry
@Component
struct Index {
//用来配置CanvasRenderingContext2D对象和OffscreenCanvasRenderingContext2D对象的参数,包括是否开启抗锯齿。true表明开启抗锯齿
private settings: RenderingContextSettings = new RenderingContextSettings(true)
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
build() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Canvas(this.context)
.width('100%')
.height('100%')
.backgroundColor('#cbbbf2')
.onReady(() => {
this.context.fillStyle = '#0097D4';
this.context.fillRect(50, 50, 100, 100);
})
}
.width('100%')
.height('100%')
}
}
绘制圆形
通过arc绘制圆形:
@Entry
@Component
struct Index {
//用来配置CanvasRenderingContext2D对象和OffscreenCanvasRenderingContext2D对象的参数,包括是否开启抗锯齿。true表明开启抗锯齿
private settings: RenderingContextSettings = new RenderingContextSettings(true)
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
build() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Canvas(this.context)
.width('100%')
.height('100%')
.backgroundColor('#cbbbf2')
.onReady(() => {
let region = new Path2D();
region.arc(100, 75, 50, 0, 6.28);
this.context.stroke(region);
})
}
.width('100%')
.height('100%')
}
}
绘制椭圆
ellipse可以用来绘制椭圆:
@Entry
@Component
struct Index {
//用来配置CanvasRenderingContext2D对象和OffscreenCanvasRenderingContext2D对象的参数,包括是否开启抗锯齿。true表明开启抗锯齿
private settings: RenderingContextSettings = new RenderingContextSettings(true)
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
build() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Canvas(this.context)
.width('100%')
.height('100%')
.backgroundColor('#cbbbf2')
.onReady(() => {
this.context.beginPath();
this.context.ellipse(150, 150, 50, 100, Math.PI * 0.25, Math.PI * 0, Math.PI * 2);
this.context.stroke();
})
}
.width('100%')
.height('100%')
}
}
文本绘制
可以通过fillText(文本填充)、strokeText(文本描边)等接口进行文本绘制,示例中设置了font为50像素高加粗的"sans-serif"字体,然后调用fillText方法在(50, 100)处绘制文本"Hello World!",设置strokeStyle为红色,lineWidth为2,font为50像素高加粗的"sans-serif"字体,然后调用strokeText方法在(50, 150)处绘制文本"Hello World!"的轮廓。
@Entry
@Component
struct Index {
//用来配置CanvasRenderingContext2D对象和OffscreenCanvasRenderingContext2D对象的参数,包括是否开启抗锯齿。true表明开启抗锯齿
private settings: RenderingContextSettings = new RenderingContextSettings(true)
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
build() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Canvas(this.context)
.width('100%')
.height('100%')
.backgroundColor('#cbbbf2')
.onReady(() => {
// 文本填充
this.context.font = '50px bolder sans-serif';
this.context.fillText("HarmonyOS!", 50, 100);
// 文本描边
this.context.strokeStyle = "#ff0000"
this.context.lineWidth = 2
this.context.font = '50px bolder sans-serif';
this.context.strokeText("HarmonyOS", 50, 150);
})
}
.width('100%')
.height('100%')
}
}
其他
此外还提供了绘制图片和图像像素信息处理、绘制渐变(CanvasGradient对象)相关的方法:createLinearGradient(创建一个线性渐变色)、createRadialGradient(创建一个径向渐变色)等。
总结
本文详细介绍了在 HarmonyOS Next 中使用 Canvas 组件进行自定义图形绘制的方法。Canvas 是一个用于绘制图形的画布组件,支持通过 CanvasRenderingContext2D 和 OffscreenCanvasRenderingContext2D 对象绘制基础形状、文本、图片等内容。文章重点讲解了三种绘制方式:直接绘制、离屏绘制(提升效率)以及加载 Lottie 动画。