Canvas 画布组件
ArkUI 开发框架提供了 Canvas 画布组件支持我们自绘制各种图形的需求,Canvas 的具体绘制是委托给 CanvasRenderingContext2D 实现的, CanvasRenderingContext2D 提供了一系列绘画相关的方法,笔者把 CanvasRenderingContext2D 简单理解成一个画笔,画笔绘制的内容在画布 Canvas 上显示。本节课主要向读者介绍 CanvasRenderingContext2D 的使用。
Canvas 定义介绍
interface CanvasInterface {
(context?: CanvasRenderingContext2D): CanvasAttribute;
}
- context:Canvas 组件创建的时候需要一个
CanvasRenderingContext2D
实例,该实例负责在 Canvas 上绘制具体内容,比如文本、图片以及各种形状等
Canvas 事件介绍
declare class CanvasAttribute extends CommonMethod<CanvasAttribute> {
onReady(event: () => void): CanvasAttribute;
}
- onReady():Canvas 组件初始化成功后的回调,绘制相关的操作均在该回调中进行。
简单样例如下所示:
@Entry @Component struct Index {
// 初始化RenderingContextSettings并设置为抗锯齿
private setting: RenderingContextSettings = new RenderingContextSettings(true);
// 初始化CanvasRenderingContext2D
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.setting);
build() {
Column() {
Canvas(this.context) // 设置Canvas所需要的context
.size({width: '100%', height: "100%"}) // 设置Canvas的宽高
.onReady(() => { // 监听回调,在回调内执行绘画操作
this.context.fillRect(10, 10, 130, 40); // 以(10, 10)为起点坐标,画矩形,默认黑色
})
}
.width('100%')
.height('100%')
}
}
样例运行结果如下图所示:
CanvasRenderingContext2D 属性介绍
CanvasRenderingContext2D
是 Canvas
的画笔,继承自 CanvasRenderer
,它的常用属性如下所示:
declare class CanvasRenderer extends CanvasPath {
// 绘制图片
drawImage(image: ImageBitmap | PixelMap, dx: number, dy: number): void;
// 绘制矩形
fillRect(x: number, y: number, w: number, h: number): void;
// 绘制文本
fillText(text: string, x: number, y: number, maxWidth?: number): void;
// 测量文本
measureText(text: string): TextMetrics;
// 旋转画布
rotate(angle: number): void;
// 恢复当前绘图上下文
restore(): void;
// 保存当前绘图上下文
save(): void;
// 省略部分API
}
CanvasRenderer 提供了丰富的符合业界 W3C 标准规范的 API ,但是从易用性上来有点复杂,笔者也向 OpenHarmony 讨论过这些 API 的易用性 问题 (opens new window),为了方便读者快速实现绘制能力,笔者封装了一个 MiniCanvas (opens new window)组件,接下来向大家介绍 MiniCanvas (opens new window)的用法,有关 CanvasRenderer 的详细用法请参考官方文档 (opens new window),笔者就不一一介绍了。
MiniCanvas 组件介绍
MiniCanvas 组件是笔者基于 Canvas 封装的一个 Mini 版的绘图组件,它屏蔽了 Canvas 内部复杂的调用流程,给读者提供了一系列精简的 API ,具体绘制通过一个 API 就可以搞定,极大的简化了绘制操作,目前该控件还在不断完善中,笔者也欢迎读者使用该控件并为该控件提交 PR。
MiniCanvas 提供了一系列 drawXXX() 方法,该方法内需要接收一个 Paint 对象,通过设置 Paint 的参数来实现不同的绘制样式,比如 setColor() 设置绘制颜色,setTextSize() 设置文字大小,setStroke() 设置是否绘制轮廓等,具体样式可以读者可以阅读源码。
绘制直线
public drawLine(startX: number, startY: number, stopX: number, stopY: number, paint: Paint);
MiniCanvas 提供了 drawLine() 方法绘制直线,它接收起始点坐标(startX,startY)和结束点坐标(stopX,stopY)和一个画笔(paint),画笔(paint)支持设置直线的颜色,粗细等。简单样例如下所示:
@Entry @Component struct MiniCanvasTest {
build() {
Column() {
MiniCanvas({ // 使用MiniCanvas组件
onDraw: (canvas) => { // 在onDraw回调方法内绘制图形
let paint = new Paint(); // 创建画笔
paint.setColor(Color.Red.toString()); // 设置画笔颜色
paint.setStrokeWidth(4); // 设置画笔线条粗细
canvas.drawLine(10, 10, 200, 10, paint); // 调用drawLine绘制一条直线
paint.setColor("#aabbcc") // 设置画笔颜色
paint.setStrokeWidth(2); // 设置画笔线条粗细
canvas.drawLine(10, 20, 260, 60, paint); // 调用drawLine绘制一条直线
}
})
}
.size({width: '100%', height: "100%"})
}
}
样例运行结果如下图所示:
绘制文本
public drawText(text: string, x: number, y: number, paint: Paint, maxWidth?: number);
MiniCanvas 提供了 drawText() 方法绘制文本, text 是要绘制的文本内容, x 和 y 表示文本绘制的起始坐标,画笔(paint)支持文本的大小,字体,颜色等。简单样例如下所示:
@Entry @Component struct MiniCanvasTest {
build() {
Column() {
MiniCanvas({
onDraw: (canvas) => {
let text = "OpenHarmony"; // 需要绘制的文本
let paint = new Paint() // 创建画笔
paint.setFontSize(vp2px(30)) // 设置字体大小
canvas.drawText(text, 10, 12, paint); // 绘制文本
paint.setColor(Color.Red.toString()) // 设置字体颜色
canvas.drawText(text, 140, 45, paint); // 绘制文本
}
})
}
.size({width: '100%', height: "100%"})
}
}
样例运行结果如下图所示:
绘制圆
public drawCircle(x: number, y: number, radius: number, paint: Paint);
MiniCanvas 提供了 drawCircle() 方法绘制圆, x 和 y 表示圆心坐标, radius 表示圆的半径,画笔(paint)支持设置圆的颜色,是否是圆环以及圆环的粗细。简单样例如下所示:
@Entry @Component struct MiniCanvasTest {
build() {
Column() {
MiniCanvas({
onDraw: (canvas) => {
let paint = new Paint()
canvas.drawCircle(90, 45, 30, paint); // 绘制圆,半径30
paint.setColor("#ff0000") // 设置圆的颜色
canvas.drawCircle(170, 45, 30, paint); // 绘制圆
paint.setStroke(true) // 设置绘制圆环
canvas.drawCircle(90, 125, 30, paint); // 绘制圆环
paint.setColor("#000000") // 设置圆环颜色
paint.setStrokeWidth(vp2px(4)) // 设置圆环粗细
canvas.drawCircle(170, 125, 30, paint); // 绘制圆环
}
})
}
.size({width: '100%', height: "100%"})
}
}
样例运行结果如下所示:
绘制椭圆
public drawOval(x: number, y: number, width: number, height: number, paint: Paint);
MiniCanvas 提供了 drawOval() 方法绘制椭圆,x 和 y 表示椭圆所在矩形的左上角坐标, width 和 height 表示椭圆所在矩形的宽高,画笔(paint)支持设置圆的颜色,是否是圆环以及圆环的粗细等。简单样例如下所示:
@Entry @Component struct MiniCanvasTest {
build() {
Column() {
MiniCanvas({
onDraw: (canvas) => {
let paint = new Paint()
canvas.drawOval(10, 10, 150, 60, paint);
paint.setColor('#ff0000')
canvas.drawOval(170, 10, 150, 60, paint);
paint.setStroke(true)
paint.setColor(Color.Pink.toString())
canvas.drawOval(10, 80, 150, 60, paint);
paint.setColor('#ff0000')
paint.setStrokeWidth(vp2px(3))
canvas.drawOval(170, 80, 150, 60, paint);
}
})
}
.size({width: '100%', height: "100%"})
}
}
样例运行结果如下图所示:
绘制矩形
public drawRect(x: number, y: number, width: number, height: number, paint: Paint);
MiniCanvas 提供了 drawRect() 方法绘制矩形, x 和 y 表示矩形的左上角坐标, width 和 height 表示矩形的宽高,画笔(paint)支持设置矩形的颜色,是否是矩形框以及矩形框的粗细等。简单样例如下所示:
@Entry @Component struct MiniCanvasTest {
build() {
Column() {
MiniCanvas({
onDraw: (canvas) => {
let paint = new Paint() // 创建画笔
canvas.drawRect(10, 10, 150, 50, paint);
paint.setColor(Color.Pink.toString())
canvas.drawRect(170, 10, 150, 50, paint);
paint.setStroke(true)
canvas.drawRect(10, 70, 150, 50, paint);
paint.setColor('#ff0000')
paint.setStrokeWidth(3)
canvas.drawRect(170, 70, 150, 50, paint);
}
})
}
.size({width: '100%', height: "100%"})
}
}
样例运行结果如下所示:
绘制圆角矩形
public drawRoundRect(x: number, y: number, width: number, height: number, radius: number, paint: Paint);
MiniCanvas 提供了 drawRoundRect() 方法绘制圆角矩形, x 和 y 表示圆角矩形的左上角坐标, width 和 height 表示圆角矩形的宽高, radius 表示圆角大小,画笔(paint)支持设置矩形的颜色,是否是矩形框以及矩形框的粗细等。简单样例如下所示:
@Entry @Component struct MiniCanvasTest {
build() {
Column() {
MiniCanvas({
onDraw: (canvas) => {
let paint = new Paint()
canvas.drawRoundRect(10, 10, 150, 50, 10, paint);
paint.setColor(Color.Pink.toString())
canvas.drawRoundRect(170, 10, 150, 50, 15, paint);
paint.setStroke(true)
canvas.drawRoundRect(10, 70, 150, 50, 15, paint);
paint.setColor('#ff0000')
paint.setStrokeWidth(3)
canvas.drawRoundRect(170, 70, 150, 50, 10, paint);
}
})
}
.size({width: '100%', height: "100%"})
}
}
样例运行结果如下图所示:
绘制圆弧
drawArc(x: number, y: number, radius: number, startAngle: number, endAngle: number, paint: Paint, counterclockwise?: boolean): void;
MiniCanvas 提供了 drawArc() 方法绘制圆弧, x 和 y 表示圆心坐标, radius 表示圆弧的半径, startAngle 表示圆弧起始角度, endAngle 表示圆弧结束角度,画笔(paint)支持设置圆弧的颜色以及是否实心等。简单样例如下所示:
@Entry @Component struct MiniCanvasTest {
build() {
Column() {
MiniCanvas({
onDraw: (canvas) => {
let paint = new Paint(); // 创建画笔
paint.setStroke(true) // 设置空心圆弧
canvas.drawArc(30, 30, 30, 0, 130, paint)
paint.setColor(Color.Red.toString()) // 设置圆弧颜色
canvas.drawArc(100, 30, 30, 0, 130, paint)
paint.setStroke(false) // 设置实心圆弧
canvas.drawArc(170, 30, 30, 0, 130, paint)
}
})
}
.size({width: '100%', height: "100%"})
}
}
样例运行结果如下图所示:
绘制图片
public drawImage(image: ImageBitmap, sx: number, sy: number, sWidth: number, sHeight: number, dx: number, dy: number, dWidth: number, dHeight: number);
MiniCanvas 提供了 drawImage() 方法绘制图片, image 表示要绘制的图片数据源, sx 和 sy 表示从图片的起始点开始绘制, sWidth 和 sHeight 表示选取图片的宽高, dx 和 dy 表示绘制在画布上的起始点坐标, dWidth 和 dHeight 表示绘制图片的区域,简单理解就是把选取的图片区域 Rect(sx, sy, sWidth, sHeight) 绘制在指定的画布区域 Rect(sx, dy, dWidth, dHeight) 中。简单样例如下所示:
@Entry @Component struct MiniCanvasTest {
build() {
Column() {
MiniCanvas({
onDraw: (canvas) => {
let paint = new Paint();
let image = new ImageBitmap("pages/test.jpg"); // 创建ImageBitmap实例
canvas.drawImage(image, 0, 0, 500, 500, 10, 10, 250, 100, paint) // 绘制图片
}
})
}
.size({width: '100%', height: "100%"})
}
}
样例运行结果如下图所示: